libsangoma.c

Go to the documentation of this file.
00001 /*******************************************************************************/
00035 #include "libsangoma-pvt.h"
00036 
00037 static void libsng_dbg(const char * fmt, ...)
00038 {
00039     va_list args;
00040     char buf[1024];
00041     va_start(args, fmt);
00042     _vsnprintf(buf, sizeof(buf), fmt, args);
00043 #if defined(__WINDOWS__)
00044     OutputDebugString(buf);
00045 #else
00046     printf(buf);
00047 #endif
00048     va_end(args);
00049 }
00050 
00051 /*********************************************************************/
00055 #define DBG_POLL    if(0)libsng_dbg
00056 #define DBG_EVNT    if(0)libsng_dbg
00057 #define DBG_ERR     if(0)libsng_dbg("Error: %s() line: %d : ", __FUNCTION__, __LINE__);if(0)libsng_dbg
00058 #define DBG_INIT    if(0)libsng_dbg
00059 
00060 #if defined(__WINDOWS__)
00061 
00062 /*
00063   \fn static void DecodeLastError(LPSTR lpszFunction)
00064   \brief Decodes the Error in radable format.
00065   \param lpszFunction error string
00066 
00067   Private Windows Only Function
00068  */
00069 static void DecodeLastError(LPSTR lpszFunction) 
00070 { 
00071     LPVOID lpMsgBuf;
00072     DWORD dwLastErr = GetLastError();
00073     FormatMessage( 
00074         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
00075         FORMAT_MESSAGE_FROM_SYSTEM | 
00076         FORMAT_MESSAGE_IGNORE_INSERTS,
00077         NULL,
00078         dwLastErr,
00079         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
00080         (LPTSTR) &lpMsgBuf,
00081         0,
00082         NULL 
00083     );
00084     // Display the string.
00085     DBG_POLL("Last Error in %s(): %s (%d)\n", lpszFunction, lpMsgBuf, dwLastErr);
00086     // Free the buffer.
00087     LocalFree( lpMsgBuf );
00088 } 
00089 
00090 /*
00091   \fn static int handle_device_ioctl_result(int bResult)
00092   \brief Checks result code of ioctl
00093   \param bResult result of ioctl call
00094 
00095   Private Windows Only Function
00096  */
00097 static u16 handle_device_ioctl_result(int bResult, char *caller_name)
00098 {
00099     if(bResult == 0){
00100         //error
00101         DecodeLastError(caller_name);
00102         return 1;
00103 
00104     }else{
00105         return 0;
00106     }
00107 }
00108 
00109 /*
00110   \fn static int DoManagementCommand(HANDLE fd, wan_udp_hdr_t* wan_udp)
00111   \brief Executes Driver Management Command
00112   \param fd device file descriptor
00113   \param wan_udp managemet cmd structure
00114 
00115   Private Windows Function
00116  */
00117 static int DoManagementCommand(HANDLE fd, wan_udp_hdr_t* wan_udp)
00118 {
00119     DWORD ln, bIoResult;
00120     unsigned char id = 0;
00121 
00122     wan_udp->wan_udphdr_request_reply = 0x01;
00123     wan_udp->wan_udphdr_id = id;
00124     wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
00125 
00126     bIoResult = DeviceIoControl(
00127             fd,
00128             IoctlManagementCommand,
00129             (LPVOID)wan_udp,
00130             sizeof(wan_udp_hdr_t),
00131             (LPVOID)wan_udp,
00132             sizeof(wan_udp_hdr_t),
00133             (LPDWORD)(&ln),
00134             (LPOVERLAPPED)NULL
00135             );
00136 
00137     return handle_device_ioctl_result(bIoResult, __FUNCTION__);
00138 }
00139 
00140 /*
00141   \fn static int DoTdmvApiCommand(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00142   \brief Executes Driver TDM API Command
00143   \param fd device file descriptor
00144   \param api_cmd tdm_api managemet cmd structure
00145 
00146   Private Windows Function
00147  */
00148 static int DoTdmvApiCommand(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00149 {
00150     DWORD ln, bIoResult;
00151 
00152     bIoResult = DeviceIoControl(
00153             fd,
00154             IoctlTdmApiCommand,
00155             (LPVOID)api_cmd,
00156             sizeof(wanpipe_tdm_api_cmd_t),
00157             (LPVOID)api_cmd,
00158             sizeof(wanpipe_tdm_api_cmd_t),
00159             (LPDWORD)(&ln),
00160             (LPOVERLAPPED)NULL
00161             );
00162 
00163     return handle_device_ioctl_result(bIoResult, __FUNCTION__);
00164 }
00165 
00166 /*
00167   \fn static int tdmv_api_ioctl(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00168   \brief Executes Driver TDM API Command Wrapper Function
00169   \param fd device file descriptor
00170   \param api_cmd tdm_api managemet cmd structure
00171 
00172   Private Windows Function
00173  */
00174 static int tdmv_api_ioctl(HANDLE fd, wanpipe_tdm_api_cmd_t *api_cmd)
00175 {
00176     if(DoTdmvApiCommand(fd, api_cmd)){
00177         return SANG_STATUS_GENERAL_ERROR;
00178     }
00179 
00180     return api_cmd->result;
00181 }
00182 
00183 /*
00184   \fn static USHORT DoReadCommand(HANDLE drv, RX_DATA_STRUCT * pRx)
00185   \brief  API READ Function
00186   \param drv device file descriptor
00187   \param pRx receive data structure
00188 
00189   Private Windows Function
00190   This function will NOT block because using IoctlReadCommandNonBlocking.
00191  */
00192 static USHORT DoReadCommand(HANDLE drv, RX_DATA_STRUCT * pRx)
00193 {
00194     DWORD ln, bIoResult;
00195 
00196     bIoResult = DeviceIoControl(
00197             drv,
00198             IoctlReadCommandNonBlocking,
00199             (LPVOID)NULL,//NO input buffer!
00200             0,
00201             (LPVOID)pRx,
00202             sizeof(RX_DATA_STRUCT),
00203             (LPDWORD)(&ln),
00204             (LPOVERLAPPED)NULL);
00205 
00206     return handle_device_ioctl_result(bIoResult, __FUNCTION__);
00207 }
00208 
00209 /*
00210   \fn static UCHAR DoWriteCommand(HANDLE drv, TX_DATA_STRUCT * pTx)
00211   \brief API Write Function
00212   \param drv device file descriptor
00213   \param pRx receive data structure
00214 
00215   Private Windows Function
00216   In Legacy API mode this fuction will Block if data is busy.
00217   In API mode no function is allowed to Block
00218  */
00219 static UCHAR DoWriteCommand(HANDLE drv,
00220                             void *input_data_buffer, u32 size_of_input_data_buffer,
00221                             void *output_data_buffer, u32 size_of_output_data_buffer
00222                             )
00223 {
00224     DWORD BytesReturned, bIoResult;
00225 
00226     bIoResult = DeviceIoControl(
00227             drv,
00228             IoctlWriteCommand,
00229             (LPVOID)input_data_buffer,
00230             size_of_input_data_buffer,
00231             (LPVOID)output_data_buffer,
00232             size_of_output_data_buffer,
00233             (LPDWORD)(&BytesReturned),
00234             (LPOVERLAPPED)NULL);
00235 
00236     return (UCHAR)handle_device_ioctl_result(bIoResult, __FUNCTION__);  
00237 }
00238 
00239 /*
00240   \fn static USHORT sangoma_poll_fd(HANDLE drv, API_POLL_STRUCT *api_poll_ptr)
00241   \brief Non Blocking API Poll function used to find out if Rx Data, Events or
00242             Free Tx buffer available
00243   \param drv device file descriptor
00244   \param api_poll_ptr poll device that stores polling information read/write/event
00245   \param overlapped pointer to system overlapped io structure.
00246 
00247   Private Windows Function
00248  */
00249 static USHORT sangoma_poll_fd(sng_fd_t fd, API_POLL_STRUCT *api_poll_ptr)
00250 {
00251     DWORD ln, bIoResult;
00252 
00253     bIoResult = DeviceIoControl(
00254             fd,
00255             IoctlApiPoll,
00256             (LPVOID)NULL,
00257             0L,
00258             (LPVOID)api_poll_ptr,
00259             sizeof(API_POLL_STRUCT),
00260             (LPDWORD)(&ln),
00261             (LPOVERLAPPED)NULL);
00262 
00263     return handle_device_ioctl_result(bIoResult, __FUNCTION__);
00264 }
00265 
00266 static USHORT DoSetSharedEventCommand(HANDLE drv, PREGISTER_EVENT event)
00267 {
00268     DWORD ln, bIoResult;
00269 
00270     bIoResult = DeviceIoControl(
00271             drv,
00272             IoctlSetSharedEvent,
00273             (LPVOID)event,
00274             sizeof(REGISTER_EVENT),
00275             (LPVOID)event,
00276             sizeof(REGISTER_EVENT),
00277             (LPDWORD)(&ln),
00278             (LPOVERLAPPED)NULL);
00279 
00280     return handle_device_ioctl_result(bIoResult, __FUNCTION__);
00281 }
00282 
00283 static int init_sangoma_event_object(sangoma_wait_obj_t *sng_wait_obj, int flags_in)
00284 {
00285     int event_index = -1;
00286     
00287     if(flags_in & POLLIN){
00288         event_index = LIBSNG_EVENT_INDEX_POLLIN;
00289     }
00290 
00291     if(flags_in & POLLOUT){
00292         event_index = LIBSNG_EVENT_INDEX_POLLOUT;
00293     }
00294 
00295     if(flags_in & POLLPRI){
00296         event_index = LIBSNG_EVENT_INDEX_POLLPRI;
00297     }
00298 
00299     if(event_index == -1){
00300         /* invalid 'flags_in', this should be an assert */
00301         return SANG_STATUS_GENERAL_ERROR;
00302     }
00303 
00304     sng_wait_obj->sng_event_objects[event_index].hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
00305     if(!sng_wait_obj->sng_event_objects[event_index].hEvent){
00306         //error
00307         return SANG_STATUS_GENERAL_ERROR;
00308     }
00309 
00310     sng_wait_obj->sng_event_objects[event_index].user_flags_bitmap = flags_in;
00311     if(DoSetSharedEventCommand(sng_wait_obj->fd, &sng_wait_obj->sng_event_objects[event_index])){
00312         //error
00313         return SANG_STATUS_GENERAL_ERROR;
00314     }
00315 
00316     return sng_wait_obj->sng_event_objects[event_index].operation_status;
00317 }
00318 
00319 static void sangoma_reset_wait_obj(sangoma_wait_obj_t *sng_wait_obj, int flags_in)
00320 {
00321     if(flags_in & POLLIN){
00322         if(sng_wait_obj->sng_event_objects[LIBSNG_EVENT_INDEX_POLLIN].hEvent){
00323             ResetEvent(sng_wait_obj->sng_event_objects[LIBSNG_EVENT_INDEX_POLLIN].hEvent);
00324         }
00325     }
00326 
00327     if(flags_in & POLLOUT){
00328         if(sng_wait_obj->sng_event_objects[LIBSNG_EVENT_INDEX_POLLOUT].hEvent){
00329             ResetEvent(sng_wait_obj->sng_event_objects[LIBSNG_EVENT_INDEX_POLLOUT].hEvent);
00330         }
00331     }
00332 
00333     if(flags_in & POLLPRI){
00334         if(sng_wait_obj->sng_event_objects[LIBSNG_EVENT_INDEX_POLLPRI].hEvent){
00335             ResetEvent(sng_wait_obj->sng_event_objects[LIBSNG_EVENT_INDEX_POLLPRI].hEvent);
00336         }
00337     }
00338 }
00339 
00340 static sangoma_status_t _SAPI_CALL sangoma_wait_obj_poll(sangoma_wait_obj_t *sangoma_wait_object, int flags_in, int *flags_out)
00341 {
00342     int err;
00343     sangoma_wait_obj_t *sng_wait_obj = sangoma_wait_object;
00345     API_POLL_STRUCT api_poll;
00346 
00347     *flags_out = 0;
00348 
00349     memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT));
00350     api_poll.user_flags_bitmap = flags_in;
00351 
00352     /* This call is non-blocking - it will return immediatly. */
00353     if(sangoma_poll_fd(sng_wait_obj->fd, &api_poll)){
00354         /* error - ioctl failed */
00355         return SANG_STATUS_IO_ERROR;
00356     }
00357 
00358     if(api_poll.operation_status == SANG_STATUS_SUCCESS){
00359         *flags_out = api_poll.poll_events_bitmap;
00360         err = 0;
00361     }else{
00362         /* error - command failed */
00363         err = api_poll.operation_status;
00364     }
00365 
00366     if(*flags_out == 0){
00367         DBG_POLL("======%s(): *flags_out: 0x%X, flags_in: 0x%X\n", __FUNCTION__, *flags_out, flags_in);
00368     }
00369     return err;
00370 }
00371 
00372 static int check_number_of_wait_objects(uint32_t number_of_objects, const char *caller_function, int lineno)
00373 {
00374     if(number_of_objects >= MAXIMUM_WAIT_OBJECTS){
00375         DBG_ERR("Caller: %s(): Line: %d: 'number_of_objects': %d is greater than the Maximum of: %d\n", 
00376             caller_function, lineno, number_of_objects, MAXIMUM_WAIT_OBJECTS);
00377         return 1;
00378     }
00379     return 0;
00380 }
00381 
00382 static sangoma_status_t get_out_flags(IN sangoma_wait_obj_t *sng_wait_objects[],
00383                                       IN uint32_t in_flags[], OUT uint32_t out_flags[],
00384                                       IN uint32_t number_of_sangoma_wait_objects,
00385                                       IN BOOL   reset_events_if_out_flags_set,
00386                                       OUT BOOL  *at_least_one_poll_set_flags_out)
00387 {
00388     uint32_t i, j;
00389 
00390     if(at_least_one_poll_set_flags_out){
00391         *at_least_one_poll_set_flags_out = FALSE;
00392     }
00393 
00394     for(i = 0; i < number_of_sangoma_wait_objects; i++) {
00395 
00396         sangoma_wait_obj_t *sangoma_wait_object = sng_wait_objects[i];
00397         if (!SANGOMA_OBJ_HAS_DEVICE(sangoma_wait_object)) {
00398             continue;
00399         }
00400 
00401         for(j = 0; j < LIBSNG_NUMBER_OF_EVENT_OBJECTS; j++){
00402 
00403             if(!sangoma_wait_object->sng_event_objects[j].hEvent) {
00404                 continue;
00405             }
00406 
00407             if(sangoma_wait_obj_poll(sangoma_wait_object, in_flags[i], &out_flags[i])){
00408                 return SANG_STATUS_GENERAL_ERROR;
00409             }
00410 
00411             if( out_flags[i] & in_flags[i] ){
00412                 if(TRUE == reset_events_if_out_flags_set){
00413                     sangoma_reset_wait_obj(sangoma_wait_object, out_flags[i]);/* since we are NOT going to wait on this event, reset it 'manually' */
00414                 }
00415                 if(at_least_one_poll_set_flags_out){
00416                     *at_least_one_poll_set_flags_out = TRUE;
00417                 }
00418             }
00419         }
00420     }
00421 
00422     return SANG_STATUS_SUCCESS;
00423 }
00424 #endif  /* __WINDOWS__ */
00425 
00426 
00427 /*********************************************************************/
00433 /************************************************************/
00446 sangoma_status_t _SAPI_CALL sangoma_wait_obj_create(sangoma_wait_obj_t **sangoma_wait_object, sng_fd_t fd, sangoma_wait_obj_type_t object_type)
00447 {
00448     int err = 0;
00449     sangoma_wait_obj_t *sng_wait_obj;
00450 
00451     if (!sangoma_wait_object) { 
00452         return SANG_STATUS_INVALID_DEVICE;
00453     }
00454     *sangoma_wait_object = NULL;
00455     sng_wait_obj = malloc(sizeof(**sangoma_wait_object));
00456     if (!sng_wait_obj) {
00457         return SANG_STATUS_FAILED_ALLOCATE_MEMORY;
00458     }
00459 
00460     memset(sng_wait_obj, 0x00, sizeof(*sng_wait_obj));
00461     /* it is a first initialization of the object */
00462     sng_wait_obj->init_flag = LIBSNG_MAGIC_NO;
00463 
00464     sng_wait_obj->fd            = fd;
00465     sng_wait_obj->object_type   = object_type;
00466 
00467 #if defined(__WINDOWS__)
00468     DBG_INIT("%s(): sng_wait_obj ptr: 0x%p\n", __FUNCTION__, sng_wait_obj);
00469     DBG_INIT("%s(): fd: 0x%X, object_type: %s\n", __FUNCTION__, fd, DECODE_SANGOMA_WAIT_OBJECT_TYPE(object_type));
00470     DBG_INIT("%s(): sizeof(**sangoma_wait_object): %d\n", __FUNCTION__, sizeof(**sangoma_wait_object));
00471 
00472     if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
00473         sng_wait_obj->generic_event_object.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
00474         if(!sng_wait_obj->generic_event_object.hEvent){
00475             return SANG_STATUS_GENERAL_ERROR;
00476         }
00477     }
00478 
00479     if(SANGOMA_GENERIC_WAIT_OBJ == object_type){
00480         /* everything is done for the generic wait object */
00481         *sangoma_wait_object = sng_wait_obj;
00482         return SANG_STATUS_SUCCESS;
00483     }
00484 
00485     err = init_sangoma_event_object(sng_wait_obj, POLLIN /* must be a SINGLE bit because there is a signaling object for each bit */);
00486     if(SANG_STATUS_SUCCESS != err){
00487         return err;
00488     }
00489 
00490     err = init_sangoma_event_object(sng_wait_obj, POLLOUT /* must be a SINGLE bit because there is a signaling object for each bit */);
00491     if(SANG_STATUS_SUCCESS != err){
00492         return err;
00493     }
00494 
00495     err = init_sangoma_event_object(sng_wait_obj, POLLPRI /* must be a SINGLE bit because there is a signaling object for each bit */);
00496     if(SANG_STATUS_SUCCESS != err) {
00497         return err;
00498     }
00499         
00500     DBG_INIT("%s(): returning: %d", __FUNCTION__, err);
00501 #else
00502     int filedes[2];
00503     if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
00504         sng_wait_obj->signal_read_fd = INVALID_HANDLE_VALUE;
00505         sng_wait_obj->signal_write_fd = INVALID_HANDLE_VALUE;
00506         /* if we want cross-process event notification we can use a named pipe with mkfifo() */
00507         if (pipe(filedes)) {
00508             return -1;
00509         }
00510         sng_wait_obj->signal_read_fd = filedes[0];
00511         sng_wait_obj->signal_write_fd = filedes[1];
00512     }
00513 #endif
00514     *sangoma_wait_object = sng_wait_obj;
00515     return err;
00516 }
00517 
00524 sangoma_status_t _SAPI_CALL sangoma_wait_obj_delete(sangoma_wait_obj_t **sangoma_wait_object)
00525 {
00526     sangoma_wait_obj_t *sng_wait_obj = *sangoma_wait_object;
00527 #if defined(__WINDOWS__)
00528     int index = 0;
00529 #endif
00530 
00531     if(sng_wait_obj->init_flag != LIBSNG_MAGIC_NO){
00532         /* error. object was not initialized by sangoma_wait_obj_init() */
00533         return SANG_STATUS_INVALID_DEVICE;
00534     }
00535 
00536 #if defined(__WINDOWS__)
00537     if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
00538         sangoma_close(&sng_wait_obj->generic_event_object.hEvent);
00539     }
00540     if (SANGOMA_OBJ_HAS_DEVICE(sng_wait_obj)) {
00541         for(index = 0; index < LIBSNG_NUMBER_OF_EVENT_OBJECTS; index++){
00542             sangoma_close(&sng_wait_obj->sng_event_objects[index].hEvent);
00543         }
00544     }
00545 #else
00546     if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
00547         sangoma_close(&sng_wait_obj->signal_read_fd);
00548         sangoma_close(&sng_wait_obj->signal_write_fd);
00549     }
00550 #endif
00551     sng_wait_obj->init_flag = 0;
00552     sng_wait_obj->object_type = UNKNOWN_WAIT_OBJ;
00553     *sangoma_wait_object = NULL;
00554     return SANG_STATUS_SUCCESS;
00555 }
00556 
00563 int _SAPI_CALL sangoma_wait_obj_signal(sangoma_wait_obj_t *sng_wait_obj)
00564 {
00565     if (!SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
00566         /* even when Windows objects are always signalable for the sake of providing
00567          * a consistent interface to the user we downgrade the capabilities of Windows
00568          * objects unless the sangoma wait object is explicitly initialized as signalable
00569          * */
00570         return SANG_STATUS_INVALID_DEVICE;
00571     }
00572 #if defined(__WINDOWS__)
00573     if(sng_wait_obj->generic_event_object.hEvent){
00574         if (!SetEvent(sng_wait_obj->generic_event_object.hEvent)) {
00575             return SANG_STATUS_GENERAL_ERROR;
00576         }
00577     }
00578 #else
00579     /* at this point we know is a signalable object and has a signal_write_fd */
00580     if (write(sng_wait_obj->signal_write_fd, "s", 1) < 1) {
00581         return SANG_STATUS_GENERAL_ERROR;
00582     }
00583 #endif
00584     return SANG_STATUS_SUCCESS;
00585 }
00586 
00593 sng_fd_t _SAPI_CALL sangoma_wait_obj_get_fd(sangoma_wait_obj_t *sng_wait_obj)
00594 {
00595     return sng_wait_obj->fd;
00596 }
00597 
00606 void _SAPI_CALL sangoma_wait_obj_set_context(sangoma_wait_obj_t *sng_wait_obj, void *context)
00607 {
00608     sng_wait_obj->context = context;
00609 }
00610 
00617 void* _SAPI_CALL sangoma_wait_obj_get_context(sangoma_wait_obj_t *sng_wait_obj)
00618 {
00619     return sng_wait_obj->context;
00620 }
00621 
00632 sangoma_status_t _SAPI_CALL sangoma_waitfor_many(sangoma_wait_obj_t *sng_wait_objects[], uint32_t in_flags[], uint32_t out_flags[],
00633         uint32_t number_of_sangoma_wait_objects, int32_t system_wait_timeout)
00634 {
00635 #if defined(__WINDOWS__)
00636     HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
00637     int at_least_one_poll_set_flags_out, number_of_internal_signaling_objects, err;
00638 #endif
00639     uint32_t i = 0, j = 0;
00640 
00641     memset(out_flags, 0x00, number_of_sangoma_wait_objects * sizeof(out_flags[0]));
00642 #if defined(__WINDOWS__)
00643     /* This loop will calculate 'number_of_internal_signaling_objects' and will initialize 'hEvents'
00644      * based on 'number_of_sangoma_wait_objects' and 'in_flags'.  */
00645     number_of_internal_signaling_objects = 0;
00646     for(i = 0; i < number_of_sangoma_wait_objects; i++){
00647         sangoma_wait_obj_t *sangoma_wait_object = sng_wait_objects[i];
00648 
00649         /* if SANGOMA_OBJ_IS_SIGNALABLE add the generic_event_object.hEvent to the hEvents */
00650         if(sangoma_wait_object->generic_event_object.hEvent){
00651             if(check_number_of_wait_objects(number_of_internal_signaling_objects, __FUNCTION__, __LINE__)){
00652                 return SANG_STATUS_NO_FREE_BUFFERS;
00653             }
00654             hEvents[number_of_internal_signaling_objects] = sangoma_wait_object->generic_event_object.hEvent;
00655             number_of_internal_signaling_objects++;
00656         }
00657 
00658         for(j = 0; j < LIBSNG_NUMBER_OF_EVENT_OBJECTS; j++){
00659             if(sangoma_wait_object->sng_event_objects[j].hEvent){
00660                 if( ((j == LIBSNG_EVENT_INDEX_POLLIN)   && (in_flags[i] & POLLIN))  ||
00661                     ((j == LIBSNG_EVENT_INDEX_POLLOUT)  && (in_flags[i] & POLLOUT)) ||
00662                     ((j == LIBSNG_EVENT_INDEX_POLLPRI)  && (in_flags[i] & POLLPRI)) ){
00663 
00664                     if(check_number_of_wait_objects(number_of_internal_signaling_objects, __FUNCTION__, __LINE__)){
00665                         return SANG_STATUS_NO_FREE_BUFFERS;
00666                     }
00667                     hEvents[number_of_internal_signaling_objects] = sangoma_wait_object->sng_event_objects[j].hEvent;
00668                     number_of_internal_signaling_objects++;
00669                 }
00670             }/* if () */
00671         }/* for() */
00672     }/* for() */
00673 
00674     if(number_of_internal_signaling_objects < 1){
00675         DBG_ERR("'number_of_internal_signaling_objects': %d is less than the Minimum of: 1!\n",
00676             number_of_internal_signaling_objects);
00677         /* error - most likely the user did not initialize sng_wait_objects[] */
00678         return SANG_STATUS_INVALID_PARAMETER;
00679     }
00680 
00681     at_least_one_poll_set_flags_out = FALSE;
00682 
00683     /* It is important to get 'out flags' BEFORE the WaitForMultipleObjects()
00684      * because it allows to keep API driver's transmit queue full. */
00685     err = get_out_flags(sng_wait_objects, in_flags, out_flags, number_of_sangoma_wait_objects, TRUE, &at_least_one_poll_set_flags_out);
00686     if(SANG_ERROR(err)){
00687         return err;
00688     }
00689 
00690     if(TRUE == at_least_one_poll_set_flags_out){
00691         return SANG_STATUS_SUCCESS;
00692     }
00693 
00694     /* wait untill at least one of the events is signaled OR a 'system_wait_timeout' occured */
00695     if (WAIT_TIMEOUT == WaitForMultipleObjects(number_of_internal_signaling_objects, &hEvents[0], FALSE, system_wait_timeout)){
00696         return SANG_STATUS_APIPOLL_TIMEOUT;
00697     }
00698 
00699     /* WaitForMultipleObjects() was waken by a Sangoma or by a non-Sangoma wait object. */
00700     err = get_out_flags(sng_wait_objects, in_flags, out_flags, number_of_sangoma_wait_objects, TRUE, NULL);
00701     if(SANG_ERROR(err)){
00702         return err;
00703     }
00704 
00705     return SANG_STATUS_SUCCESS;
00706 #else
00707     struct pollfd pfds[number_of_sangoma_wait_objects*2]; /* we need twice as many polls because of the sangoma signalable objects */
00708     char dummy_buf[1];
00709     int res;
00710     j = 0;
00711 
00712     memset(pfds, 0, sizeof(pfds));
00713 
00714     for(i = 0; i < number_of_sangoma_wait_objects; i++){
00715 
00716         if (SANGOMA_OBJ_HAS_DEVICE(sng_wait_objects[i])) {
00717             pfds[i].fd = sng_wait_objects[i]->fd;
00718             pfds[i].events = in_flags[i];
00719         }
00720 
00721         if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_objects[i])) {
00722             pfds[number_of_sangoma_wait_objects+j].fd = sng_wait_objects[i]->signal_read_fd;
00723             pfds[number_of_sangoma_wait_objects+j].events = POLLIN;
00724             j++;
00725         }
00726     }
00727 
00728     poll_try_again:
00729 
00730     res = poll(pfds, (number_of_sangoma_wait_objects + j), system_wait_timeout);
00731     if (res > 0) {
00732         for(i = 0; i < number_of_sangoma_wait_objects; i++){
00733             out_flags[i] = pfds[i].revents;
00734         }
00735         for(i = 0; i < j; i++){
00736             /* TODO: we must do something extra for signalled objects like setting a flag.
00737              * current user of the SANGOMA_OBJ_IS_SIGNALABLE feature is Netborder and they dont
00738              * need to know which object was signaled. If we want to know which object was signaled
00739              * we need a new libsangoma API sangoma_wait_obj_is_signaled() where in Windows we can
00740              * use WaitForSingleObject to test the signaled state and in Linux we can set a flag in
00741              * sng_wait_obj
00742              * */
00743             if (pfds[number_of_sangoma_wait_objects+i].revents & POLLIN) {
00744                 /* read and discard the signal byte */
00745                 read(pfds[number_of_sangoma_wait_objects+i].fd, &dummy_buf, 1);
00746             }
00747         }
00748     } else if (res < 0 && errno == EINTR) {
00749         /* TODO: decrement system_wait_timeout */
00750         goto poll_try_again;
00751     }
00752     if (res < 0) {
00753         return SANG_STATUS_GENERAL_ERROR;
00754     }
00755     if (res == 0) {
00756         return SANG_STATUS_APIPOLL_TIMEOUT;
00757     }
00758     return SANG_STATUS_SUCCESS;
00759 #endif
00760 }
00761 
00762 
00770 sangoma_status_t _SAPI_CALL sangoma_waitfor(sangoma_wait_obj_t *sangoma_wait_obj, uint32_t inflags, uint32_t *outflags, int32_t timeout)
00771 {
00772     return sangoma_waitfor_many(&sangoma_wait_obj, &inflags, outflags, 1, timeout);
00773 }
00774 
00775 
00776 /************************************************************/
00781 int _SAPI_CALL sangoma_span_chan_toif(int span, int chan, char *interface_name)
00782 {
00783 #if defined(__WINDOWS__)
00784 /* FIXME: Not implemented */
00785     return -1;
00786 #else
00787     sprintf(interface_name,"s%ic%i",span,chan);
00788 #endif
00789     return 0;
00790 }
00791 
00792 int _SAPI_CALL sangoma_interface_toi(char *interface_name, int *span, int *chan)
00793 {
00794     char *p=NULL, *sp = NULL, *ch = NULL;
00795     int ret = 0;
00796     char data[FNAME_LEN];
00797 
00798     strncpy(data, interface_name, FNAME_LEN);
00799     if ((data[0])) {
00800         for (p = data; *p; p++) {
00801             if (sp && *p == 'g') {
00802                 *p = '\0';
00803                 ch = (p + 1);
00804                 break;
00805             } else if (*p == 'w') {
00806                 sp = (p + 1);
00807             }
00808         }
00809 
00810         if(ch && sp) {
00811             *span = atoi(sp);
00812             *chan = atoi(ch);
00813             ret = 1;
00814         } else {
00815             *span = -1;
00816             *chan = -1;
00817         }
00818     }
00819 
00820     return ret;
00821 }
00822 
00823 int _SAPI_CALL sangoma_interface_wait_up(int span, int chan, int sectimeout)
00824 {
00825 #if defined(__WINDOWS__)
00826   /* Windows does not need to wait for interfaces to come up */
00827   return 0;
00828 #else
00829     char interface_name[FNAME_LEN];
00830   struct stat statbuf;
00831   struct timeval endtime = {0,0};
00832   struct timeval curtime = {0,0};
00833   int counter;
00834   int rc;
00835   if (sectimeout >= 0 && gettimeofday(&endtime, NULL)) {
00836     return -1;
00837   }
00838   snprintf(interface_name, sizeof(interface_name), "/dev/" WP_INTERFACE_NAME_FORM, span, chan);
00839   endtime.tv_sec += sectimeout;
00840   do {
00841     counter = 0;
00842     while ((rc = stat(interface_name, &statbuf)) && errno == ENOENT && counter != 10) {
00843       poll(0, 0, 100); // test in 100ms increments
00844       counter++;
00845     }
00846     if (!rc || errno != ENOENT) break;
00847     if (gettimeofday(&curtime, NULL)) {
00848       return -1;
00849     }
00850   } while (sectimeout < 0 || timercmp(&endtime, &curtime,>));
00851   return rc;
00852 #endif
00853 }
00854 
00855 int _SAPI_CALL sangoma_span_chan_fromif(char *interface_name, int *span, int *chan)
00856 {
00857     char *p = NULL, *sp = NULL, *ch = NULL;
00858     int ret = 0;
00859     char data[FNAME_LEN];
00860 
00861     strncpy(data, interface_name, FNAME_LEN);
00862     if ((data[0])) {
00863         for (p = data; *p; p++) {
00864             if (sp && *p == 'c') {
00865                 *p = '\0';
00866                 ch = (p + 1);
00867                 break;
00868             } else if (*p == 's') {
00869                 sp = (p + 1);
00870             }
00871         }
00872 
00873         if(ch && sp) {
00874             *span = atoi(sp);
00875             *chan = atoi(ch);
00876             ret = 1;
00877         } else {
00878             *span = -1;
00879             *chan = -1;
00880         }
00881     }
00882 
00883     return ret;
00884 }
00885 
00886 sng_fd_t _SAPI_CALL sangoma_open_api_span_chan(int span, int chan) 
00887 {
00888     sng_fd_t fd = INVALID_HANDLE_VALUE;
00889     wanpipe_api_t tdm_api;
00890     int err;
00891 
00892     fd = __sangoma_open_api_span_chan(span, chan);
00893 
00894 #if defined(__WINDOWS__)
00895     if(fd == INVALID_HANDLE_VALUE){
00896         return fd;
00897     }
00898 #else
00899     if (fd < 0) {
00900         return fd;
00901     }
00902 #endif
00903 
00904     memset(&tdm_api,0,sizeof(tdm_api));
00905     tdm_api.wp_cmd.cmd = WP_API_CMD_OPEN_CNT;
00906     err=sangoma_cmd_exec(fd,&tdm_api);
00907     if (err){
00908         sangoma_close(&fd);
00909         return fd;
00910     }
00911 
00912     if (tdm_api.wp_cmd.open_cnt > 1) {
00913         /* this is NOT the first open request for this span/chan */
00914         sangoma_close(&fd);
00915         fd = INVALID_HANDLE_VALUE;/* fd is NOT valid anymore */
00916     }
00917 
00918     return fd;
00919 }            
00920 
00921 /* no checks done for multiple open */
00922 sng_fd_t _SAPI_CALL __sangoma_open_api_span_chan(int span, int chan)
00923 {
00924     char fname[FNAME_LEN], tmp_fname[FNAME_LEN];
00925 
00926     /* Form the Interface Name from span and chan number (i.e. wanpipe1_if1). */
00927     _snprintf(tmp_fname, DEV_NAME_LEN, WP_INTERFACE_NAME_FORM, span, chan);
00928 
00929 #if defined(__WINDOWS__)
00930     _snprintf(fname , FNAME_LEN, "\\\\.\\%s", tmp_fname);
00931     return CreateFile(  fname, 
00932                         GENERIC_READ | GENERIC_WRITE, 
00933                         FILE_SHARE_READ | FILE_SHARE_WRITE,
00934                         (LPSECURITY_ATTRIBUTES)NULL, 
00935                         OPEN_EXISTING,
00936                         FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
00937                         (HANDLE)NULL
00938                         );
00939 #else
00940     sprintf(fname,"/dev/%s", tmp_fname);
00941 
00942     return open(fname, O_RDWR);
00943 #endif
00944 }            
00945 
00946 sng_fd_t _SAPI_CALL sangoma_open_api_ctrl(void)
00947 {
00948     char fname[FNAME_LEN], tmp_fname[FNAME_LEN];
00949 
00950     /* Form the Ctrl Device Name. */
00951     _snprintf(tmp_fname, DEV_NAME_LEN, WP_CTRL_DEV_NAME);
00952 
00953 #if defined(__WINDOWS__)
00954     _snprintf(fname , FNAME_LEN, "\\\\.\\%s", tmp_fname);
00955 
00956     return CreateFile(  fname, 
00957                         GENERIC_READ | GENERIC_WRITE, 
00958                         FILE_SHARE_READ | FILE_SHARE_WRITE,
00959                         (LPSECURITY_ATTRIBUTES)NULL, 
00960                         OPEN_EXISTING,
00961                         FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
00962                         (HANDLE)NULL
00963                         );
00964 #else
00965     sprintf(fname,"/dev/%s", tmp_fname);
00966 
00967     return open(fname, O_RDWR);
00968 #endif
00969 }
00970 
00971 
00972 int _SAPI_CALL sangoma_get_open_cnt(sng_fd_t fd, wanpipe_api_t *tdm_api)
00973 {
00974     int err;
00975     tdm_api->wp_cmd.cmd = WP_API_CMD_OPEN_CNT;
00976 
00977     err=sangoma_cmd_exec(fd,tdm_api);
00978     if (err){
00979         return -1;
00980     }
00981 
00982     return tdm_api->wp_cmd.open_cnt;
00983 }
00984 
00985 sng_fd_t _SAPI_CALL sangoma_create_socket_by_name(char *device, char *card) 
00986 {
00987     int span,chan;
00988     sangoma_interface_toi(device,&span,&chan);
00989     
00990     return sangoma_open_api_span_chan(span,chan);
00991 }
00992 
00993           
00994 sng_fd_t _SAPI_CALL sangoma_open_api_span(int span) 
00995 {
00996     int i=0;
00997     sng_fd_t fd = INVALID_HANDLE_VALUE;
00998 
00999     for(i = 1; i < 32; i++){
01000 
01001         fd = sangoma_open_api_span_chan(span, i);
01002 
01003 #if defined(__WINDOWS__)
01004         if(fd != INVALID_HANDLE_VALUE){
01005 #else
01006         if (fd >= 0) {
01007 #endif
01008 
01009             //found free chan
01010             break;
01011         }
01012 
01013     }//for()
01014 
01015     return fd;  
01016 }
01017 
01018 
01025 void _SAPI_CALL sangoma_close(sng_fd_t *fd)
01026 {
01027 #if defined(__WINDOWS__)
01028     if( *fd != INVALID_HANDLE_VALUE){
01029         CloseHandle(*fd);
01030         *fd = INVALID_HANDLE_VALUE;
01031     }
01032 #else
01033     if (*fd >= 0) {
01034         close(*fd);
01035         *fd = -1;
01036     }
01037 #endif
01038 }
01039 
01040 
01041 
01042 /************************************************************/
01046 int _SAPI_CALL sangoma_readmsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
01047 {
01048     int rx_len=0;
01049 
01050 #if defined(__WINDOWS__)
01051     wp_api_hdr_t    *rx_hdr = (wp_api_hdr_t*)hdrbuf;
01052     wp_api_element_t wp_api_element;
01053 
01054     if(hdrlen != sizeof(wp_api_hdr_t)){
01055         //error
01056         DBG_ERR("hdrlen (%i) != sizeof(wp_api_hdr_t) (%i)\n", hdrlen, sizeof(wp_api_hdr_t));
01057         return -1;
01058     }
01059 
01060     if(DoReadCommand(fd, &wp_api_element)){
01061         //error
01062         DBG_ERR("DoReadCommand() failed! Check messages log.\n");
01063         return -4;
01064     }
01065 
01066     memcpy(rx_hdr, &wp_api_element.hdr, sizeof(wp_api_hdr_t));
01067 
01068     switch(rx_hdr->operation_status)
01069     {
01070     case SANG_STATUS_RX_DATA_AVAILABLE:
01071         /* ok */
01072         if(rx_hdr->data_length <= datalen){
01073             memcpy(databuf, wp_api_element.data, rx_hdr->data_length);
01074         }else{
01075             rx_hdr->operation_status = SANG_STATUS_BUFFER_TOO_SMALL;
01076         }
01077         break;
01078     default:
01079         /* note that SANG_STATUS_NO_DATA_AVAILABLE is NOT an error! */
01080         if(0)DBG_ERR("Operation Status: %s(%d)\n",
01081             SDLA_DECODE_SANG_STATUS(rx_hdr->operation_status), rx_hdr->operation_status);
01082         return -5;
01083     }
01084 
01085     rx_len = rx_hdr->data_length;
01086 #else
01087     struct msghdr msg;
01088     struct iovec iov[2];
01089 
01090     memset(&msg,0,sizeof(struct msghdr));
01091 
01092     iov[0].iov_len=hdrlen;
01093     iov[0].iov_base=hdrbuf;
01094 
01095     iov[1].iov_len=datalen;
01096     iov[1].iov_base=databuf;
01097 
01098     msg.msg_iovlen=2;
01099     msg.msg_iov=iov;
01100 
01101     rx_len = read(fd,&msg,sizeof(msg));
01102 
01103     if (rx_len <= sizeof(wp_api_hdr_t)){
01104         return -EINVAL;
01105     }
01106 
01107     rx_len-=sizeof(wp_api_hdr_t);
01108 #endif
01109     return rx_len;
01110 }                    
01111 
01112 int _SAPI_CALL sangoma_writemsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
01113 {
01114     int bsent=-1;
01115     wp_api_hdr_t *wp_api_hdr = hdrbuf;
01116 
01117     if (hdrlen != sizeof(wp_api_hdr_t)) {
01118         /* error. Possible cause is a mismatch between versions of API header files. */
01119         DBG_ERR("hdrlen (%i) != sizeof(wp_api_hdr_t) (%i)\n", hdrlen, sizeof(wp_api_hdr_t));
01120         return -1;
01121     }
01122 
01123 #if defined(__WINDOWS__)
01124     //queue data for transmission
01125     if(DoWriteCommand(fd, databuf, datalen, hdrbuf, hdrlen)){
01126         //error
01127         DBG_ERR("DoWriteCommand() failed!! Check messages log.\n");
01128         return -1;
01129     }
01130 
01131     bsent=0;
01132     //check that frame was transmitted
01133     switch(wp_api_hdr->operation_status)
01134     {
01135     case SANG_STATUS_SUCCESS:
01136         bsent = datalen;
01137         break;
01138     default:
01139         DBG_ERR("Operation Status: %s(%d)\n",
01140             SDLA_DECODE_SANG_STATUS(wp_api_hdr->operation_status), wp_api_hdr->operation_status);
01141         break;
01142     }//switch()
01143 #else
01144     struct msghdr msg;
01145     struct iovec iov[2];
01146 
01147     memset(&msg,0,sizeof(struct msghdr));
01148 
01149     iov[0].iov_len=hdrlen;
01150     iov[0].iov_base=hdrbuf;
01151 
01152     iov[1].iov_len=datalen;
01153     iov[1].iov_base=databuf;
01154 
01155     msg.msg_iovlen=2;
01156     msg.msg_iov=iov;
01157 
01158     bsent = write(fd,&msg,datalen+hdrlen);
01159 
01160     if (bsent == (datalen+hdrlen)){
01161         wp_api_hdr->wp_api_hdr_operation_status=SANG_STATUS_SUCCESS;
01162         bsent-=sizeof(wp_api_hdr_t);
01163     } else if (errno == EBUSY){
01164         wp_api_hdr->wp_api_hdr_operation_status=SANG_STATUS_DEVICE_BUSY;
01165     } else {
01166         wp_api_hdr->wp_api_hdr_operation_status=SANG_STATUS_IO_ERROR;
01167     }
01168     wp_api_hdr->wp_api_hdr_data_length=bsent;
01169 
01170     //FIXME - THIS SHOULD BE DONE IN KERNEL
01171         wp_api_hdr->wp_api_tx_hdr_max_queue_length=16;
01172         wp_api_hdr->wp_api_tx_hdr_number_of_frames_in_queue=0;
01173 
01174 #endif
01175     return bsent;
01176 }
01177 
01178 
01179 #ifdef WANPIPE_TDM_API
01180 
01181 
01182 /************************************************************/
01188 /*========================================================
01189  * Execute TDM command
01190  *
01191  */
01192 int _SAPI_CALL sangoma_cmd_exec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01193 {
01194     int err;
01195 
01196 #if defined(__WINDOWS__)
01197     err = tdmv_api_ioctl(fd, &tdm_api->wp_cmd);
01198 #else
01199     err = ioctl(fd,WANPIPE_IOCTL_API_CMD,&tdm_api->wp_cmd);
01200     if (err < 0){
01201         char tmp[50];
01202         sprintf(tmp,"TDM API: CMD: %i\n",tdm_api->wp_cmd.cmd);
01203         perror(tmp);
01204         return -1;
01205     }
01206 #endif
01207     return err;
01208 }
01209 
01210 /*========================================================
01211  * Get Full TDM API configuration per channel
01212  *
01213  */
01214 int _SAPI_CALL sangoma_get_full_cfg(sng_fd_t fd, wanpipe_api_t *tdm_api)
01215 {
01216     int err;
01217 
01218     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FULL_CFG;
01219 
01220     err=sangoma_cmd_exec(fd,tdm_api);
01221     if (err){
01222         return err;
01223     }
01224 
01225 #if 0
01226     printf("TDM API CFG:\n");
01227     printf("\thw_tdm_coding:\t%d\n",tdm_api->wp_cmd.hw_tdm_coding);
01228     printf("\thw_mtu_mru:\t%d\n",tdm_api->wp_cmd.hw_mtu_mru);
01229     printf("\tusr_period:\t%d\n",tdm_api->wp_cmd.usr_period);
01230     printf("\ttdm_codec:\t%d\n",tdm_api->wp_cmd.tdm_codec);
01231     printf("\tpower_level:\t%d\n",tdm_api->wp_cmd.power_level);
01232     printf("\trx_disable:\t%d\n",tdm_api->wp_cmd.rx_disable);
01233     printf("\ttx_disable:\t%d\n",tdm_api->wp_cmd.tx_disable);
01234     printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_cmd.usr_mtu_mru);
01235     printf("\tidle flag:\t0x%02X\n",tdm_api->wp_cmd.idle_flag);
01236 
01237 #ifdef WP_API_FEATURE_FE_ALARM
01238     printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_cmd.fe_alarms);
01239 #endif
01240     
01241     printf("\trx pkt\t%d\ttx pkt\t%d\n",tdm_api->wp_cmd.stats.rx_packets,
01242                 tdm_api->wp_cmd.stats.tx_packets);
01243     printf("\trx err\t%d\ttx err\t%d\n",
01244                 tdm_api->wp_cmd.stats.rx_errors,
01245                 tdm_api->wp_cmd.stats.tx_errors);
01246 #ifndef __WINDOWS__
01247     printf("\trx ovr\t%d\ttx idl\t%d\n",
01248                 tdm_api->wp_cmd.stats.rx_fifo_errors,
01249                 tdm_api->wp_cmd.stats.tx_carrier_errors);
01250 #endif      
01251 #endif      
01252     
01253     return 0;
01254 }
01255 
01256 /*========================================================
01257  * SET Codec on a particular Channel.
01258  * 
01259  * Available codecs are defined in 
01260  * /usr/src/linux/include/linux/wanpipe_cfg.h
01261  * 
01262  * enum wan_codec_format {
01263  *      WP_NONE,
01264  *  WP_SLINEAR
01265  * }
01266  *
01267  */
01268 int _SAPI_CALL sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_api_t *tdm_api, int codec)
01269 {
01270     int err;
01271 
01272     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_CODEC;
01273     tdm_api->wp_cmd.tdm_codec = codec;
01274 
01275     err=sangoma_cmd_exec(fd,tdm_api);
01276 
01277     return err;
01278 }
01279 
01280 /*========================================================
01281  * GET Codec from a particular Channel.
01282  * 
01283  * Available codecs are defined in 
01284  * /usr/src/linux/include/linux/wanpipe_cfg.h
01285  * 
01286  * enum wan_codec_format {
01287  *      WP_NONE,
01288  *  WP_SLINEAR
01289  * }
01290  *
01291  */
01292 int _SAPI_CALL sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01293 {
01294     int err;
01295 
01296     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_CODEC;
01297 
01298     err=sangoma_cmd_exec(fd,tdm_api);
01299     if (err){
01300         return err;
01301     }
01302 
01303     return tdm_api->wp_cmd.tdm_codec;   
01304 }
01305 
01306 /*========================================================
01307  * SET Rx/Tx Hardware Period in milliseconds.
01308  * 
01309  * Available options are:
01310  *  10,20,30,40,50 ms      
01311  *
01312  */
01313 int _SAPI_CALL sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_api_t *tdm_api, int period)
01314 {
01315     int err;
01316 
01317     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_USR_PERIOD;
01318     tdm_api->wp_cmd.usr_period = period;
01319 
01320     err=sangoma_cmd_exec(fd,tdm_api);
01321 
01322     return err;
01323 }
01324 
01325 /*========================================================
01326  * GET Rx/Tx Hardware Period in milliseconds.
01327  * 
01328  * Available options are:
01329  *  10,20,30,40,50 ms      
01330  *
01331  */
01332 int _SAPI_CALL sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_api_t *tdm_api)
01333 {
01334     int err;
01335 
01336     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_USR_PERIOD;
01337 
01338     err=sangoma_cmd_exec(fd,tdm_api);
01339     if (err){
01340         return err;
01341     }
01342 
01343     return tdm_api->wp_cmd.usr_period;
01344 }
01345 
01346 /*========================================================
01347  * GET Current User Hardware Coding Format
01348  *
01349  * Coding Format will be ULAW/ALAW based on T1/E1 
01350  */
01351 
01352 int _SAPI_CALL sangoma_get_hw_coding(sng_fd_t fd, wanpipe_api_t *tdm_api)
01353 {
01354         int err;
01355         tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_CODING;
01356         err=sangoma_cmd_exec(fd,tdm_api);
01357         if (err){
01358                 return err;
01359         }
01360         return tdm_api->wp_cmd.hw_tdm_coding;
01361 }
01362 
01363 #ifdef WP_API_FEATURE_DTMF_EVENTS
01364 /*========================================================
01365  * GET Current User Hardware DTMF Enabled/Disabled
01366  *
01367  * Will return true if HW DTMF is enabled on Octasic
01368  */
01369 
01370 int _SAPI_CALL sangoma_tdm_get_hw_dtmf(sng_fd_t fd, wanpipe_api_t *tdm_api)
01371 {
01372     int err;
01373     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_DTMF;
01374     err=sangoma_cmd_exec(fd,tdm_api);
01375     if (err){
01376         return err;
01377     }
01378     return tdm_api->wp_cmd.hw_dtmf;
01379 }
01380 #endif
01381 
01382 /*========================================================
01383  * GET Current User MTU/MRU values in bytes.
01384  * 
01385  * The USER MTU/MRU values will change each time a PERIOD
01386  * or CODEC is adjusted.
01387  */
01388 int _SAPI_CALL sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_api_t *tdm_api)
01389 {
01390     int err;
01391 
01392     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_USR_MTU_MRU;
01393 
01394     err=sangoma_cmd_exec(fd,tdm_api);
01395     if (err){
01396         return err;
01397     }
01398 
01399     return tdm_api->wp_cmd.usr_mtu_mru;
01400 }
01401 
01402 /*========================================================
01403  * SET TDM Power Level
01404  * 
01405  * This option is not implemented yet
01406  *
01407  */
01408 int _SAPI_CALL sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_api_t *tdm_api, int power)
01409 {
01410     int err;
01411 
01412     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_POWER_LEVEL;
01413     tdm_api->wp_cmd.power_level = power;
01414 
01415     err=sangoma_cmd_exec(fd,tdm_api);
01416 
01417     return err;
01418 }
01419 
01420 /*========================================================
01421  * GET TDM Power Level
01422  * 
01423  * This option is not implemented yet
01424  *
01425  */
01426 int _SAPI_CALL sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_api_t *tdm_api)
01427 {
01428     int err;
01429 
01430     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_POWER_LEVEL;
01431 
01432     err=sangoma_cmd_exec(fd,tdm_api);
01433     if (err){
01434         return err;
01435     }
01436 
01437     return tdm_api->wp_cmd.power_level;
01438 }
01439 
01440 int _SAPI_CALL sangoma_flush_bufs(sng_fd_t fd, wanpipe_api_t *tdm_api)
01441 {
01442     int err;
01443     tdm_api->wp_cmd.cmd = WP_API_CMD_FLUSH_BUFFERS;
01444 
01445     err=sangoma_cmd_exec(fd,tdm_api);
01446     if (err){
01447         return err;
01448     }
01449 
01450     return 0;
01451 }
01452 
01453 int _SAPI_CALL sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_api_t *tdm_api, int poll_in_sec) {
01454     
01455     int err;
01456     
01457     tdm_api->wp_cmd.cmd = WP_API_CMD_ENABLE_RBS_EVENTS;
01458     tdm_api->wp_cmd.rbs_poll=poll_in_sec;
01459     
01460     err=sangoma_cmd_exec(fd,tdm_api);
01461     if (err){
01462         return err;
01463     }
01464 
01465     return 0;
01466 }
01467 
01468 
01469 int _SAPI_CALL sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01470 
01471     int err;
01472     tdm_api->wp_cmd.cmd = WP_API_CMD_DISABLE_RBS_EVENTS;
01473     
01474     err=sangoma_cmd_exec(fd,tdm_api);
01475     if (err){
01476         return err;
01477     }
01478 
01479     return 0;
01480 }
01481 
01482 int _SAPI_CALL sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel, unsigned char rbs)
01483 {
01484     
01485     int err;
01486     tdm_api->wp_cmd.cmd = WP_API_CMD_WRITE_RBS_BITS;
01487     tdm_api->wp_cmd.chan = (unsigned char)channel;
01488     tdm_api->wp_cmd.rbs_tx_bits=rbs;
01489     
01490     err=sangoma_cmd_exec(fd,tdm_api);
01491     if (err){
01492         return err;
01493     }
01494 
01495     return 0;
01496 }        
01497 
01498 
01499 int _SAPI_CALL sangoma_tdm_read_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel, unsigned char *rbs)
01500 {
01501     
01502     int err;
01503     tdm_api->wp_cmd.cmd = WP_API_CMD_READ_RBS_BITS;
01504     tdm_api->wp_cmd.chan = (unsigned char)channel;
01505     tdm_api->wp_cmd.rbs_tx_bits=0;
01506     
01507     err=sangoma_cmd_exec(fd,tdm_api);
01508     if (err){
01509         return err;
01510     }
01511 
01512     *rbs=(unsigned char)tdm_api->wp_cmd.rbs_rx_bits;
01513 
01514     return 0;
01515 }        
01516 
01517 int _SAPI_CALL sangoma_read_event(sng_fd_t fd, wanpipe_api_t *tdm_api)
01518 {
01519 
01520 #ifdef WP_API_FEATURE_EVENTS
01521     wp_api_event_t *rx_event;
01522     int err;
01523 
01524     tdm_api->wp_cmd.cmd = WP_API_CMD_READ_EVENT;
01525     
01526     err=sangoma_cmd_exec(fd,tdm_api);
01527     if (err){
01528         return err;
01529     }
01530 
01531     rx_event = &tdm_api->wp_cmd.event;
01532 
01533 
01534     /*
01535      The use of callbacks here is purely optional and is left
01536      here for backward compatibility purposes.  By default user
01537      should handle events outside this funciton. This function
01538      should only be used to read the event
01539     */
01540 
01541     switch (rx_event->wp_api_event_type){
01542     
01543     case WP_API_EVENT_RBS:
01544         if (tdm_api->wp_callback.wp_rbs_event) {
01545             tdm_api->wp_callback.wp_rbs_event(fd,rx_event->wp_api_event_rbs_bits);
01546         }
01547         
01548         break;
01549     
01550 #ifdef WP_API_FEATURE_DTMF_EVENTS
01551     case WP_API_EVENT_DTMF:
01552         if (tdm_api->wp_callback.wp_dtmf_event) {
01553             tdm_api->wp_callback.wp_dtmf_event(fd,
01554                         rx_event->wp_api_event_dtmf_digit,
01555                         rx_event->wp_api_event_dtmf_type,
01556                         rx_event->wp_api_event_dtmf_port);
01557         }
01558         break;
01559 #endif
01560         
01561     case WP_API_EVENT_RXHOOK:
01562         if (tdm_api->wp_callback.wp_rxhook_event) {
01563             tdm_api->wp_callback.wp_rxhook_event(fd,
01564                         rx_event->wp_api_event_hook_state);
01565         }
01566         break;
01567 
01568     case WP_API_EVENT_RING_DETECT:
01569         if (tdm_api->wp_callback.wp_ring_detect_event) {
01570             tdm_api->wp_callback.wp_ring_detect_event(fd,
01571                         rx_event->wp_api_event_ring_state);
01572         }
01573         break;
01574 
01575     case WP_API_EVENT_RING_TRIP_DETECT:
01576         if (tdm_api->wp_callback.wp_ring_trip_detect_event) {
01577             tdm_api->wp_callback.wp_ring_trip_detect_event(fd,
01578                         rx_event->wp_api_event_ring_state);
01579         }
01580         break;
01581 
01582 #ifdef WP_API_FEATURE_FE_ALARM
01583     case WP_API_EVENT_ALARM:
01584         if (tdm_api->wp_callback.wp_fe_alarm_event) {
01585             tdm_api->wp_callback.wp_fe_alarm_event(fd,
01586                         rx_event->wp_api_event_alarm);
01587         }   
01588         break; 
01589 #endif
01590 
01591 #ifdef WP_API_FEATURE_LINK_STATUS
01592     /* Link Status */   
01593     case WP_API_EVENT_LINK_STATUS:
01594         if(tdm_api->wp_callback.wp_link_status_event){
01595             tdm_api->wp_callback.wp_link_status_event(fd,
01596                         rx_event->wp_api_event_link_status);
01597         }
01598         
01599         break;
01600 #endif
01601 
01602 #ifdef WP_API_FEATURE_POL_REV
01603     case WP_API_EVENT_POLARITY_REVERSE:
01604         break;
01605 #endif  
01606     default:
01607 #ifdef __WINDOWS__
01608         printf("libsangoma: %s fd=0x%p: Unknown TDM event!", __FUNCTION__,fd);
01609 #else
01610         printf("libsangoma: %s fd=%d: Unknown TDM event!", __FUNCTION__, fd);
01611 #endif
01612         break;
01613     }
01614     
01615     return 0;
01616 #else
01617     printf("Error: Read Event not supported!\n");
01618     return -1;
01619 #endif
01620 }        
01621 
01622 #ifdef WP_API_FEATURE_DTMF_EVENTS
01623 int _SAPI_CALL sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01624 {
01625     int err;
01626     
01627     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01628     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_DTMF;
01629     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01630     err=sangoma_cmd_exec(fd,tdm_api);
01631     if (err){
01632         return err;
01633     }
01634 
01635     return 0;
01636 }
01637 
01638 int _SAPI_CALL sangoma_tdm_disable_dtmf_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_DTMF;
01644     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01645     err=sangoma_cmd_exec(fd,tdm_api);
01646     if (err){
01647         return err;
01648     }
01649 
01650     return 0;
01651 }
01652 
01653 int _SAPI_CALL sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01654 {
01655     int err;
01656     
01657     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01658     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RM_DTMF;
01659     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01660     err=sangoma_cmd_exec(fd,tdm_api);
01661     if (err){
01662         return err;
01663     }
01664 
01665     return 0;
01666 }
01667 
01668 int _SAPI_CALL sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01669 {
01670     int err;
01671 
01672     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01673     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RM_DTMF;
01674     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01675     err=sangoma_cmd_exec(fd,tdm_api);
01676     if (err){
01677         return err;
01678     }
01679 
01680     return 0;
01681 }
01682 
01683 int _SAPI_CALL sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01684 {
01685     int err;
01686 
01687     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01688     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RXHOOK;
01689     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01690     err=sangoma_cmd_exec(fd,tdm_api);
01691     if (err){
01692         return err;
01693     }
01694 
01695     return 0;
01696 }
01697 
01698 int _SAPI_CALL sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
01699 {
01700     int err;
01701 
01702     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01703     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RXHOOK;
01704     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01705     err=sangoma_cmd_exec(fd,tdm_api);
01706     if (err){
01707         return err;
01708     }
01709 
01710     return 0;
01711 }
01712 
01713 int _SAPI_CALL sangoma_tdm_enable_ring_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01714     
01715     int err;
01716     
01717     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01718     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING;
01719     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01720     
01721     err=sangoma_cmd_exec(fd,tdm_api);
01722     if (err){
01723         return err;
01724     }
01725 
01726     return 0;
01727 }
01728 
01729 
01730 int _SAPI_CALL sangoma_tdm_disable_ring_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01731 
01732     int err;
01733     
01734     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01735     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING;
01736     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01737     
01738     err=sangoma_cmd_exec(fd,tdm_api);
01739     if (err){
01740         return err;
01741     }
01742 
01743     return 0;
01744 }
01745 
01746 int _SAPI_CALL sangoma_tdm_enable_ring_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01747     
01748     int err;
01749     
01750     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01751     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
01752     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01753     err=sangoma_cmd_exec(fd,tdm_api);
01754     if (err){
01755         return err;
01756     }
01757 
01758     return err;
01759 }
01760 
01761 
01762 int _SAPI_CALL sangoma_tdm_disable_ring_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01763 
01764     int err;
01765     
01766     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01767     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
01768     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01769     err=sangoma_cmd_exec(fd,tdm_api);
01770     if (err){
01771         return err;
01772     }
01773 
01774     return 0;
01775 }
01776 
01777 int _SAPI_CALL sangoma_tdm_enable_ring_trip_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01778     
01779     int err;
01780     
01781     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01782     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_TRIP_DETECT;
01783     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01784     err=sangoma_cmd_exec(fd,tdm_api);
01785     if (err){
01786         return err;
01787     }
01788 
01789     return tdm_api->wp_cmd.rbs_poll;
01790 }
01791 
01792 
01793 int _SAPI_CALL sangoma_tdm_disable_ring_trip_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01794 
01795     int err;
01796     
01797     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01798     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
01799     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01800     err=sangoma_cmd_exec(fd,tdm_api);
01801     if (err){
01802         return err;
01803     }
01804 
01805     return 0;
01806 }
01807 
01808 int _SAPI_CALL sangoma_tdm_txsig_kewl(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01809 
01810     int err;
01811     
01812     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01813     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_KEWL;
01814     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01815     err=sangoma_cmd_exec(fd,tdm_api);
01816     if (err){
01817         return err;
01818     }
01819 
01820     return 0;
01821 }
01822 
01823 int _SAPI_CALL sangoma_tdm_txsig_start(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01824 
01825     int err;
01826     
01827     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01828     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_START;
01829     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01830     err=sangoma_cmd_exec(fd,tdm_api);
01831     if (err){
01832         return err;
01833     }
01834 
01835     return 0;
01836 }
01837 
01838 int _SAPI_CALL sangoma_tdm_txsig_onhook(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01839 
01840     int err;
01841     
01842     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01843     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_ONHOOK;
01844     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01845     err=sangoma_cmd_exec(fd,tdm_api);
01846     if (err){
01847         return err;
01848     }
01849 
01850     return 0;
01851 }
01852 
01853 int _SAPI_CALL sangoma_tdm_txsig_offhook(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01854 
01855     int err;
01856     
01857     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01858     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_OFFHOOK;
01859     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01860     err=sangoma_cmd_exec(fd,tdm_api);
01861     if (err){
01862         return err;
01863     }
01864 
01865     return 0;
01866 }
01867 
01868 
01869 int _SAPI_CALL sangoma_tdm_enable_tone_events(sng_fd_t fd, wanpipe_api_t *tdm_api, uint16_t tone_id) {
01870     
01871     int err;
01872     
01873     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01874     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TONE;
01875     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
01876     tdm_api->wp_cmd.event.wp_api_event_tone_type = tone_id;
01877     err=sangoma_cmd_exec(fd,tdm_api);
01878     if (err){
01879         return err;
01880     }
01881 
01882     return tdm_api->wp_cmd.rbs_poll;
01883 }
01884 
01885 int _SAPI_CALL sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_api_t *tdm_api) {
01886     
01887     int err;
01888     
01889     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01890     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TONE;
01891     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01892     tdm_api->wp_cmd.event.wp_api_event_tone_type = 0x00;
01893     err=sangoma_cmd_exec(fd,tdm_api);
01894     if (err){
01895         return err;
01896     }
01897 
01898     return tdm_api->wp_cmd.rbs_poll;
01899 }
01900 
01901 #endif
01902 
01903 int _SAPI_CALL sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01904 {
01905         int err;
01906 
01907         tdm_api->wp_cmd.cmd = WP_API_CMD_ENABLE_HWEC;
01908         err=sangoma_cmd_exec(fd,tdm_api);
01909         if (err){
01910                 return err;
01911         }
01912 
01913         return 0;
01914 }
01915 
01916 int _SAPI_CALL sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_api_t *tdm_api)
01917 {
01918         int err;
01919 
01920         tdm_api->wp_cmd.cmd = WP_API_CMD_DISABLE_HWEC;
01921         err=sangoma_cmd_exec(fd,tdm_api);
01922         if (err){
01923                 return err;
01924         }
01925 
01926         return 0;
01927 }
01928 
01929 
01930 /*========================================================
01931  * GET Front End Alarms
01932  * 
01933  */                  
01934 #ifdef WP_API_FEATURE_FE_ALARM
01935 int _SAPI_CALL sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned int *alarms)
01936 {
01937     int err;
01938 
01939     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_ALARMS;
01940 
01941     err=sangoma_cmd_exec(fd,tdm_api);
01942     if (err){
01943         return err;
01944     }
01945 
01946     *alarms=tdm_api->wp_cmd.fe_alarms;
01947 
01948     return 0;
01949 }         
01950 
01951 /* get current Line Connection state - Connected/Disconnected */
01952 int _SAPI_CALL sangoma_get_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
01953 {
01954     int err;
01955 
01956     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_STATUS;
01957     err = sangoma_cmd_exec(fd, tdm_api);
01958     *current_status = tdm_api->wp_cmd.fe_status;
01959 
01960     return err;
01961 }
01962 #endif
01963 
01964 /* get current Line Connection state - Connected/Disconnected */
01965 #ifdef WP_API_FEATURE_LINK_STATUS
01966 int _SAPI_CALL sangoma_get_link_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
01967 {
01968     int err;
01969 
01970     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_STATUS;
01971     err = sangoma_cmd_exec(fd, tdm_api);
01972     *current_status = tdm_api->wp_cmd.fe_status;
01973 
01974     return err;
01975 }
01976 
01977 /* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */
01978 int _SAPI_CALL sangoma_set_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char new_status)
01979 {
01980     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_FE_STATUS;
01981     tdm_api->wp_cmd.fe_status = new_status;
01982 
01983     return sangoma_cmd_exec(fd, tdm_api);
01984 }
01985 #endif
01986 
01987 int _SAPI_CALL sangoma_disable_bri_bchan_loopback(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel)
01988 {
01989     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01990     tdm_api->wp_cmd.event.channel   = (unsigned char)channel;
01991     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_BRI_CHAN_LOOPBACK;
01992     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
01993     return sangoma_cmd_exec(fd, tdm_api);
01994 }
01995 
01996 int _SAPI_CALL sangoma_enable_bri_bchan_loopback(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel)
01997 {
01998     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
01999     tdm_api->wp_cmd.event.channel   = (unsigned char)channel;
02000     tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_BRI_CHAN_LOOPBACK;
02001     tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
02002     return sangoma_cmd_exec(fd, tdm_api);
02003 }
02004 
02005 
02006 int _SAPI_CALL sangoma_get_tx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api)
02007 {
02008     int err;
02009 
02010     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_TX_Q_SIZE;
02011     tdm_api->wp_cmd.tx_queue_sz = 0;
02012     
02013     err=sangoma_cmd_exec(fd, tdm_api);
02014     if (err < 0) {
02015         return err;
02016     }
02017 
02018     return tdm_api->wp_cmd.tx_queue_sz;
02019 }
02020 
02021 int _SAPI_CALL sangoma_set_tx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api, int size)
02022 {
02023     if (size < 0) {
02024         return -1;
02025     }
02026 
02027     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_TX_Q_SIZE;
02028     tdm_api->wp_cmd.tx_queue_sz = size;
02029     
02030     return sangoma_cmd_exec(fd, tdm_api);
02031 }
02032 
02033 int _SAPI_CALL sangoma_get_rx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api)
02034 {
02035     int err;
02036 
02037     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_RX_Q_SIZE;
02038     tdm_api->wp_cmd.rx_queue_sz = 0;
02039     
02040     err=sangoma_cmd_exec(fd, tdm_api);
02041     if (err < 0) {
02042         return err;
02043     }
02044 
02045     return tdm_api->wp_cmd.rx_queue_sz;
02046 
02047 }
02048 
02049 int _SAPI_CALL sangoma_set_rx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api, int size)
02050 {
02051     if (size < 0) {
02052         return -1;
02053     }
02054 
02055     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_RX_Q_SIZE;
02056     tdm_api->wp_cmd.rx_queue_sz = size;
02057     
02058     return sangoma_cmd_exec(fd, tdm_api);
02059 
02060 }
02061 
02062 int _SAPI_CALL sangoma_get_driver_version(sng_fd_t fd, wanpipe_api_t *tdm_api, wan_driver_version_t *drv_ver)
02063 {
02064     int err;
02065 
02066     tdm_api->wp_cmd.cmd = WP_API_CMD_DRIVER_VERSION;
02067 
02068     err = sangoma_cmd_exec(fd, tdm_api);
02069     if (err == 0) {
02070         if (tdm_api->wp_cmd.data_len == sizeof(wan_driver_version_t)) {
02071             if (drv_ver) {
02072                 memcpy(drv_ver,&tdm_api->wp_cmd.version,sizeof(wan_driver_version_t));
02073             }
02074         } else {
02075             return -1;
02076         }
02077     }
02078 
02079     return err;
02080 }
02081 
02082 int _SAPI_CALL sangoma_get_firmware_version(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *ver)
02083 {
02084     int err;
02085 
02086     tdm_api->wp_cmd.cmd = WP_API_CMD_FIRMWARE_VERSION;
02087 
02088     err = sangoma_cmd_exec(fd, tdm_api);
02089     if (err == 0) {
02090         if (tdm_api->wp_cmd.data_len == sizeof(unsigned char)) {
02091             *ver = tdm_api->wp_cmd.data[0];
02092         } else {
02093             return -1;
02094         }
02095     }
02096 
02097     return err;
02098 }
02099 
02100 
02101 int _SAPI_CALL sangoma_get_cpld_version(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *ver)
02102 {
02103     int err;
02104 
02105     tdm_api->wp_cmd.cmd = WP_API_CMD_CPLD_VERSION;
02106 
02107     err = sangoma_cmd_exec(fd, tdm_api);
02108     if (err == 0) {
02109         if (tdm_api->wp_cmd.data_len == sizeof(unsigned char)) {
02110             *ver = tdm_api->wp_cmd.data[0];
02111         } else {
02112             return -1;
02113         }
02114     }
02115 
02116     return err;
02117 }
02118 
02119 int _SAPI_CALL sangoma_get_stats(sng_fd_t fd, wanpipe_api_t *tdm_api, wanpipe_chan_stats_t *stats)
02120 {
02121     int err;
02122 
02123     tdm_api->wp_cmd.cmd = WP_API_CMD_GET_STATS;
02124 
02125     err = sangoma_cmd_exec(fd, tdm_api);
02126     if (err == 0) {
02127         if (stats) {
02128             memcpy(stats,&tdm_api->wp_cmd.stats,sizeof(wanpipe_chan_stats_t));
02129         }
02130     }
02131 
02132     return err;
02133 }
02134 
02135 int _SAPI_CALL sangoma_flush_stats(sng_fd_t fd, wanpipe_api_t *tdm_api)
02136 {
02137     tdm_api->wp_cmd.cmd = WP_API_CMD_RESET_STATS;
02138     return sangoma_cmd_exec(fd, tdm_api);
02139 }
02140 
02141 int _SAPI_CALL sangoma_set_rm_rxflashtime(sng_fd_t fd, wanpipe_api_t *tdm_api, int rxflashtime)
02142 {
02143     int err;
02144 
02145     tdm_api->wp_cmd.cmd = WP_API_CMD_SET_RM_RXFLASHTIME;
02146     tdm_api->wp_cmd.rxflashtime=rxflashtime;
02147     err = sangoma_cmd_exec(fd, tdm_api);
02148     return err;
02149 }
02150 
02151 
02152 #ifndef LIBSANGOMA_LIGHT 
02153 
02154 
02155 /************************************************************/
02159 static int sangoma_port_mgmnt_ioctl(sng_fd_t fd, port_management_struct_t *port_management)
02160 {
02161 
02162 #if defined(__WINDOWS__)
02163     DWORD ln;
02164     if(DeviceIoControl(
02165             fd,
02166             IoctlPortManagementCommand,
02167             (LPVOID)port_management,
02168             sizeof(port_management_struct_t),
02169             (LPVOID)port_management,
02170             sizeof(port_management_struct_t),
02171             (LPDWORD)(&ln),
02172             (LPOVERLAPPED)NULL
02173                         ) == FALSE){
02174         //check messages log
02175         printf("%s():Error: IoctlPortManagementCommand failed!!\n", __FUNCTION__);
02176         return -1;
02177     }else {
02178         return 0;
02179     }
02180 #else
02181     int err;
02182     err=ioctl(fd,WANPIPE_IOCTL_PORT_MGMT,port_management);
02183     if (err) {
02184         return -1;
02185     } else {
02186         return 0;
02187     }
02188 #endif
02189 }
02190 
02191 static int sangoma_port_cfg_ioctl(sng_fd_t fd, port_cfg_t *port_cfg)
02192 {
02193 
02194 #if defined(__WINDOWS__)
02195     DWORD ln;
02196     if(DeviceIoControl(
02197             fd,
02198             IoctlPortConfigurationCommand,
02199             (LPVOID)port_cfg,
02200             sizeof(port_cfg_t),
02201             (LPVOID)port_cfg,
02202             sizeof(port_cfg_t),
02203             (LPDWORD)(&ln),
02204             (LPOVERLAPPED)NULL
02205                         ) == FALSE){
02206         //check messages log
02207         printf("%s():Error: IoctlSetDriverConfiguration failed!!\n", __FUNCTION__);
02208         return 1;
02209     }else{
02210         return 0;
02211     }
02212 #else
02213     int err;
02214     err=ioctl(fd,WANPIPE_IOCTL_PORT_CONFIG,port_cfg);
02215     if (err) {
02216         return -1;
02217     } else {
02218         return 0;
02219     }
02220 #endif
02221 }
02222 
02223 /* open wanpipe configuration device */
02224 sng_fd_t _SAPI_CALL sangoma_open_driver_ctrl(int port_no)
02225 {
02226     char fname[FNAME_LEN], tmp_fname[FNAME_LEN];
02227 
02228 #if defined(__WINDOWS__)
02229     /* Form the Config Device Name (i.e. wanpipe1, wanpipe2,...). */
02230     _snprintf(tmp_fname, DEV_NAME_LEN, WP_PORT_NAME_FORM, port_no);
02231     _snprintf(fname, FNAME_LEN, "\\\\.\\%s", tmp_fname);
02232 
02233     return CreateFile(  fname, 
02234                         GENERIC_READ | GENERIC_WRITE, 
02235                         FILE_SHARE_READ | FILE_SHARE_WRITE,
02236                         (LPSECURITY_ATTRIBUTES)NULL, 
02237                         OPEN_EXISTING,
02238                         FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
02239                         (HANDLE)NULL
02240                         );
02241 #else
02242     /* Form the Config Device Name. ("/dev/wanpipe") */
02243     _snprintf(tmp_fname, DEV_NAME_LEN, WP_CONFIG_DEV_NAME);
02244 
02245     sprintf(fname,"/dev/%s", tmp_fname);
02246 
02247     return open(fname, O_RDWR);
02248 #endif
02249 }
02250 
02251 
02252 int _SAPI_CALL sangoma_mgmt_cmd(sng_fd_t fd, wan_udp_hdr_t* wan_udp)
02253 {
02254 #if defined(__WINDOWS__)
02255     if(DoManagementCommand(fd, wan_udp)){
02256         return 1;
02257     }
02258 #else
02259     unsigned char id = 0;
02260     int err=0;
02261     wan_udp->wan_udphdr_request_reply = 0x01;
02262     wan_udp->wan_udphdr_id = id;
02263     wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
02264 
02265     err=ioctl(fd,WANPIPE_IOCTL_PIPEMON,wan_udp);
02266     if (err < 0) {
02267         return 1;
02268     }
02269 #endif
02270 
02271     if(wan_udp->wan_udphdr_return_code != WAN_CMD_OK){
02272         return 2;
02273     }
02274     return 0;
02275 }
02276 
02277 int _SAPI_CALL sangoma_driver_port_start(sng_fd_t fd, port_management_struct_t *port_mgmnt, unsigned short port_no)
02278 {
02279     int err;
02280     port_mgmnt->command_code = START_PORT_VOLATILE_CONFIG;
02281     port_mgmnt->port_no = port_no;
02282 
02283     err = sangoma_port_mgmnt_ioctl(fd, port_mgmnt);
02284     if (err) {
02285         return err;
02286     }
02287 
02288     if (port_mgmnt->operation_status != SANG_STATUS_SUCCESS ) {
02289         err=port_mgmnt->operation_status;
02290     }
02291 
02292     return err;
02293 }
02294 
02295 int _SAPI_CALL sangoma_driver_port_stop(sng_fd_t fd, port_management_struct_t *port_mgmnt, unsigned short port_no)
02296 {
02297     int err;
02298     port_mgmnt->command_code = STOP_PORT;
02299     port_mgmnt->port_no = port_no;
02300 
02301     err = sangoma_port_mgmnt_ioctl(fd, port_mgmnt);
02302     if (err) {
02303         return err;
02304     }
02305 
02306     if (port_mgmnt->operation_status != SANG_STATUS_SUCCESS){
02307 
02308         if(port_mgmnt->operation_status == SANG_STATUS_CAN_NOT_STOP_DEVICE_WHEN_ALREADY_STOPPED) {
02309             err = 0;
02310         }else{
02311             err = port_mgmnt->operation_status;
02312         }
02313     }
02314 
02315     return err;
02316 }
02317 
02318 int _SAPI_CALL sangoma_driver_get_hw_info(sng_fd_t fd, port_management_struct_t *port_mgmnt, unsigned short port_no)
02319 {
02320         int err;
02321         port_mgmnt->command_code = GET_HARDWARE_INFO;
02322         port_mgmnt->port_no     = port_no;
02323 
02324         err = sangoma_port_mgmnt_ioctl(fd, port_mgmnt);
02325         if (err) {
02326                 port_mgmnt->operation_status = SANG_STATUS_INVALID_DEVICE;
02327                 return err;
02328         }
02329 
02330         if (port_mgmnt->operation_status != SANG_STATUS_SUCCESS ) {
02331                 err=port_mgmnt->operation_status;
02332         }
02333 
02334         return err;
02335 }
02336 
02337 int _SAPI_CALL sangoma_driver_port_set_config(sng_fd_t fd, port_cfg_t *port_cfg, unsigned short port_no)
02338 {
02339     port_cfg->command_code = SET_PORT_VOLATILE_CONFIG;
02340     port_cfg->port_no   = port_no;
02341 
02342     return sangoma_port_cfg_ioctl(fd, port_cfg);
02343 }
02344 
02345 int _SAPI_CALL sangoma_driver_port_get_config(sng_fd_t fd, port_cfg_t *port_cfg, unsigned short port_no)
02346 {
02347 
02348     port_cfg->command_code = GET_PORT_VOLATILE_CONFIG;
02349     port_cfg->port_no   = port_no;
02350 
02351     return sangoma_port_cfg_ioctl(fd, port_cfg);
02352 }
02353 
02354 #endif
02355 
02356 
02357 #endif /* WANPIPE_TDM_API */

Generated on Fri Jun 26 12:46:14 2009 for libsangoma by  doxygen 1.4.7