libsangoma.c

Go to the documentation of this file.
00001 /*******************************************************************************/
00036 #include "libsangoma.h"
00037 
00042 #define DFT_CARD "wanpipe1"
00043 
00044 
00045 #ifndef WP_API_FEATURE_FE_ALARM
00046 #warning "Warning: SANGOMA API FE ALARM not supported by driver"
00047 #endif
00048 
00049 #ifndef WP_API_FEATURE_DTMF_EVENTS
00050 #warning "Warning: SANGOMA API DTMF not supported by driver"
00051 #endif
00052 
00053 #ifndef WP_API_FEATURE_EVENTS
00054 #warning "Warning: SANGOMA API EVENTS not supported by driver"
00055 #endif
00056 
00057 #ifndef WP_API_FEATURE_LINK_STATUS
00058 #warning "Warning: SANGOMA API LINK STATUS not supported by driver"
00059 #endif
00060 
00065 #define DEV_NAME_LEN    100
00066 
00067 
00068 static void libsng_dbg(const char * fmt, ...)
00069 {
00070     va_list args;
00071     char buf[1024];
00072     va_start(args, fmt);
00073     _vsnprintf(buf, sizeof(buf), fmt, args);
00074 #if defined(WIN32)
00075     OutputDebugString(buf);
00076 #else
00077     printf(buf);
00078 #endif
00079     va_end(args);
00080 }
00081 
00082 /*********************************************************************/
00086 #define DBG_POLL    if(0)libsng_dbg
00087 #define DBG_EVNT    if(0)libsng_dbg
00088 #define DBG_ERR     if(1)libsng_dbg
00089 
00090 #if defined(WIN32)
00091 
00096 #define WP_INIT_OVERLAPPED_STRUCT(o)\
00097 {   \
00098     o->Internal = (ULONG_PTR)NULL; \
00099     o->InternalHigh = (ULONG_PTR)NULL; \
00100     o->Offset = 0; \
00101     o->OffsetHigh = 0;\
00102 }
00103 
00104 /*
00105   \fn static void DecodeLastError(LPSTR lpszFunction)
00106   \brief Decodes the Error in radable format.
00107   \param lpszFunction error string
00108 
00109   Private Windows Only Function
00110  */
00111 static void DecodeLastError(LPSTR lpszFunction) 
00112 { 
00113     LPVOID lpMsgBuf;
00114     DWORD dwLastErr = GetLastError();
00115     FormatMessage( 
00116         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
00117         FORMAT_MESSAGE_FROM_SYSTEM | 
00118         FORMAT_MESSAGE_IGNORE_INSERTS,
00119         NULL,
00120         dwLastErr,
00121         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
00122         (LPTSTR) &lpMsgBuf,
00123         0,
00124         NULL 
00125     );
00126     // Display the string.
00127     printf("Last Error: %s (GetLastError() returned: %d)\n", lpMsgBuf, dwLastErr);
00128     // Free the buffer.
00129     LocalFree( lpMsgBuf );
00130 } 
00131 
00132 /*
00133   \fn static int handle_device_ioctl_result(int bResult)
00134   \brief Checks result code of ioctl
00135   \param bResult result of ioctl call
00136 
00137   Private Windows Only Function
00138  */
00139 static int handle_device_ioctl_result(int bResult)
00140 {
00141     if(bResult == 0){
00142         DecodeLastError(__FUNCTION__);
00143         return 1;
00144     }else{
00145         return 0;
00146     }
00147 }
00148 
00149 /*
00150   \fn static int DoManagementCommand(HANDLE fd, wan_udp_hdr_t* wan_udp)
00151   \brief Executes Driver Management Command
00152   \param fd device file descriptor
00153   \param wan_udp managemet cmd structure
00154 
00155   Private Windows Function
00156  */
00157 static int DoManagementCommand(HANDLE fd, wan_udp_hdr_t* wan_udp)
00158 {
00159     DWORD ln, bIoResult;
00160     unsigned char id = 0;
00161 
00162     wan_udp->wan_udphdr_request_reply = 0x01;
00163     wan_udp->wan_udphdr_id = id;
00164     wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
00165 
00166     bIoResult = DeviceIoControl(
00167             fd,
00168             IoctlManagementCommand,
00169             (LPVOID)wan_udp,
00170             sizeof(wan_udp_hdr_t),
00171             (LPVOID)wan_udp,
00172             sizeof(wan_udp_hdr_t),
00173             (LPDWORD)(&ln),
00174             (LPOVERLAPPED)NULL
00175             );
00176 
00177     return handle_device_ioctl_result(bIoResult);
00178 }
00179 
00180 /*
00181   \fn static int DoTdmvApiCommand(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00182   \brief Executes Driver TDM API Command
00183   \param fd device file descriptor
00184   \param api_cmd tdm_api managemet cmd structure
00185 
00186   Private Windows Function
00187  */
00188 static int DoTdmvApiCommand(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00189 {
00190     DWORD ln, bIoResult;
00191 
00192     bIoResult = DeviceIoControl(
00193             fd,
00194             IoctlTdmApiCommand,
00195             (LPVOID)api_cmd,
00196             sizeof(wanpipe_tdm_api_cmd_t),
00197             (LPVOID)api_cmd,
00198             sizeof(wanpipe_tdm_api_cmd_t),
00199             (LPDWORD)(&ln),
00200             (LPOVERLAPPED)NULL
00201             );
00202 
00203     return handle_device_ioctl_result(bIoResult);
00204 }
00205 
00206 /*
00207   \fn static int tdmv_api_ioctl(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00208   \brief Executes Driver TDM API Command Wrapper Function
00209   \param fd device file descriptor
00210   \param api_cmd tdm_api managemet cmd structure
00211 
00212   Private Windows Function
00213  */
00214 static int tdmv_api_ioctl(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00215 {
00216     if(DoTdmvApiCommand(fd, api_cmd)){
00217         return SANG_STATUS_GENERAL_ERROR;
00218     }
00219 
00220     return api_cmd->result;
00221 }
00222 
00223 /*
00224   \fn static USHORT DoReadCommand(HANDLE drv, RX_DATA_STRUCT * pRx)
00225   \brief  API READ Function
00226   \param drv device file descriptor
00227   \param pRx receive data structure
00228 
00229   Private Windows Function
00230   In Legacy API mode this fuction will Block if there is no data.
00231   In API mode no function is allowed to Block
00232  */
00233 static USHORT DoReadCommand(HANDLE drv, RX_DATA_STRUCT * pRx)
00234 {
00235     DWORD ln;
00236 
00237     if (DeviceIoControl(
00238             drv,
00239             IoctlReadCommand,
00240             (LPVOID)NULL,//NO input buffer!
00241             0,
00242             (LPVOID)pRx,
00243             sizeof(RX_DATA_STRUCT),
00244             (LPDWORD)(&ln),
00245             (LPOVERLAPPED)NULL
00246             ) == FALSE){
00247         //check messages log
00248         DBG_EVNT("Error: %s(): DeviceIoControl failed!\n", __FUNCTION__);
00249         return 1;
00250     }else{
00251         return 0;
00252     }
00253 }
00254 
00255 /*
00256   \fn static UCHAR DoWriteCommand(HANDLE drv, TX_DATA_STRUCT * pTx)
00257   \brief API Write Function
00258   \param drv device file descriptor
00259   \param pRx receive data structure
00260 
00261   Private Windows Function
00262   In Legacy API mode this fuction will Block if data is busy.
00263   In API mode no function is allowed to Block
00264  */
00265 static UCHAR DoWriteCommand(HANDLE drv,
00266                             void *input_data_buffer, u32 size_of_input_data_buffer,
00267                             void *output_data_buffer, u32 size_of_output_data_buffer
00268                             )
00269 {
00270     DWORD BytesReturned;
00271 
00272     if(DeviceIoControl(
00273             drv,
00274             IoctlWriteCommand,
00275             (LPVOID)input_data_buffer,
00276             size_of_input_data_buffer,
00277             (LPVOID)output_data_buffer,
00278             size_of_output_data_buffer,
00279             (LPDWORD)(&BytesReturned),
00280             (LPOVERLAPPED)NULL
00281             ) == FALSE){
00282         //check messages log
00283         DBG_EVNT("Error: %s(): DeviceIoControl failed!\n", __FUNCTION__);
00284         return 1;
00285     }else{
00286         return 0;
00287     }
00288 }
00289 
00290 /*
00291   \fn static USHORT DoApiPollCommand(HANDLE drv, API_POLL_STRUCT *api_poll_ptr, OVERLAPPED *overlapped)
00292   \brief Blocking API Poll function used to wait on events
00293   \param drv device file descriptor
00294   \param api_poll_ptr poll device that stores polling information read/write/event
00295   \param overlapped pointer to system overlapped io structure.
00296 
00297   Private Windows Function
00298   This function blocks and waits for events: read/write/event/timeout
00299  */
00300 static USHORT DoApiPollCommand(HANDLE drv, API_POLL_STRUCT *api_poll_ptr, OVERLAPPED *overlapped)
00301 {
00302     DWORD ln;
00303 
00304     WP_INIT_OVERLAPPED_STRUCT(overlapped);
00305 
00306     if (DeviceIoControl(
00307             drv,
00308             IoctlApiPoll,
00309             (LPVOID)NULL,
00310             0L,
00311             (LPVOID)api_poll_ptr,
00312             sizeof(API_POLL_STRUCT),
00313             (LPDWORD)(&ln),
00314             overlapped
00315             ) == FALSE){
00316         //check messages log
00317         DBG_EVNT("Error: %s(): DeviceIoControl failed!\n", __FUNCTION__);
00318         return 1;
00319     }else{
00320         return 0;
00321     }
00322 }
00323 
00324 static int _SAPI_CALL sangoma_socket_get_state(sangoma_wait_obj_t *sng_wait_obj)
00325 {
00326     DWORD   NumberOfBytesTransferred;
00327     BOOL    bOverlappedResult;
00328 
00329     bOverlappedResult = GetOverlappedResult(sng_wait_obj->fd,   
00330                                             &sng_wait_obj->OverlappedApiPoll,
00331                                             &NumberOfBytesTransferred,
00332                                             FALSE/* do NOT wait for IO to complete */);
00333 
00334     if(bOverlappedResult == FALSE){
00335         if(GetLastError() == ERROR_IO_INCOMPLETE){
00336             /* IO still in process */
00337             return 0;
00338         }else{
00339             /* Function call failed. Error. */
00340             return -1;
00341         }
00342     }else{
00343         if(GetLastError() == ERROR_SUCCESS){
00344             /* IO is complete. Sangoma "socket" is signaled. */
00345             return 1;
00346         }
00347         if(GetLastError() == ERROR_INVALID_PARAMETER){
00348             /* IO is complete, but with an error. */
00349             return -2;
00350         }
00351     }
00352     /* all other cases are errors */
00353     return -3;
00354 }
00355 
00356 static int _SAPI_CALL sangoma_socket_poll(sangoma_wait_obj_t *sng_wait_obj)
00357 {
00358     API_POLL_STRUCT *api_poll = &sng_wait_obj->api_poll;
00359 #if 0
00360     DBG_POLL("%s(): span: %d, chan: %d\n", __FUNCTION__, sng_wait_obj->span, sng_wait_obj->chan);
00361 #endif
00362     memset(api_poll, 0x00, sizeof(API_POLL_STRUCT));
00363 
00364     api_poll->timeout = sng_wait_obj->timeout;
00365     api_poll->user_flags_bitmap = sng_wait_obj->flags_in;
00366 
00367     /* This call will return immediatly because it is "overlapped"! 
00368      * Caller of this function must implement the actual wait. */
00369     if(DoApiPollCommand(sng_wait_obj->fd, api_poll, &sng_wait_obj->OverlappedApiPoll)){
00370         //failed
00371         return -1;
00372     }
00373     return 0;
00374 }
00375 
00376 #endif  /* WIN32 */
00377 
00378 
00379 /*********************************************************************/
00390 void _SAPI_CALL sangoma_close(sng_fd_t *fd)
00391 {
00392 #if defined(WIN32)
00393     if( *fd != INVALID_HANDLE_VALUE){
00394         CloseHandle(*fd);
00395         *fd = INVALID_HANDLE_VALUE;
00396     }
00397 #else
00398     if (*fd >= 0) {
00399         close(*fd);
00400         *fd = -1;
00401     }
00402 #endif
00403 }
00404 
00417 void _SAPI_CALL sangoma_init_wait_obj(sangoma_wait_obj_t *sng_wait_obj, sng_fd_t fd, int span, int chan, int timeout, int flags_in, int object_type)
00418 {
00419     sng_wait_obj->fd        = fd;
00420     sng_wait_obj->timeout   = timeout;
00421     sng_wait_obj->flags_in  = flags_in;
00422     sng_wait_obj->span      = span;
00423     sng_wait_obj->chan      = chan;
00424     sng_wait_obj->object_type = object_type;
00425 #if defined(WIN32)
00426     sng_wait_obj->OverlappedApiPoll.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
00427 #endif
00428 }
00429 
00436 void _SAPI_CALL sangoma_release_wait_obj(sangoma_wait_obj_t *sng_wait_obj)
00437 {
00438     if(sng_wait_obj->fd != INVALID_HANDLE_VALUE){
00439         sangoma_close(&sng_wait_obj->fd);
00440         sng_wait_obj->fd = INVALID_HANDLE_VALUE;
00441     }
00442 
00443     sng_wait_obj->object_type = UNKNOWN_WAIT_OBJ;
00444 
00445 #if defined(WIN32)
00446     if(sng_wait_obj->OverlappedApiPoll.hEvent){
00447         CloseHandle(sng_wait_obj->OverlappedApiPoll.hEvent);
00448         sng_wait_obj->OverlappedApiPoll.hEvent = 0;
00449     }
00450 #endif
00451 }
00452 
00459 void _SAPI_CALL sangoma_signal_wait_obj(sangoma_wait_obj_t *sng_wait_obj)
00460 {
00461 #if defined(WIN32)
00462     if(sng_wait_obj->OverlappedApiPoll.hEvent){
00463         SetEvent(sng_wait_obj->OverlappedApiPoll.hEvent);
00464     }
00465 #else
00466     //FIXME: implement signalling of the sng_wait_obj->fd ??
00467 #endif
00468 }
00469 
00478 int _SAPI_CALL sangoma_socket_waitfor_many(sangoma_wait_obj_t sangoma_wait_objects[], int number_of_sangoma_wait_objects, uint32_t system_wait_timeout)
00479 {
00480     int i;
00481 #if defined(WIN32)
00482     HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
00483 
00484     if(number_of_sangoma_wait_objects > MAXIMUM_WAIT_OBJECTS){
00485         DBG_EVNT("Error: %s(): 'number_of_sangoma_wait_objects': %d is greater than the Maximum of: %d\n", __FUNCTION__,
00486             number_of_sangoma_wait_objects, MAXIMUM_WAIT_OBJECTS);
00487         return -1;
00488     }
00489 
00490     if(number_of_sangoma_wait_objects < 1){
00491         DBG_EVNT("Error: %s(): 'number_of_sangoma_wait_objects': %d is less than the Minimum of: 1!\n", __FUNCTION__,
00492             number_of_sangoma_wait_objects);
00493         return -2;
00494     }
00495 
00496     for(i = 0; i < number_of_sangoma_wait_objects; i++){
00497         hEvents[i] = sangoma_wait_objects[i].OverlappedApiPoll.hEvent;
00498         if(sangoma_wait_objects[i].object_type == SANGOMA_WAIT_OBJ){
00499             sangoma_socket_poll(&sangoma_wait_objects[i]);
00500         }
00501     }
00502 
00503     /* wait untill at least one of the events is signalled OR a timeout */
00504     if(WAIT_TIMEOUT == WaitForMultipleObjects(number_of_sangoma_wait_objects, &hEvents[0], FALSE, system_wait_timeout)){
00505         return 0;
00506     }
00507 
00508     /* find which overlapped IO was completed */
00509     for(i = 0; i < number_of_sangoma_wait_objects; i++){
00510 
00511         if(sangoma_wait_objects[i].object_type != SANGOMA_WAIT_OBJ){
00512             DBG_POLL("%s(): at index %d is not a SANGOMA_WAIT_OBJ\n", __FUNCTION__, i);
00513             continue;
00514         }
00515 
00516         if(sangoma_socket_get_state(&sangoma_wait_objects[i]) > 0){
00517 
00518             if(sangoma_wait_objects[i].api_poll.operation_status == SANG_STATUS_SUCCESS){
00519 
00520                 sangoma_wait_objects[i].flags_out = sangoma_wait_objects[i].api_poll.poll_events_bitmap;
00521 
00522             }else{
00523                 DBG_EVNT("Error: %s(): Invalid Operation Status: %s(%d)\n", __FUNCTION__,
00524                     SDLA_DECODE_SANG_STATUS(sangoma_wait_objects[i].api_poll.operation_status), 
00525                     sangoma_wait_objects[i].api_poll.operation_status);
00526                 return -2;
00527             }
00528         }
00529     }
00530 
00531     return 1;
00532 #else
00533     struct pollfd pfds[number_of_sangoma_wait_objects];
00534     int res;
00535 
00536     memset(pfds, 0, sizeof(pfds));
00537 
00538     for(i = 0; i < number_of_sangoma_wait_objects; i++){
00539         pfds[i].fd = sangoma_wait_objects[i].fd;
00540         pfds[i].events = sangoma_wait_objects[i].flags_in;
00541     }
00542 
00543     res = poll(pfds, number_of_sangoma_wait_objects, sangoma_wait_objects[0].timeout);
00544     if (res > 0) {
00545         for(i = 0; i < number_of_sangoma_wait_objects; i++){
00546             sangoma_wait_objects[i].flags_out = pfds[i].revents;
00547         }
00548     }
00549 
00550     return res;
00551 #endif
00552 }
00553 
00554 
00564 int _SAPI_CALL sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags_in, unsigned int *flags_out)
00565 {
00566 #if defined(WIN32)
00567     API_POLL_STRUCT api_poll;
00568     DWORD           NumberOfBytesTransferred;
00569     BOOL            bOverlappedResult;
00570     OVERLAPPED      OverlappedApiPoll;
00571 
00572     memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT));
00573 
00574     api_poll.user_flags_bitmap = flags_in;
00575 
00576     /* This call will return immediatly because it is "overlapped"! 
00577      * Caller of this function must implement the actual wait. */
00578     if(DoApiPollCommand(fd, &api_poll, &OverlappedApiPoll)){
00579         //failed
00580         return -1;
00581     }
00582         
00583     bOverlappedResult = GetOverlappedResult(fd, &OverlappedApiPoll, &NumberOfBytesTransferred,
00584                                             TRUE /* wait (indefinitely) for IO to complete */);
00585     if(bOverlappedResult == FALSE){
00586         if(GetLastError() == ERROR_IO_INCOMPLETE){
00587             /* IO still in process */
00588             return 0;
00589         }else{
00590             /* Function call failed. Error. */
00591             return -1;
00592         }
00593     }else{
00594         if(GetLastError() == ERROR_SUCCESS){
00595             /* IO is complete. Sangoma "socket" is signaled. */
00596             if(api_poll.operation_status == SANG_STATUS_SUCCESS){
00597 
00598                 *flags_out = api_poll.poll_events_bitmap;
00599                 return 1;
00600             }else{
00601                 DBG_EVNT("Error: %s(): Invalid Operation Status: %s(%d)\n", __FUNCTION__,
00602                     SDLA_DECODE_SANG_STATUS(api_poll.operation_status), api_poll.operation_status);
00603                 return -3;
00604             }
00605         }
00606         if(GetLastError() == ERROR_INVALID_PARAMETER){
00607             /* IO is complete, but with an error. */
00608             return -2;
00609         }
00610     }
00611     return -1;
00612 #else
00613     struct pollfd pfds[1];
00614     int res;
00615 
00616     memset(&pfds[0], 0, sizeof(pfds[0]));
00617     pfds[0].fd = fd;
00618     pfds[0].events = flags_in;
00619     *flags_out=0;
00620 
00621     res = poll(pfds, 1, timeout);
00622     if (res > 0) {
00623         *flags_out = pfds[0].revents;
00624     }
00625 
00626     return res;
00627 #endif
00628 }
00629 
00630 int _SAPI_CALL sangoma_mgmt_cmd(sng_fd_t fd, wan_udp_hdr_t* wan_udp)
00631 {
00632 #if defined(__WINDOWS__)
00633     if(DoManagementCommand(fd, wan_udp)){
00634         return 1;
00635     }
00636 #else
00637     unsigned char id = 0;
00638     int err=0;
00639     wan_udp->wan_udphdr_request_reply = 0x01;
00640     wan_udp->wan_udphdr_id = id;
00641     wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
00642 
00643     err=ioctl(fd,WANPIPE_IOCTL_PIPEMON,wan_udp);
00644     if (err < 0) {
00645         return 1;
00646     }
00647 #endif
00648 
00649     if(wan_udp->wan_udphdr_return_code != WAN_CMD_OK){
00650         return 2;
00651     }
00652     return 0;
00653 }
00654 
00655 int _SAPI_CALL sangoma_span_chan_toif(int span, int chan, char *interface_name)
00656 {
00657 #if defined(WIN32)
00658 /* FIXME: Not implemented */
00659     return -1;
00660 #else
00661     sprintf(interface_name,"s%ic%i",span,chan);
00662 #endif
00663     return 0;
00664 }
00665 
00666 int _SAPI_CALL sangoma_interface_toi(char *interface_name, int *span, int *chan)
00667 {
00668     char *p=NULL, *sp = NULL, *ch = NULL;
00669     int ret = 0;
00670     char data[FNAME_LEN];
00671 
00672     strncpy(data, interface_name, FNAME_LEN);
00673     if ((data[0])) {
00674         for (p = data; *p; p++) {
00675             if (sp && *p == 'g') {
00676                 *p = '\0';
00677                 ch = (p + 1);
00678                 break;
00679             } else if (*p == 'w') {
00680                 sp = (p + 1);
00681             }
00682         }
00683 
00684         if(ch && sp) {
00685             *span = atoi(sp);
00686             *chan = atoi(ch);
00687             ret = 1;
00688         } else {
00689             *span = -1;
00690             *chan = -1;
00691         }
00692     }
00693 
00694     return ret;
00695 }
00696 
00697 int _SAPI_CALL sangoma_span_chan_fromif(char *interface_name, int *span, int *chan)
00698 {
00699     char *p = NULL, *sp = NULL, *ch = NULL;
00700     int ret = 0;
00701     char data[FNAME_LEN];
00702 
00703     strncpy(data, interface_name, FNAME_LEN);
00704     if ((data[0])) {
00705         for (p = data; *p; p++) {
00706             if (sp && *p == 'c') {
00707                 *p = '\0';
00708                 ch = (p + 1);
00709                 break;
00710             } else if (*p == 's') {
00711                 sp = (p + 1);
00712             }
00713         }
00714 
00715         if(ch && sp) {
00716             *span = atoi(sp);
00717             *chan = atoi(ch);
00718             ret = 1;
00719         } else {
00720             *span = -1;
00721             *chan = -1;
00722         }
00723     }
00724 
00725     return ret;
00726 }
00727 
00728 sng_fd_t _SAPI_CALL sangoma_open_api_span_chan(int span, int chan) 
00729 {
00730     sng_fd_t fd = INVALID_HANDLE_VALUE;
00731     wanpipe_api_t tdm_api;
00732     int err;
00733 
00734     fd = __sangoma_open_api_span_chan(span, chan);
00735 
00736 #if defined(__WINDOWS__)
00737     if(fd == INVALID_HANDLE_VALUE){
00738         //DBG_EVNT("Span: %d, chan: %d: is not running, consider 'busy'\n", span, chan);
00739         return fd;
00740     }
00741 #else
00742     if (fd < 0) {
00743         return fd;
00744     }
00745 #endif
00746 
00747     memset(&tdm_api,0,sizeof(tdm_api));
00748     tdm_api.wp_cmd.cmd = WP_API_CMD_OPEN_CNT;
00749     err=sangoma_cmd_exec(fd,&tdm_api);
00750     if (err){
00751         sangoma_close(&fd);
00752         return err;
00753     }
00754 
00755     if (tdm_api.wp_cmd.open_cnt > 1) {
00756         sangoma_close(&fd);
00757     }
00758 
00759     return fd;
00760 }            
00761 
00762 /* no checks done for multiple open */
00763 sng_fd_t _SAPI_CALL __sangoma_open_api_span_chan(int span, int chan)
00764 {
00765     char fname[FNAME_LEN], tmp_fname[FNAME_LEN];
00766 
00767     /* Form the Interface Name from span and chan number (i.e. wanpipe1_if1). */
00768     _snprintf(tmp_fname, DEV_NAME_LEN, WP_INTERFACE_NAME_FORM, span, chan);
00769 
00770 #if defined(WIN32)
00771     _snprintf(fname , FNAME_LEN, "\\\\.\\%s", tmp_fname);
00772     return CreateFile(  fname, 
00773                         GENERIC_READ | GENERIC_WRITE, 
00774                         FILE_SHARE_READ | FILE_SHARE_WRITE,
00775                         (LPSECURITY_ATTRIBUTES)NULL, 
00776                         OPEN_EXISTING,
00777                         FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED,
00778                         (HANDLE)NULL
00779                         );
00780 #else
00781     //sprintf(fname,"/dev/wanpipe%d_if%d",span,chan);
00782     sprintf(fname,"/dev/%s", tmp_fname);
00783 
00784     return open(fname, O_RDWR);
00785 #endif
00786 }            
00787 
00788 sng_fd_t sangoma_open_api_ctrl(void)
00789 {
00790 #if defined(WIN32)
00791     sng_fd_t fd = INVALID_HANDLE_VALUE;
00792 
00793 #pragma message("sangoma_open_api_ctrl: Not support on Windows")
00794 #else
00795     sng_fd_t fd=-1;
00796 
00797     fd = open("/dev/wanpipe_ctrl", O_RDWR);
00798 #endif
00799 
00800     return fd;
00801 }
00802 
00803 sng_fd_t _SAPI_CALL sangoma_create_socket_by_name(char *device, char *card) 
00804 {
00805     int span,chan;
00806     sangoma_interface_toi(device,&span,&chan);
00807     
00808     return sangoma_open_api_span_chan(span,chan);
00809 }
00810 
00811           
00812 sng_fd_t _SAPI_CALL sangoma_open_api_span(int span) 
00813 {
00814     int i=0;
00815     sng_fd_t fd = INVALID_HANDLE_VALUE;
00816 
00817     for(i = 1; i < 32; i++){
00818 
00819         fd = sangoma_open_api_span_chan(span, i);
00820 
00821 #if defined(WIN32)
00822         if(fd != INVALID_HANDLE_VALUE){
00823 #else
00824         if (fd >= 0) {
00825 #endif
00826 
00827             //found free chan
00828             break;
00829         }
00830 
00831     }//for()
00832 
00833     return fd;  
00834 }      
00835 
00836 int _SAPI_CALL sangoma_readmsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
00837 {
00838     int rx_len=0;
00839 
00840 #if defined(WIN32)
00841     wp_api_hdr_t    *rx_hdr = (wp_api_hdr_t*)hdrbuf;
00842     wp_api_element_t wp_api_element;
00843 
00844     if(hdrlen != sizeof(wp_api_hdr_t)){
00845         //error
00846         DBG_EVNT("Error: %s(): invalid size of user's 'header buffer'. Should be 'sizeof(wp_api_hdr_t)'.\n", __FUNCTION__);
00847         return -1;
00848     }
00849 
00850     if(DoReadCommand(fd, &wp_api_element)){
00851         //error
00852         DBG_EVNT("Error: %s(): DoReadCommand() failed! Check messages log.\n", __FUNCTION__);
00853         return -4;
00854     }
00855 
00856     memcpy(rx_hdr, &wp_api_element.hdr, sizeof(wp_api_hdr_t));
00857 
00858     switch(rx_hdr->operation_status)
00859     {
00860     case SANG_STATUS_RX_DATA_AVAILABLE:
00861         /* ok */
00862         if(rx_hdr->data_length <= datalen){
00863             memcpy(databuf, wp_api_element.data, rx_hdr->data_length);
00864         }else{
00865             rx_hdr->operation_status = SANG_STATUS_BUFFER_TOO_SMALL;
00866         }
00867         break;
00868     default:
00869         /* note that SANG_STATUS_DEVICE_BUSY is NOT an error! */
00870         if(0)DBG_EVNT("Error: %s(): Operation Status: %s(%d)\n", __FUNCTION__, 
00871             SDLA_DECODE_SANG_STATUS(rx_hdr->operation_status), rx_hdr->operation_status);
00872         return -5;
00873     }
00874 
00875     rx_len = rx_hdr->data_length;
00876 #else
00877     struct msghdr msg;
00878     struct iovec iov[2];
00879 
00880     memset(&msg,0,sizeof(struct msghdr));
00881 
00882     iov[0].iov_len=hdrlen;
00883     iov[0].iov_base=hdrbuf;
00884 
00885     iov[1].iov_len=datalen;
00886     iov[1].iov_base=databuf;
00887 
00888     msg.msg_iovlen=2;
00889     msg.msg_iov=iov;
00890 
00891     rx_len = read(fd,&msg,datalen+hdrlen);
00892 
00893     if (rx_len <= sizeof(wp_api_hdr_t)){
00894         return -EINVAL;
00895     }
00896 
00897     rx_len-=sizeof(wp_api_hdr_t);
00898 #endif
00899     return rx_len;
00900 }                    
00901 
00902 int _SAPI_CALL sangoma_writemsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
00903 {
00904     int bsent=-1;
00905     wp_api_hdr_t *wp_api_hdr = hdrbuf;
00906 
00907     if (hdrlen != sizeof(wp_api_hdr_t)) {
00908         DBG_ERR("Error: sangoma_writemsg() failed! hdrlen (%i) != sizeof(wp_api_hdr_t) (%i)\n",
00909                         hdrlen,sizeof(wp_api_hdr_t));
00910         wp_api_hdr->operation_status = SANG_STATUS_TX_HDR_TOO_SHORT;
00911         return -1;
00912     }
00913 
00914 #if defined(WIN32)
00915     
00916 
00917     //queue data for transmission
00918     if(DoWriteCommand(fd, databuf, datalen, hdrbuf, hdrlen)){
00919         //error
00920         DBG_EVNT("Error: DoWriteCommand() failed!! Check messages log.\n");
00921         return -1;
00922     }
00923 
00924     bsent=0;
00925     //check that frame was transmitted
00926     switch(wp_api_hdr->operation_status)
00927     {
00928     case SANG_STATUS_SUCCESS:
00929         bsent = datalen;
00930         break;
00931     default:
00932         DBG_EVNT("Error: %s(): Operation Status: %s(%d)\n", __FUNCTION__, 
00933             SDLA_DECODE_SANG_STATUS(wp_api_hdr->operation_status), wp_api_hdr->operation_status);
00934         break;
00935     }//switch()
00936 #else
00937     struct msghdr msg;
00938     struct iovec iov[2];
00939     wp_api_hdr_t    *tx_el=hdrbuf;
00940 
00941     memset(&msg,0,sizeof(struct msghdr));
00942 
00943     iov[0].iov_len=hdrlen;
00944     iov[0].iov_base=hdrbuf;
00945 
00946     iov[1].iov_len=datalen;
00947     iov[1].iov_base=databuf;
00948 
00949     msg.msg_iovlen=2;
00950     msg.msg_iov=iov;
00951 
00952     bsent = write(fd,&msg,datalen+hdrlen);
00953 
00954     if (bsent == (datalen+hdrlen)){
00955         tx_el->wp_api_hdr_operation_status=SANG_STATUS_SUCCESS;
00956         bsent-=sizeof(wp_api_hdr_t);
00957     } else if (errno == EBUSY){
00958         tx_el->wp_api_hdr_operation_status=SANG_STATUS_DEVICE_BUSY;
00959     } else {
00960         tx_el->wp_api_hdr_operation_status=SANG_STATUS_IO_ERROR;
00961     }
00962     tx_el->wp_api_hdr_data_length=bsent;
00963 #endif
00964     return bsent;
00965 }
00966 
00967 
00968 #ifdef WANPIPE_TDM_API
00969 
00970 /*========================================================
00971  * Execute TDM command
00972  *
00973  */
00974 int _SAPI_CALL sangoma_cmd_exec(sng_fd_t fd, wanpipe_api_t *tdm_api)
00975 {
00976     int err;
00977 
00978 #if defined(WIN32)
00979     err = tdmv_api_ioctl(fd, &tdm_api->wp_cmd);
00980 #else
00981     err = ioctl(fd,SIOC_WANPIPE_TDM_API,&tdm_api->wp_cmd);
00982     if (err < 0){
00983         char tmp[50];
00984         sprintf(tmp,"TDM API: CMD: %i\n",tdm_api->wp_cmd.cmd);
00985         perror(tmp);
00986         return -1;
00987     }
00988 #endif
00989     return err;
00990 }
00991 
00992 /*========================================================
00993  * Get Full TDM API configuration per channel
00994  *
00995  */
00996 int _SAPI_CALL sangoma_get_full_cfg(sng_fd_t fd, wanpipe_api_t *tdm_api)
00997 {
00998     int err;
00999 
01000     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FULL_CFG;
01001 
01002     err=sangoma_cmd_exec(fd,tdm_api);
01003     if (err){
01004         return err;
01005     }
01006 
01007 #if 1
01008     printf("TDM API CFG:\n");
01009     printf("\thw_tdm_coding:\t%d\n",tdm_api->wp_cmd.hw_tdm_coding);
01010     printf("\thw_mtu_mru:\t%d\n",tdm_api->wp_cmd.hw_mtu_mru);
01011     printf("\tusr_period:\t%d\n",tdm_api->wp_cmd.usr_period);
01012     printf("\ttdm_codec:\t%d\n",tdm_api->wp_cmd.tdm_codec);
01013     printf("\tpower_level:\t%d\n",tdm_api->wp_cmd.power_level);
01014     printf("\trx_disable:\t%d\n",tdm_api->wp_cmd.rx_disable);
01015     printf("\ttx_disable:\t%d\n",tdm_api->wp_cmd.tx_disable);
01016     printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_cmd.usr_mtu_mru);
01017     printf("\tidle flag:\t0x%02X\n",tdm_api->wp_cmd.idle_flag);
01018 
01019 #ifdef WP_API_FEATURE_FE_ALARM
01020     printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_cmd.fe_alarms);
01021 #endif
01022     
01023     printf("\trx pkt\t%d\ttx pkt\t%d\n",tdm_api->wp_cmd.stats.rx_packets,
01024                 tdm_api->wp_cmd.stats.tx_packets);
01025     printf("\trx err\t%d\ttx err\t%d\n",
01026                 tdm_api->wp_cmd.stats.rx_errors,
01027                 tdm_api->wp_cmd.stats.tx_errors);
01028 #ifndef __WINDOWS__
01029     printf("\trx ovr\t%d\ttx idl\t%d\n",
01030                 tdm_api->wp_cmd.stats.rx_fifo_errors,
01031                 tdm_api->wp_cmd.stats.tx_carrier_errors);
01032 #endif      
01033 #endif      
01034     
01035     return 0;
01036 }
01037 
01038 /*========================================================
01039  * SET Codec on a particular Channel.
01040  * 
01041  * Available codecs are defined in 
01042  * /usr/src/linux/include/linux/wanpipe_cfg.h
01043  * 
01044  * enum wan_codec_format {
01045  *      WP_NONE,
01046  *  WP_SLINEAR
01047  * }
01048  *
01049  */
01050 int _SAPI_CALL sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_api_t *tdm_api, int codec)
01051 {
01052     int err;
01053 
01054     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_CODEC;
01055     tdm_api->wp_cmd.tdm_codec = codec;
01056 
01057     err=sangoma_cmd_exec(fd,tdm_api);
01058 
01059     return err;
01060 }
01061 
01062 /*========================================================
01063  * GET Codec from a particular Channel.
01064  * 
01065  * Available codecs are defined in 
01066  * /usr/src/linux/include/linux/wanpipe_cfg.h
01067  * 
01068  * enum wan_codec_format {
01069  *      WP_NONE,
01070  *  WP_SLINEAR
01071  * }
01072  *
01073  */
01074 int _SAPI_CALL sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01075 {
01076     int err;
01077 
01078     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_CODEC;
01079 
01080     err=sangoma_cmd_exec(fd,tdm_api);
01081     if (err){
01082         return err;
01083     }
01084 
01085     return tdm_api->wp_cmd.tdm_codec;   
01086 }
01087 
01088 /*========================================================
01089  * SET Rx/Tx Hardware Period in milliseconds.
01090  * 
01091  * Available options are:
01092  *  10,20,30,40,50 ms      
01093  *
01094  */
01095 int _SAPI_CALL sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_api_t *tdm_api, int period)
01096 {
01097     int err;
01098 
01099     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_USR_PERIOD;
01100     tdm_api->wp_cmd.usr_period = period;
01101 
01102     err=sangoma_cmd_exec(fd,tdm_api);
01103 
01104     return err;
01105 }
01106 
01107 /*========================================================
01108  * GET Rx/Tx Hardware Period in milliseconds.
01109  * 
01110  * Available options are:
01111  *  10,20,30,40,50 ms      
01112  *
01113  */
01114 int _SAPI_CALL sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_api_t *tdm_api)
01115 {
01116     int err;
01117 
01118     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_USR_PERIOD;
01119 
01120     err=sangoma_cmd_exec(fd,tdm_api);
01121     if (err){
01122         return err;
01123     }
01124 
01125     return tdm_api->wp_cmd.usr_period;
01126 }
01127 
01128 /*========================================================
01129  * GET Current User Hardware Coding Format
01130  *
01131  * Coding Format will be ULAW/ALAW based on T1/E1 
01132  */
01133 
01134 int _SAPI_CALL sangoma_get_hw_coding(sng_fd_t fd, wanpipe_api_t *tdm_api)
01135 {
01136         int err;
01137         tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_CODING;
01138         err=sangoma_cmd_exec(fd,tdm_api);
01139         if (err){
01140                 return err;
01141         }
01142         return tdm_api->wp_cmd.hw_tdm_coding;
01143 }
01144 
01145 #ifdef WP_API_FEATURE_DTMF_EVENTS
01146 /*========================================================
01147  * GET Current User Hardware DTMF Enabled/Disabled
01148  *
01149  * Will return true if HW DTMF is enabled on Octasic
01150  */
01151 
01152 int _SAPI_CALL sangoma_tdm_get_hw_dtmf(sng_fd_t fd, wanpipe_api_t *tdm_api)
01153 {
01154     int err;
01155     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_DTMF;
01156     err=sangoma_cmd_exec(fd,tdm_api);
01157     if (err){
01158         return err;
01159     }
01160     return tdm_api->wp_cmd.hw_dtmf;
01161 }
01162 #endif
01163 
01164 /*========================================================
01165  * GET Current User MTU/MRU values in bytes.
01166  * 
01167  * The USER MTU/MRU values will change each time a PERIOD
01168  * or CODEC is adjusted.
01169  */
01170 int _SAPI_CALL sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_api_t *tdm_api)
01171 {
01172     int err;
01173 
01174     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_USR_MTU_MRU;
01175 
01176     err=sangoma_cmd_exec(fd,tdm_api);
01177     if (err){
01178         return err;
01179     }
01180 
01181     return tdm_api->wp_cmd.usr_mtu_mru;
01182 }
01183 
01184 /*========================================================
01185  * SET TDM Power Level
01186  * 
01187  * This option is not implemented yet
01188  *
01189  */
01190 int _SAPI_CALL sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_api_t *tdm_api, int power)
01191 {
01192     int err;
01193 
01194     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_POWER_LEVEL;
01195     tdm_api->wp_cmd.power_level = power;
01196 
01197     err=sangoma_cmd_exec(fd,tdm_api);
01198 
01199     return err;
01200 }
01201 
01202 /*========================================================
01203  * GET TDM Power Level
01204  * 
01205  * This option is not implemented yet
01206  *
01207  */
01208 int _SAPI_CALL sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_api_t *tdm_api)
01209 {
01210     int err;
01211 
01212     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_POWER_LEVEL;
01213 
01214     err=sangoma_cmd_exec(fd,tdm_api);
01215     if (err){
01216         return err;
01217     }
01218 
01219     return tdm_api->wp_cmd.power_level;
01220 }
01221 
01222 int _SAPI_CALL sangoma_flush_bufs(sng_fd_t fd, wanpipe_api_t *tdm_api)
01223 {
01224     int err;
01225     tdm_api->wp_cmd.cmd = WP_API_CMD_FLUSH_BUFFERS;
01226 
01227     err=sangoma_cmd_exec(fd,tdm_api);
01228     if (err){
01229         return err;
01230     }
01231 
01232     return 0;
01233 }
01234 
01235 int _SAPI_CALL sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_api_t *tdm_api, int poll_in_sec) {
01236     
01237     int err;
01238     
01239     tdm_api->wp_cmd.cmd = WP_API_CMD_ENABLE_RBS_EVENTS;
01240     tdm_api->wp_cmd.rbs_poll=poll_in_sec;
01241     
01242     err=sangoma_cmd_exec(fd,tdm_api);
01243     if (err){
01244         return err;
01245     }
01246 
01247     return tdm_api->wp_cmd.rbs_poll;
01248 }
01249 
01250 
01251 int _SAPI_CALL sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01252 
01253     int err;
01254     tdm_api->wp_cmd.cmd = WP_API_CMD_DISABLE_RBS_EVENTS;
01255     
01256     err=sangoma_cmd_exec(fd,tdm_api);
01257     if (err){
01258         return err;
01259     }
01260 
01261     return 0;
01262 }
01263 
01264 int _SAPI_CALL sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char rbs)
01265 {
01266     
01267     int err;
01268     tdm_api->wp_cmd.cmd = WP_API_CMD_WRITE_RBS_BITS;
01269     tdm_api->wp_cmd.rbs_tx_bits=rbs;
01270     
01271     err=sangoma_cmd_exec(fd,tdm_api);
01272     if (err){
01273         return err;
01274     }
01275 
01276     return 0;
01277 }        
01278 
01279 int _SAPI_CALL sangoma_read_event(sng_fd_t fd, wanpipe_api_t *tdm_api)
01280 {
01281 
01282 #ifdef WP_API_FEATURE_EVENTS
01283     wp_api_event_t *rx_event;
01284     int err;
01285 
01286     tdm_api->wp_cmd.cmd = WP_API_CMD_READ_EVENT;
01287     
01288     err=sangoma_cmd_exec(fd,tdm_api);
01289     if (err){
01290         return err;
01291     }
01292 
01293     rx_event = &tdm_api->wp_cmd.event;
01294 
01295 
01296     /*
01297      The use of callbacks here is purely optional and is left
01298      here for backward compatibility purposes.  By default user
01299      should handle events outside this funciton. This function
01300      should only be used to read the event
01301     */
01302 
01303     switch (rx_event->wp_api_event_type){
01304     
01305     case WP_API_EVENT_RBS:
01306         if (tdm_api->wp_callback.wp_rbs_event) {
01307             tdm_api->wp_callback.wp_rbs_event(fd,rx_event->wp_api_event_rbs_bits);
01308         }
01309         
01310         break;
01311     
01312 #ifdef WP_API_FEATURE_DTMF_EVENTS
01313     case WP_API_EVENT_DTMF:
01314         if (tdm_api->wp_callback.wp_dtmf_event) {
01315             tdm_api->wp_callback.wp_dtmf_event(fd,
01316                         rx_event->wp_api_event_dtmf_digit,
01317                         rx_event->wp_api_event_dtmf_type,
01318                         rx_event->wp_api_event_dtmf_port);
01319         }
01320         break;
01321 #endif
01322         
01323     case WP_API_EVENT_RXHOOK:
01324         if (tdm_api->wp_callback.wp_rxhook_event) {
01325             tdm_api->wp_callback.wp_rxhook_event(fd,
01326                         rx_event->wp_api_event_hook_state);
01327         }
01328         break;
01329 
01330     case WP_API_EVENT_RING_DETECT:
01331         if (tdm_api->wp_callback.wp_ring_detect_event) {
01332             tdm_api->wp_callback.wp_ring_detect_event(fd,
01333                         rx_event->wp_api_event_ring_state);
01334         }
01335         break;
01336 
01337     case WP_API_EVENT_RING_TRIP_DETECT:
01338         if (tdm_api->wp_callback.wp_ring_trip_detect_event) {
01339             tdm_api->wp_callback.wp_ring_trip_detect_event(fd,
01340                         rx_event->wp_api_event_ring_state);
01341         }
01342         break;
01343 
01344 #ifdef WP_API_FEATURE_FE_ALARM
01345     case WP_API_EVENT_ALARM:
01346         if (tdm_api->wp_callback.wp_fe_alarm_event) {
01347             tdm_api->wp_callback.wp_fe_alarm_event(fd,
01348                         rx_event->wp_api_event_alarm);
01349         }   
01350         break; 
01351 #endif
01352 
01353 #ifdef WP_API_FEATURE_LINK_STATUS
01354     /* Link Status */   
01355     case WP_API_EVENT_LINK_STATUS:
01356         if(tdm_api->wp_callback.wp_link_status_event){
01357             tdm_api->wp_callback.wp_link_status_event(fd,
01358                         rx_event->wp_api_event_link_status);
01359         }
01360         
01361         break;
01362 #endif  
01363     default:
01364         printf("%d: Unknown TDM event!", (int)fd);
01365         break;
01366     }
01367     
01368     return 0;
01369 #else
01370     printf("Error: Read Event not supported!\n");
01371     return -1;
01372 #endif
01373 }        
01374 
01375 #ifdef WP_API_FEATURE_DTMF_EVENTS
01376 int _SAPI_CALL sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01377 {
01378     int err;
01379     
01380     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01381     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_DTMF;
01382     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01383     err=sangoma_cmd_exec(fd,tdm_api);
01384     if (err){
01385         return err;
01386     }
01387 
01388     return 0;
01389 }
01390 
01391 int _SAPI_CALL sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01392 {
01393     int err;
01394 
01395     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01396     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_DTMF;
01397     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01398     err=sangoma_cmd_exec(fd,tdm_api);
01399     if (err){
01400         return err;
01401     }
01402 
01403     return 0;
01404 }
01405 
01406 int _SAPI_CALL sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01407 {
01408     int err;
01409     
01410     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01411     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RM_DTMF;
01412     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01413     err=sangoma_cmd_exec(fd,tdm_api);
01414     if (err){
01415         return err;
01416     }
01417 
01418     return 0;
01419 }
01420 
01421 int _SAPI_CALL sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01422 {
01423     int err;
01424 
01425     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01426     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RM_DTMF;
01427     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01428     err=sangoma_cmd_exec(fd,tdm_api);
01429     if (err){
01430         return err;
01431     }
01432 
01433     return 0;
01434 }
01435 
01436 int _SAPI_CALL sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01437 {
01438     int err;
01439 
01440     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01441     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RXHOOK;
01442     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01443     err=sangoma_cmd_exec(fd,tdm_api);
01444     if (err){
01445         return err;
01446     }
01447 
01448     return 0;
01449 }
01450 
01451 int _SAPI_CALL sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01452 {
01453     int err;
01454 
01455     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01456     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RXHOOK;
01457     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01458     err=sangoma_cmd_exec(fd,tdm_api);
01459     if (err){
01460         return err;
01461     }
01462 
01463     return 0;
01464 }
01465 
01466 int _SAPI_CALL sangoma_tdm_enable_ring_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01467     
01468     int err;
01469     
01470     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01471     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING;
01472     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01473     
01474     err=sangoma_cmd_exec(fd,tdm_api);
01475     if (err){
01476         return err;
01477     }
01478 
01479     return 0;
01480 }
01481 
01482 
01483 int _SAPI_CALL sangoma_tdm_disable_ring_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01484 
01485     int err;
01486     
01487     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01488     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING;
01489     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01490     
01491     err=sangoma_cmd_exec(fd,tdm_api);
01492     if (err){
01493         return err;
01494     }
01495 
01496     return 0;
01497 }
01498 
01499 int _SAPI_CALL sangoma_tdm_enable_ring_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01500     
01501     int err;
01502     
01503     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01504     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
01505     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01506     err=sangoma_cmd_exec(fd,tdm_api);
01507     if (err){
01508         return err;
01509     }
01510 
01511     return err;
01512 }
01513 
01514 
01515 int _SAPI_CALL sangoma_tdm_disable_ring_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01516 
01517     int err;
01518     
01519     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01520     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
01521     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01522     err=sangoma_cmd_exec(fd,tdm_api);
01523     if (err){
01524         return err;
01525     }
01526 
01527     return 0;
01528 }
01529 
01530 int _SAPI_CALL sangoma_tdm_enable_ring_trip_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01531     
01532     int err;
01533     
01534     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01535     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_TRIP_DETECT;
01536     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01537     err=sangoma_cmd_exec(fd,tdm_api);
01538     if (err){
01539         return err;
01540     }
01541 
01542     return tdm_api->wp_cmd.rbs_poll;
01543 }
01544 
01545 
01546 int _SAPI_CALL sangoma_tdm_disable_ring_trip_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01547 
01548     int err;
01549     
01550     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01551     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
01552     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01553     err=sangoma_cmd_exec(fd,tdm_api);
01554     if (err){
01555         return err;
01556     }
01557 
01558     return 0;
01559 }
01560 
01561 int _SAPI_CALL sangoma_tdm_txsig_kewl(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01562 
01563     int err;
01564     
01565     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01566     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_KEWL;
01567     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01568     err=sangoma_cmd_exec(fd,tdm_api);
01569     if (err){
01570         return err;
01571     }
01572 
01573     return 0;
01574 }
01575 
01576 int _SAPI_CALL sangoma_tdm_txsig_start(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01577 
01578     int err;
01579     
01580     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01581     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_START;
01582     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01583     err=sangoma_cmd_exec(fd,tdm_api);
01584     if (err){
01585         return err;
01586     }
01587 
01588     return 0;
01589 }
01590 
01591 int _SAPI_CALL sangoma_tdm_txsig_onhook(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01592 
01593     int err;
01594     
01595     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01596     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_ONHOOK;
01597     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01598     err=sangoma_cmd_exec(fd,tdm_api);
01599     if (err){
01600         return err;
01601     }
01602 
01603     return 0;
01604 }
01605 
01606 int _SAPI_CALL sangoma_tdm_txsig_offhook(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01607 
01608     int err;
01609     
01610     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01611     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_OFFHOOK;
01612     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01613     err=sangoma_cmd_exec(fd,tdm_api);
01614     if (err){
01615         return err;
01616     }
01617 
01618     return 0;
01619 }
01620 
01621 
01622 int _SAPI_CALL sangoma_tdm_enable_tone_events(sng_fd_t fd, wanpipe_api_t *tdm_api, uint16_t tone_id) {
01623     
01624     int err;
01625     
01626     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01627     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TONE;
01628     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01629     tdm_api->wp_cmd.event.wp_api_event_tone_type = tone_id;
01630     err=sangoma_cmd_exec(fd,tdm_api);
01631     if (err){
01632         return err;
01633     }
01634 
01635     return tdm_api->wp_cmd.rbs_poll;
01636 }
01637 
01638 int _SAPI_CALL sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01639     
01640     int err;
01641     
01642     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01643     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TONE;
01644     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01645     tdm_api->wp_cmd.event.wp_api_event_tone_type = 0x00;
01646     err=sangoma_cmd_exec(fd,tdm_api);
01647     if (err){
01648         return err;
01649     }
01650 
01651     return tdm_api->wp_cmd.rbs_poll;
01652 }
01653 
01654 #endif
01655 
01656 int _SAPI_CALL sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01657 {
01658         int err;
01659 
01660         tdm_api->wp_cmd.cmd = WP_API_CMD_ENABLE_HWEC;
01661         err=sangoma_cmd_exec(fd,tdm_api);
01662         if (err){
01663                 return err;
01664         }
01665 
01666         return 0;
01667 }
01668 
01669 int _SAPI_CALL sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01670 {
01671         int err;
01672 
01673         tdm_api->wp_cmd.cmd = WP_API_CMD_DISABLE_HWEC;
01674         err=sangoma_cmd_exec(fd,tdm_api);
01675         if (err){
01676                 return err;
01677         }
01678 
01679         return 0;
01680 }
01681 
01682 
01683 /*========================================================
01684  * GET Front End Alarms
01685  * 
01686  */                  
01687 #ifdef WP_API_FEATURE_FE_ALARM
01688 int _SAPI_CALL sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_api_t *tdm_api)
01689 {
01690     int err;
01691 
01692     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_ALARMS;
01693 
01694     err=sangoma_cmd_exec(fd,tdm_api);
01695     if (err){
01696         return err;
01697     }
01698 
01699     return tdm_api->wp_cmd.fe_alarms;
01700 }         
01701 
01702 /* get current Line Connection state - Connected/Disconnected */
01703 int _SAPI_CALL sangoma_get_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
01704 {
01705     int err;
01706 
01707     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_STATUS;
01708     err = sangoma_cmd_exec(fd, tdm_api);
01709     *current_status = tdm_api->wp_cmd.fe_status;
01710 
01711     return err;
01712 }
01713 #endif
01714 
01715 /* get current Line Connection state - Connected/Disconnected */
01716 #ifdef WP_API_FEATURE_LINK_STATUS
01717 int _SAPI_CALL sangoma_get_link_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
01718 {
01719     int err;
01720 
01721     tdm_api->wp_cmd.cmd = WANPIPEMON_AFT_LINK_STATUS;
01722     err = sangoma_cmd_exec(fd, tdm_api);
01723     *current_status = tdm_api->wp_cmd.fe_status;
01724 
01725     return err;
01726 }
01727 
01728 /* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */
01729 int _SAPI_CALL sangoma_set_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char new_status)
01730 {
01731     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_FE_STATUS;
01732     tdm_api->wp_cmd.fe_status = new_status;
01733 
01734     return sangoma_cmd_exec(fd, tdm_api);
01735 }
01736 #endif
01737 
01738 #endif /* WANPIPE_TDM_API */

Generated on Tue Jan 6 18:07:39 2009 for sample_c by  doxygen 1.4.7