libsangoma  1
libsangoma.c
Go to the documentation of this file.
1 /*******************************************************************************/
35 #include "libsangoma-pvt.h"
36 
37 #if defined(__WINDOWS__)
38 # include <setupapi.h> /* SetupDiXXX() functions */
39 # include <initguid.h> /* GUID instantination */
40 # include <devguid.h> /* DEFINE_GUID() */
41 # include "public.h" /* GUID_DEVCLASS_SANGOMA_ADAPTER */
42 
43 # define MAX_COMP_INSTID 2096
44 # define MAX_COMP_DESC 2096
45 # define MAX_FRIENDLY 2096
46 # define TMP_BUFFER_LEN 256
47 
49 # define INVALID_INDEX (uint32_t) -1
50 # define WP_ALL_BITS_SET ((uint32_t)-1)
51 #endif
52 
53 int libsng_dbg_level = 0;
54 
55 /*********************************************************************/
59 #if defined(__WINDOWS__)
60 #define DBG_REGISTRY if(libsng_dbg_level)libsng_dbg
61 
62 /*
63  \fn static void DecodeLastError(LPSTR lpszFunction)
64  \brief Decodes the Error in radable format.
65  \param lpszFunction error string
66 
67  Private Windows Only Function
68  */
69 static void LibSangomaDecodeLastError(LPSTR lpszFunction)
70 {
71  LPVOID lpMsgBuf;
72  DWORD dwLastErr = GetLastError();
73  FormatMessage(
74  FORMAT_MESSAGE_ALLOCATE_BUFFER |
75  FORMAT_MESSAGE_FROM_SYSTEM |
76  FORMAT_MESSAGE_IGNORE_INSERTS,
77  NULL,
78  dwLastErr,
79  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
80  (LPTSTR) &lpMsgBuf,
81  0,
82  NULL
83  );
84  /* Display the string. */
85  DBG_POLL("Last Error in %s(): %s (%d)\n", lpszFunction, (char*)lpMsgBuf, dwLastErr);
86  /* Free the buffer. */
87  LocalFree( lpMsgBuf );
88 }
89 
90 /*
91  \fn static int handle_device_ioctl_result(int bResult)
92  \brief Checks result code of ioctl
93  \param bResult result of ioctl call
94 
95  Private Windows Only Function
96  */
97 static u16 handle_device_ioctl_result(int bResult, char *caller_name)
98 {
99  if(bResult == 0){
100  /*error*/
101  LibSangomaDecodeLastError(caller_name);
102  return SANG_STATUS_IO_ERROR;
103  }else{
104  return SANG_STATUS_SUCCESS;
105  }
106 }
107 
108 /*
109  \fn static int UdpManagementCommand(sng_fd_t fd, wan_udp_hdr_t* wan_udp)
110  \brief Executes Driver Management Command
111  \param fd device file descriptor
112  \param wan_udp managemet cmd structure
113 
114  Private Windows Function
115  */
116 int UdpManagementCommand(sng_fd_t fd, wan_udp_hdr_t* wan_udp)
117 {
118  DWORD ln, bIoResult;
119  unsigned char id = 0;
120 
121  wan_udp->wan_udphdr_request_reply = 0x01;
122  wan_udp->wan_udphdr_id = id;
123  wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
124 
125  bIoResult = DeviceIoControl(
126  fd,
127  IoctlManagementCommand,
128  (LPVOID)wan_udp,
129  sizeof(wan_udp_hdr_t),
130  (LPVOID)wan_udp,
131  sizeof(wan_udp_hdr_t),
132  (LPDWORD)(&ln),
133  (LPOVERLAPPED)NULL
134  );
135 
136  return handle_device_ioctl_result(bIoResult, __FUNCTION__);
137 }
138 
139 /*
140  \fn static int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_cmd_t *api_cmd)
141  \brief Executes Driver TDM API Command Wrapper Function
142  \param fd device file descriptor
143  \param api_cmd tdm_api managemet cmd structure
144 
145  Private Windows Function
146  */
147 static int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_cmd_t *api_cmd)
148 {
149  DWORD ln, bIoResult;
150 
151  bIoResult = DeviceIoControl(
152  fd,
153  IoctlTdmApiCommand,
154  (LPVOID)api_cmd,
155  sizeof(wanpipe_tdm_api_cmd_t),
156  (LPVOID)api_cmd,
157  sizeof(wanpipe_tdm_api_cmd_t),
158  (LPDWORD)(&ln),
159  (LPOVERLAPPED)NULL
160  );
161 
162  return handle_device_ioctl_result(bIoResult, __FUNCTION__);
163 }
164 
174 static USHORT DoReadCommand(sng_fd_t fd, wan_iovec_list_t *p_iovec_list)
175 {
176  DWORD ln, bIoResult;
177 
178  bIoResult = DeviceIoControl(
179  fd,
180  IoctlReadCommandNonBlocking,
181  (LPVOID)NULL, /*NO input buffer!*/
182  0,
183  (LPVOID)p_iovec_list,
184  sizeof(wan_iovec_list_t),
185  (LPDWORD)(&ln),
186  (LPOVERLAPPED)NULL);
187 
188  return handle_device_ioctl_result(bIoResult, __FUNCTION__);
189 }
190 
200 static UCHAR DoWriteCommand(sng_fd_t fd, wan_iovec_list_t *p_iovec_list)
201 {
202  DWORD BytesReturned, bIoResult;
203 
204  bIoResult = DeviceIoControl(
205  fd,
206  IoctlWriteCommandNonBlocking,
207  (LPVOID)p_iovec_list, //input buffer
208  sizeof(*p_iovec_list), //size of input buffer
209  (LPVOID)p_iovec_list, //output buffer
210  sizeof(*p_iovec_list), //size of output buffer
211  (LPDWORD)(&BytesReturned),
212  (LPOVERLAPPED)NULL);
213 
214  return (UCHAR)handle_device_ioctl_result(bIoResult, __FUNCTION__);
215 }
216 
217 /*
218  \fn static USHORT sangoma_poll_fd(sng_fd_t fd, API_POLL_STRUCT *api_poll_ptr)
219  \brief Non Blocking API Poll function used to find out if Rx Data, Events or
220  Free Tx buffer available
221  \param drv device file descriptor
222  \param api_poll_ptr poll device that stores polling information read/write/event
223  \param overlapped pointer to system overlapped io structure.
224 
225  Private Windows Function
226  */
227 static USHORT sangoma_poll_fd(sng_fd_t fd, API_POLL_STRUCT *api_poll_ptr)
228 {
229  DWORD ln, bIoResult;
230 
231  bIoResult = DeviceIoControl(
232  fd,
233  IoctlApiPoll,
234  (LPVOID)NULL,
235  0L,
236  (LPVOID)api_poll_ptr,
237  sizeof(API_POLL_STRUCT),
238  (LPDWORD)(&ln),
239  (LPOVERLAPPED)NULL);
240 
241  return handle_device_ioctl_result(bIoResult, __FUNCTION__);
242 }
243 
244 /*
245  \fn static int logger_api_ioctl(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
246  \brief Executes Logger API IOCTL
247  \param fd device file descriptor
248  \param logger_cmd Logger API command structure
249 
250  Private Windows Function
251  */
252 static sangoma_status_t logger_api_ioctl(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
253 {
254  DWORD ln, bIoResult;
255 
256  bIoResult = DeviceIoControl(
257  fd,
258  IoctlLoggerApiCommand,
259  (LPVOID)logger_cmd,
260  sizeof(wp_logger_cmd_t),
261  (LPVOID)logger_cmd,
262  sizeof(wp_logger_cmd_t),
263  (LPDWORD)(&ln),
264  (LPOVERLAPPED)NULL );
265 
266  return handle_device_ioctl_result(bIoResult, __FUNCTION__);
267 }
268 
269 /* This function is exported only for debugging purposes and NOT a part of API. */
270 sangoma_status_t _LIBSNG_CALL sangoma_cdev_ctrl_cmd(sng_fd_t fd, wanpipe_tdm_api_cmd_t *api_cmd)
271 {
272  DWORD ln, bIoResult;
273 
274  bIoResult = DeviceIoControl(
275  fd,
276  IoctlCdevControlCommand,
277  (LPVOID)api_cmd,
278  sizeof(wanpipe_tdm_api_cmd_t),
279  (LPVOID)api_cmd,
280  sizeof(wanpipe_tdm_api_cmd_t),
281  (LPDWORD)(&ln),
282  (LPOVERLAPPED)NULL
283  );
284 
285  return handle_device_ioctl_result(bIoResult, __FUNCTION__);
286 }
287 
288 static sangoma_status_t init_sangoma_event_object(sangoma_wait_obj_t *sng_wait_obj, sng_fd_t fd)
289 {
290  wanpipe_tdm_api_cmd_t tdm_api_cmd;
291  sangoma_status_t sng_status;
292  char event_name[200];
293 
294  memset(&tdm_api_cmd, 0x00, sizeof(tdm_api_cmd));
295 
296  tdm_api_cmd.cmd = WP_CDEV_CMD_GET_INTERFACE_NAME;
297  sng_status = sangoma_cdev_ctrl_cmd(fd, &tdm_api_cmd);
298  if(SANG_ERROR(sng_status)){
299  DBG_ERR("sangoma_cdev_ctrl_cmd() failed!\n");
300  return sng_status;
301  }
302 
303  DBG_EVNT("%s(): interface name: %s\n", __FUNCTION__, tdm_api_cmd.data);
304 
305  /* 1. The Sangoma Device Driver creates Notification Events in "\\BaseNamedObjects\\Global\\"
306  * when first CreateFile() was called by a process. That means the Events will inherit
307  * the security attributes of the calling process, so the calling process will have
308  * the permissions to open the Events by calling OpenEvent(). Since Events are created
309  * "Global" subdirectory, the calling process does NOT need Administrator priveleges.
310  * The example name of the signaling object is: \\BaseNamedObjects\\Global\\wanpipe1_if1_signal.
311  * 2. The Events are deleted when the last HANDLE for a device is closed by CloseHandle()
312  * or automatically by the system when calling process exits. */
313  _snprintf(event_name, sizeof(event_name), "Global\\%s_signal", tdm_api_cmd.data);
314 
315  sng_wait_obj->signal_object = OpenEvent(EVENT_ALL_ACCESS, TRUE, event_name);
316  if(NULL == sng_wait_obj->signal_object){
317  /* error */
318  LibSangomaDecodeLastError(__FUNCTION__);
320  }
321 
322  return SANG_STATUS_SUCCESS;
323 }
324 
325 static sangoma_status_t sangoma_wait_obj_poll(sangoma_wait_obj_t *sangoma_wait_object, int flags_in, uint32_t *flags_out)
326 {
327  int err;
328  sangoma_wait_obj_t *sng_wait_obj = sangoma_wait_object;
330  API_POLL_STRUCT api_poll;
331 
332  *flags_out = 0;
333 
334  memset(&api_poll, 0x00, sizeof(api_poll));
335  api_poll.user_flags_bitmap = flags_in;
336 
337  /* This call is non-blocking - it will return immediatly. */
338  if(sangoma_poll_fd(sng_wait_obj->fd, &api_poll)){
339  /* error - ioctl failed */
340  return SANG_STATUS_IO_ERROR;
341  }
342 
343  if(api_poll.operation_status == SANG_STATUS_SUCCESS){
344  *flags_out = api_poll.poll_events_bitmap;
345  err = 0;
346  }else{
347  /* error - command failed */
348  err = api_poll.operation_status;
349  }
350 
351  if(*flags_out == 0){
352  /*DBG_POLL("======%s(): *flags_out: 0x%X, flags_in: 0x%X\n", __FUNCTION__, *flags_out, flags_in);*/
353  }
354  return err;
355 }
356 
357 static int sangoma_check_number_of_wait_objects(uint32_t number_of_objects)
358 {
359  if(number_of_objects > MAXIMUM_WAIT_OBJECTS){
360  DBG_ERR("'number_of_objects': %d is greater than the Maximum of: %d\n",
361  number_of_objects, MAXIMUM_WAIT_OBJECTS);
362  return 1;
363  }
364 
365  if(number_of_objects < 1){
366  DBG_ERR("'number_of_objects': %d is less than the Minimum of: 1\n",
367  number_of_objects);
368  return 1;
369  }
370 
371  return 0;
372 }
373 
374 static sangoma_status_t get_out_flags(IN sangoma_wait_obj_t *sng_wait_objects[],
375  IN uint32_t first_signaled_obj_index,
376  IN uint32_t in_flags[], OUT uint32_t out_flags[],
377  IN uint32_t number_of_sangoma_wait_objects,
378  OUT BOOL *at_least_one_poll_set_flags_out)
379 {
380  uint32_t i;
381 
382  if(at_least_one_poll_set_flags_out){
383  *at_least_one_poll_set_flags_out = FALSE;
384  }
385 
386  for(i = 0; i < number_of_sangoma_wait_objects; i++) {
387 
388  sangoma_wait_obj_t *sangoma_wait_object = sng_wait_objects[i];
389 
390  if (!sangoma_wait_object->signal_object) {
392  }
393 
394  if (!SANGOMA_OBJ_HAS_DEVICE(sangoma_wait_object)) {
395 
396  /* This object does not has a device, but, may have been signaled via sangoma_wait_obj_signal()
397  * test if the object is signaled, if it is, set SANG_WAIT_OBJ_IS_SIGNALED */
398 
399  if((i == first_signaled_obj_index) || /* !+! jpboily : Since WaitForMultipleObjects cleared the status
400  * of the FIRST signaled object, we make sure that the out_flag
401  * for this object is set.
402  * !+! davidr: Status of all OTHER objects will be checked
403  * by WaitForSingleObject(). */
404  (WaitForSingleObject(sangoma_wait_object->signal_object, 0) == WAIT_OBJECT_0)) {
405  out_flags[i] |= SANG_WAIT_OBJ_IS_SIGNALED;
406  }
407  continue;
408  }
409 
410  if(sangoma_wait_obj_poll(sangoma_wait_object, in_flags[i], &out_flags[i])){
412  }
413 
414  if (out_flags[i] & in_flags[i]) {
415  if (at_least_one_poll_set_flags_out) {
416  *at_least_one_poll_set_flags_out = TRUE;
417  }
418  }
419 
420  }/* for(i = 0; i < number_of_sangoma_wait_objects; i++) */
421 
422  return SANG_STATUS_SUCCESS;
423 }
424 
428 static LONG registry_get_string_value(HKEY hkey, LPTSTR szKeyname, OUT LPSTR szValue, OUT DWORD *pdwSize)
429 {
430  LONG iReturnCode;
431 
432  /* reading twice to set pdwSize to needed value */
433  RegQueryValueEx(hkey, szKeyname, NULL, NULL, (unsigned char *)szValue, pdwSize);
434 
435  iReturnCode = RegQueryValueEx(hkey, szKeyname, NULL, NULL, (unsigned char *)szValue, pdwSize);
436  if(ERROR_SUCCESS == iReturnCode){
437  iReturnCode = 0;
438  }
439  DBG_REGISTRY("%s(): %s: %s: iReturnCode: %d\n", __FUNCTION__, szKeyname, szValue, iReturnCode);
440  return iReturnCode;
441 }
442 
446 LONG registry_set_string_value(HKEY hkey, LPTSTR szKeyname, IN LPSTR szValue)
447 {
448  DWORD dwSize;
449  LONG iReturnCode;
450 
451  dwSize = (DWORD)strlen(szValue) + 1;
452 
453  iReturnCode = RegSetValueEx(hkey, szKeyname, 0, REG_SZ, (unsigned char *)szValue, dwSize);
454  DBG_REGISTRY("%s(): %s: %s\n", __FUNCTION__, szKeyname, szValue);
455 
456  if(ERROR_SUCCESS == iReturnCode){
457  iReturnCode = 0;
458  }
459  return iReturnCode;
460 }
461 
465 LONG registry_set_integer_value(HKEY hkey, LPTSTR szKeyname, IN int iValue)
466 {
467  DWORD dwSize;
468  char szTemp[TMP_BUFFER_LEN];
469  LONG iReturnCode;
470 
471  sprintf(szTemp, "%u", iValue);
472 
473  dwSize = (DWORD)strlen(szTemp) + 1;
474  iReturnCode = RegSetValueEx(hkey, szKeyname, 0, REG_SZ, (unsigned char *)szTemp, dwSize);
475 
476  if(ERROR_SUCCESS == iReturnCode){
477  iReturnCode = 0;
478  }
479 
480  DBG_REGISTRY("%s(): %s: %d: iReturnCode: %d\n", __FUNCTION__, szKeyname, iValue, iReturnCode);
481  return iReturnCode;
482 }
483 
488 HKEY registry_open_port_key(hardware_info_t *hardware_info)
489 {
490  int i, iRegistryReturnCode;
491  SP_DEVINFO_DATA deid={sizeof(SP_DEVINFO_DATA)};
492  HDEVINFO hdi = SetupDiGetClassDevs((struct _GUID *)&GUID_DEVCLASS_SANGOMA_ADAPTER, NULL,NULL, DIGCF_PRESENT);
493  char DeviceName[TMP_BUFFER_LEN], PCI_Bus[TMP_BUFFER_LEN], PCI_Slot[TMP_BUFFER_LEN], Port_Number[TMP_BUFFER_LEN];
494  DWORD dwTemp;
495  HKEY hKeyTmp = (struct HKEY__ *)INVALID_HANDLE_VALUE;
496  HKEY hPortRegistryKey = (struct HKEY__ *)INVALID_HANDLE_VALUE;
497 
498  char szCompInstanceId[MAX_COMP_INSTID];
499  TCHAR szCompDescription[MAX_COMP_DESC];
500  DWORD dwRegType;
501  /* Possible Sangoma Port Names (refer to sdladrv.inf):
502  Sangoma Hardware Abstraction Driver (Port 1)
503  Sangoma Hardware Abstraction Driver (Port 2)
504  Sangoma Hardware Abstraction Driver (Port 3)
505  Sangoma Hardware Abstraction Driver (Port 4)
506  Sangoma Hardware Abstraction Driver (Port 5)
507  Sangoma Hardware Abstraction Driver (Port 6)
508  Sangoma Hardware Abstraction Driver (Port 7)
509  Sangoma Hardware Abstraction Driver (Port 8)
510  Sangoma Hardware Abstraction Driver (Analog)
511  Sangoma Hardware Abstraction Driver (ISDN BRI) */
512  const TCHAR *search_SubStr = "Sangoma Hardware Abstraction Driver";
513 
514  /* search for all (AFT) ports: */
515  for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &deid); i++){
516 
517  BOOL fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid, (PSTR)szCompInstanceId, MAX_COMP_INSTID, NULL);
518  if (!fSuccess){
519  continue;
520  }
521 
522  fSuccess = SetupDiGetDeviceRegistryProperty(hdi, &deid, SPDRP_DEVICEDESC, &dwRegType, (BYTE*)szCompDescription, MAX_COMP_DESC, NULL);
523  if (!fSuccess){
524  continue;
525  }
526 
527  if (!strstr(szCompDescription, search_SubStr)) { /* Windows can add #2 etc - do NOT consider */
528  /* This is a "Sangoma Card" device, we are interested only in "Sangoma Port" devices. */
529  continue;
530  }
531 
532  DBG_REGISTRY("* %s\n", szCompDescription);
533 
534  hKeyTmp = SetupDiOpenDevRegKey(hdi, &deid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_SET_VALUE );
535  if(hKeyTmp == INVALID_HANDLE_VALUE){
536  DBG_REGISTRY("Error: Failed to open Registry key!!\n");
537  continue;
538  }
539 
540  PCI_Bus[0] = '\0';
541  iRegistryReturnCode = registry_get_string_value(hKeyTmp, "PCI_Bus", PCI_Bus, &dwTemp);
542  if(iRegistryReturnCode){
543  continue;
544  }
545 
546  PCI_Slot[0] = '\0';
547  iRegistryReturnCode = registry_get_string_value(hKeyTmp, "PCI_Slot", PCI_Slot, &dwTemp);
548  if(iRegistryReturnCode){
549  continue;
550  }
551 
552  Port_Number[0] = '\0';
553  iRegistryReturnCode = registry_get_string_value(hKeyTmp, "Port_Number", Port_Number, &dwTemp);
554  if(iRegistryReturnCode){
555  continue;
556  }
557 
558  if( atoi(PCI_Bus) == hardware_info->pci_bus_number &&
559  atoi(PCI_Slot) == hardware_info->pci_slot_number &&
560  atoi(Port_Number) == hardware_info->port_number ){
561 
562  hPortRegistryKey = hKeyTmp;
563 
564  /* read device name for debugging only */
565  DeviceName[0] = '\0';
566  registry_get_string_value(hPortRegistryKey, "DeviceName", DeviceName, &dwTemp);
567 
568  DBG_REGISTRY("Found Port's Registry key: DeviceName: %s, PCI_Bus: %s, PCI_Slot: %s, Port_Number: %s\n",
569  DeviceName, PCI_Bus, PCI_Slot, Port_Number);
570  break;
571  }/* if() */
572  }/* for() */
573 
574  SetupDiDestroyDeviceInfoList(hdi);
575 
576  DBG_REGISTRY("hPortRegistryKey: 0x%X\n", hPortRegistryKey);
577 
578  return hPortRegistryKey;
579 }
580 
581 static char* timeslot_bitmap_to_string(int bitmap)
582 {
583  int i = 0, range_counter = 0;
584  int start_channel = -1, stop_channel = -1;
585  static char tmp_string[256];
586 
587  if( WP_ALL_BITS_SET == bitmap ){
588  return "ALL"; /* If all bits are set, use the "ALL" keyword. */
589  }
590 
591  tmp_string[0] = '\0';
592 
593  /* all ranges between two zeros is what we will look for */
594  for(i = 0; i < sizeof(bitmap) * 8; i++){
595 
596  if(start_channel < 0){
597  /* found a starting one of a range */
598  if(bitmap & (1 << i)){
599  start_channel = i + 1;
600  }
601  }
602 
603  if(start_channel >= 0){
604  if((bitmap & (1 << i)) == 0){
605 
606  /* we hit a zero, that means the previous channel is one */
607  stop_channel = i;
608 
609  }else if(i == (sizeof(bitmap) * 8 - 1)){
610  /* The most significant bit is set - there will be no delimiting zero.
611  * It will also take care of "all channels" which is a special
612  * case - there is a start but no stop channel because all bits
613  * are set. result will be 1-32 */
614  stop_channel = (sizeof(bitmap) * 8);
615  }
616  }
617 
618  if(start_channel >= 0 && stop_channel >= 0){
619 
620  if(range_counter){
621  /* put '.' separator from the previous range */
622  _snprintf(&tmp_string[strlen(tmp_string)], sizeof(tmp_string) - strlen(tmp_string), ".");
623  }
624 
625  if(start_channel == stop_channel){
626  /* the range contains a SINGLE channel */
627  _snprintf(&tmp_string[strlen(tmp_string)], sizeof(tmp_string) - strlen(tmp_string),
628  "%d", start_channel);
629  }else{
630  /* the range contains MULTIPLE channels */
631  _snprintf(&tmp_string[strlen(tmp_string)], sizeof(tmp_string) - strlen(tmp_string),
632  "%d-%d", start_channel, stop_channel);
633  }
634 
635  start_channel = stop_channel = -1;
636  range_counter++;
637  }
638  }/* for() */
639 
640  return tmp_string;
641 }
642 
643 int registry_write_front_end_cfg(HKEY hPortRegistryKey, port_cfg_t *port_cfg)
644 {
645  wandev_conf_t *wandev_conf = &port_cfg->wandev_conf;
646  sdla_fe_cfg_t *sdla_fe_cfg = &wandev_conf->fe_cfg;
647  sdla_te_cfg_t *te_cfg = &sdla_fe_cfg->cfg.te_cfg;
648  sdla_remora_cfg_t *analog_cfg = &sdla_fe_cfg->cfg.remora;
649  sdla_bri_cfg_t *bri_cfg = &sdla_fe_cfg->cfg.bri;
650  int iReturnCode = 0;
651 
652  /* Set Card/Port-wide values, which are independent of Media type, and
653  * stored in sdla_fe_cfg_t. */
654 
655  iReturnCode = registry_set_integer_value(hPortRegistryKey, "tdmv_law", FE_TDMV_LAW(sdla_fe_cfg) /* WAN_TDMV_MULAW/WAN_TDMV_ALAW */);
656  if(iReturnCode){
657  return iReturnCode;
658  }
659 
660  iReturnCode = registry_set_integer_value(hPortRegistryKey, "ExternalSynchronization", FE_NETWORK_SYNC(sdla_fe_cfg) /* WANOPT_NO/WANOPT_YES */);
661  if(iReturnCode){
662  return iReturnCode;
663  }
664 
665  iReturnCode = registry_set_integer_value(hPortRegistryKey, "FE_TXTRISTATE", FE_TXTRISTATE(sdla_fe_cfg) /* WANOPT_NO/WANOPT_YES */);
666  if(iReturnCode){
667  return iReturnCode;
668  }
669 
670  iReturnCode = registry_set_integer_value(hPortRegistryKey, "HWEC_CLKSRC", wandev_conf->hwec_conf.clk_src /* is this port the HWEC clock source - WANOPT_NO/WANOPT_YES */);
671  if(iReturnCode){
672  return iReturnCode;
673  }
674 
675 
676  /* set Media specific values. */
677  switch(sdla_fe_cfg->media)
678  {
679  case WAN_MEDIA_T1:
680  case WAN_MEDIA_J1: /* the same as T1 */
681  case WAN_MEDIA_E1:
682  /* only T1/E1 Port can change the Media, all other ports ignore this parameter. */
683  iReturnCode = registry_set_integer_value(hPortRegistryKey, "Media", sdla_fe_cfg->media /*WAN_MEDIA_T1*/);
684  if(iReturnCode){
685  break;
686  }
687 
688  iReturnCode = registry_set_integer_value(hPortRegistryKey, "LDecoding", sdla_fe_cfg->lcode /*WAN_LCODE_B8ZS*/);
689  if(iReturnCode){
690  break;
691  }
692 
693  iReturnCode = registry_set_integer_value(hPortRegistryKey, "Framing", sdla_fe_cfg->frame /*WAN_FR_ESF*/);
694  if(iReturnCode){
695  break;
696  }
697 
698  iReturnCode = registry_set_integer_value(hPortRegistryKey, "ClkRefPort", te_cfg->te_ref_clock);
699  if(iReturnCode){
700  break;
701  }
702 
703  iReturnCode = registry_set_integer_value(hPortRegistryKey, "TE_IGNORE_YEL", te_cfg->ignore_yel_alarm);
704  if(iReturnCode){
705  break;
706  }
707 
708  iReturnCode = registry_set_integer_value(hPortRegistryKey, "ACTIVE_CH", ENABLE_ALL_CHANNELS /*must be hardcoded*/);
709  if(iReturnCode){
710  break;
711  }
712 
713  iReturnCode = registry_set_integer_value(hPortRegistryKey, "TE_RBS_CH", te_cfg->te_rbs_ch); /*not used by DS chip code, only by PMC */
714  if(iReturnCode){
715  break;
716  }
717 
718  iReturnCode = registry_set_integer_value(hPortRegistryKey, "LBO", te_cfg->lbo /*WAN_T1_LBO_0_DB*/);
719  if(iReturnCode){
720  break;
721  }
722 
723  iReturnCode = registry_set_integer_value(hPortRegistryKey, "ClkMode", te_cfg->te_clock /*WAN_NORMAL_CLK*/);
724  if(iReturnCode){
725  break;
726  }
727 
728  iReturnCode = registry_set_integer_value(hPortRegistryKey, "HighImpedanceMode",te_cfg->high_impedance_mode /*WANOPT_NO*/);
729  if(iReturnCode){
730  break;
731  }
732 
733  iReturnCode = registry_set_integer_value(hPortRegistryKey, "TE_RX_SLEVEL", te_cfg->rx_slevel /*WAN_TE1_RX_SLEVEL_12_DB*/);
734  if(iReturnCode){
735  break;
736  }
737 
738  /* write E1 signalling for both T1 and E1 */
739  iReturnCode = registry_set_integer_value(hPortRegistryKey, "E1Signalling", te_cfg->sig_mode /*WAN_TE1_SIG_CCS*/);
740  if(iReturnCode){
741  break;
742  }
743  break;
744 
745  case WAN_MEDIA_56K:
746  /* do nothing */
747  iReturnCode = 0;
748  break;
749 
750  case WAN_MEDIA_FXOFXS:
751  /* Analog global (per-card) settings */
752  iReturnCode = registry_set_string_value(hPortRegistryKey, "remora_fxo_operation_mode_name", analog_cfg->opermode_name);
753  if(iReturnCode){
754  break;
755  }
756 
757  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_BATTTHRESH", analog_cfg->battthresh);
758  if(iReturnCode){
759  break;
760  }
761 
762  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_BATTDEBOUNCE", analog_cfg->battdebounce);
763  if(iReturnCode){
764  break;
765  }
766 
767  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_FXO_TAPPING", analog_cfg->rm_mode);
768  if(iReturnCode){
769  break;
770  }
771 
772  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_FXO_TAPPING_OFF_HOOK_THRESHOLD",analog_cfg->ohthresh);
773  if(iReturnCode){
774  break;
775  }
776 
777  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_LCM", analog_cfg->rm_lcm);
778  if(iReturnCode){
779  break;
780  }
781 
782  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_FXSTXGAIN", analog_cfg->fxs_txgain);
783  if(iReturnCode){
784  break;
785  }
786 
787  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_FXSRXGAIN", analog_cfg->fxs_rxgain);
788  if(iReturnCode){
789  break;
790  }
791 
792  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_FXOTXGAIN", analog_cfg->fxo_txgain);
793  if(iReturnCode){
794  break;
795  }
796 
797  iReturnCode = registry_set_integer_value(hPortRegistryKey, "RM_FXORXGAIN", analog_cfg->fxo_rxgain);
798  if(iReturnCode){
799  break;
800  }
801  break;
802 
803  case WAN_MEDIA_BRI:
804  iReturnCode = registry_set_integer_value(hPortRegistryKey, "aft_bri_clock_mode", bri_cfg->clock_mode);
805  if(iReturnCode){
806  break;
807  }
808  break;
809 
810  case WAN_MEDIA_SERIAL:
811  iReturnCode = registry_set_integer_value(hPortRegistryKey, "clock_source", wandev_conf->clocking);
812  if(iReturnCode){
813  break;
814  }
815 
816  iReturnCode = registry_set_integer_value(hPortRegistryKey, "BaudRate", wandev_conf->bps);
817  if(iReturnCode){
818  break;
819  }
820 
821  iReturnCode = registry_set_integer_value(hPortRegistryKey, "serial_connection_type", wandev_conf->connection);
822  if(iReturnCode){
823  break;
824  }
825 
826  iReturnCode = registry_set_integer_value(hPortRegistryKey, "serial_line_coding", wandev_conf->line_coding);
827  if(iReturnCode){
828  break;
829  }
830 
831  iReturnCode = registry_set_integer_value(hPortRegistryKey, "serial_line_idle", wandev_conf->line_idle);
832  if(iReturnCode){
833  break;
834  }
835  break;
836 
837  default:
838  DBG_ERR("Invalid Media Type %d!\n", sdla_fe_cfg->media);
839  iReturnCode = 1;
840  }
841 
842  return iReturnCode;
843 }
844 
845 int registry_write_wan_tdmv_conf(HKEY hPortRegistryKey, port_cfg_t *port_cfg)
846 {
847  wandev_conf_t *wandev_conf = &port_cfg->wandev_conf;
848  sdla_fe_cfg_t *sdla_fe_cfg = &wandev_conf->fe_cfg;
849  wan_tdmv_conf_t *tdmv_conf = &wandev_conf->tdmv_conf;
850  int iReturnCode = 1;
851 
852  /* set Media specific values. */
853  switch(sdla_fe_cfg->media)
854  {
855  case WAN_MEDIA_T1:
856  case WAN_MEDIA_J1: /* the same as T1 */
857  case WAN_MEDIA_E1:
858  /* write dchannel bitmap as a string (the same way as active channels) */
859  iReturnCode = registry_set_string_value(hPortRegistryKey, "TDMV_DCHAN", timeslot_bitmap_to_string(tdmv_conf->dchan));
860  break;
861 
862  case WAN_MEDIA_56K:
863  case WAN_MEDIA_FXOFXS:
864  case WAN_MEDIA_BRI:
865  case WAN_MEDIA_SERIAL:
866  /* do nothing */
867  iReturnCode = 0;
868  break;
869 
870  default:
871  DBG_ERR("Invalid Media Type %d!\n", sdla_fe_cfg->media);
872  iReturnCode = 2;
873  break;
874  }
875 
876  return iReturnCode;
877 }
878 
879 int registry_write_channel_group_cfg(HKEY hPortRegistryKey, port_cfg_t *port_cfg, int interface_index, wanif_conf_t wanif_conf)
880 {
881  char szTemp[TMP_BUFFER_LEN];
882  int iReturnCode = 0;
883 
884  do{
885  // Line mode
886  _snprintf(szTemp, TMP_BUFFER_LEN, "aft_logic_channel_%d_line_mode", interface_index);
887  iReturnCode = registry_set_string_value(hPortRegistryKey, szTemp,
888  (wanif_conf.hdlc_streaming == WANOPT_YES ? MODE_OPTION_HDLC : MODE_OPTION_BITSTRM));
889  if(iReturnCode){
890  break;
891  }
892 
893  // MTU
894  _snprintf(szTemp, TMP_BUFFER_LEN, "aft_logic_channel_%d_mtu", interface_index);
895  iReturnCode = registry_set_integer_value(hPortRegistryKey, szTemp, wanif_conf.mtu);
896  if(iReturnCode){
897  break;
898  }
899 
900  // Operational mode
901  _snprintf(szTemp, TMP_BUFFER_LEN, "aft_logic_channel_%d_operational_mode", interface_index);
902  iReturnCode = registry_set_string_value(hPortRegistryKey, szTemp, wanif_conf.usedby);
903  if(iReturnCode){
904  break;
905  }
906 
907  // Active Timeslots for the Group
908  _snprintf(szTemp, TMP_BUFFER_LEN, "aft_logic_channel_%d_active_ch", interface_index);
909  iReturnCode = registry_set_string_value(hPortRegistryKey, szTemp, timeslot_bitmap_to_string(wanif_conf.active_ch));
910  if(iReturnCode){
911  break;
912  }
913 
914  // Idle char.
915  _snprintf(szTemp, TMP_BUFFER_LEN, "aft_logic_channel_%d_idle_char", interface_index);
916  iReturnCode = registry_set_integer_value(hPortRegistryKey, szTemp, wanif_conf.u.aft.idle_flag);
917  if(iReturnCode){
918  break;
919  }
920 
921  }while(0);
922 
923  return iReturnCode;
924 }
925 
930 static sangoma_status_t sangoma_control_cards(DWORD StateChange)
931 {
932  sangoma_status_t rc;
933  int i;
934  SP_DEVINFO_DATA deid = {sizeof(SP_DEVINFO_DATA)};
935  HDEVINFO hdi;
936  TCHAR szInstanceId[MAX_COMP_INSTID];
937 
938  const TCHAR *szAftSearchSubStr = "PCI\\VEN_1923"; /* Sangoma PCI Vendor ID is 1923 */
939  /*const TCHAR *szS518AdslSearchSubStr = "PCI\\VEN_14BC&DEV_D002";*/ /* Note: S518 is end-of-life */
940 
941  SP_PROPCHANGE_PARAMS pcp;
942 
943  hdi = SetupDiGetClassDevs((struct _GUID *)&GUID_DEVCLASS_SANGOMA_ADAPTER, NULL, NULL, DIGCF_PRESENT);
944  if(INVALID_HANDLE_VALUE == hdi){
945  /* no sangoma cards installed on the system */
947  }
948 
949  /* search for all AFT Cards: */
950  for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &deid); i++){
951 
952  BOOL fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid, (PSTR)szInstanceId, sizeof(szInstanceId), NULL);
953  if (!fSuccess){
955  break;
956  }
957  if(!strstr(szInstanceId, szAftSearchSubStr)){
958  /* Found Sangoma Port, but we are interested only Cards. */
959  continue;
960  }
961 
962  memset(&pcp, 0x00, sizeof(pcp));
963  //Set the PropChangeParams structure.
964  pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
965  pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
966  pcp.Scope = DICS_FLAG_GLOBAL; /* DICS_FLAG_CONFIGSPECIFIC will enable ALL cards, including
967  * those explicetly DISABLED by the user in the Device Manager,
968  * and we don't want to force anything on the user, hence we
969  * use DICS_FLAG_GLOBAL. */
970  pcp.StateChange = StateChange;
971 
972  if(!SetupDiSetClassInstallParams(hdi, &deid, (SP_CLASSINSTALL_HEADER *)&pcp, sizeof(pcp))){
974  break;
975  }
976 
977  if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hdi, &deid)){
979  break;
980  }
981 
982  }/* for() */
983 
984  SetupDiDestroyDeviceInfoList(hdi);
985 
986  return SANG_STATUS_SUCCESS;
987 }
988 
989 sangoma_status_t _LIBSNG_CALL sangoma_unload_driver()
990 {
991  return sangoma_control_cards(DICS_DISABLE);
992 }
993 
994 sangoma_status_t _LIBSNG_CALL sangoma_load_driver()
995 {
996  return sangoma_control_cards(DICS_ENABLE);
997 }
998 
1004 void _LIBSNG_CALL sangoma_reset_port_numbers()
1005 {
1006  int i, iRegistryReturnCode, iPortCounter = 0;
1007  SP_DEVINFO_DATA deid={sizeof(SP_DEVINFO_DATA)};
1008  HDEVINFO hdi = SetupDiGetClassDevs((struct _GUID *)&GUID_DEVCLASS_SANGOMA_ADAPTER, NULL,NULL, DIGCF_PRESENT);
1009  HKEY hKeyTmp = (struct HKEY__ *)INVALID_HANDLE_VALUE;
1010 
1011  char szCompInstanceId[MAX_COMP_INSTID];
1012  TCHAR szCompDescription[MAX_COMP_DESC];
1013  DWORD dwRegType;
1014  /* Possible Sangoma Port Names (refer to sdladrv.inf):
1015  Sangoma Hardware Abstraction Driver (Port 1)
1016  Sangoma Hardware Abstraction Driver (Port 2)
1017  Sangoma Hardware Abstraction Driver (Port 3)
1018  Sangoma Hardware Abstraction Driver (Port 4)
1019  Sangoma Hardware Abstraction Driver (Port 5)
1020  Sangoma Hardware Abstraction Driver (Port 6)
1021  Sangoma Hardware Abstraction Driver (Port 7)
1022  Sangoma Hardware Abstraction Driver (Port 8)
1023  Sangoma Hardware Abstraction Driver (Analog)
1024  Sangoma Hardware Abstraction Driver (ISDN BRI) */
1025  const TCHAR *search_SubStr = "Sangoma Hardware Abstraction Driver";
1026 
1027  /* search for all (AFT) ports: */
1028  for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &deid); i++){
1029 
1030  BOOL fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid, (PSTR)szCompInstanceId, MAX_COMP_INSTID, NULL);
1031  if (!fSuccess){
1032  continue;
1033  }
1034 
1035  fSuccess = SetupDiGetDeviceRegistryProperty(hdi, &deid, SPDRP_DEVICEDESC, &dwRegType, (BYTE*)szCompDescription, MAX_COMP_DESC, NULL);
1036  if (!fSuccess){
1037  continue;
1038  }
1039 
1040  if (!strstr(szCompDescription, search_SubStr)) { /* Windows can add #2 etc - do NOT consider */
1041  /* This is a "Sangoma Card" device, we are interested only in "Sangoma Port" devices. */
1042  continue;
1043  }
1044 
1045  hKeyTmp = SetupDiOpenDevRegKey(hdi, &deid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_SET_VALUE );
1046  if(hKeyTmp == INVALID_HANDLE_VALUE){
1047  DBG_REGISTRY("Error: Failed to open Registry key!!\n");
1048  continue;
1049  }
1050 
1051  iPortCounter++;
1052 
1053  printf("* %s -> Setting Span/Port number: %d\n", szCompDescription, iPortCounter);
1054 
1055  /* TODO: 1. search for installed Sangoma Cards
1056  2. for each Card, search Ports (Bus/Slot must match)
1057  3. based on number of installed Ports, set SerialNumbersRange of the Card
1058 
1059  This way the WP_REGSTR_USER_SPECIFIED_WANPIPE_NUMBER can be set to zero and Span numbers will be
1060  sequencial automatically.
1061  */
1062  iRegistryReturnCode = registry_set_integer_value(hKeyTmp, WP_REGSTR_USER_SPECIFIED_WANPIPE_NUMBER, iPortCounter);
1063  if(iRegistryReturnCode){
1064  continue;
1065  }
1066 
1067  RegCloseKey(hKeyTmp);
1068 
1069  }/* for() */
1070 
1071  SetupDiDestroyDeviceInfoList(hdi);
1072 
1073  return;
1074 }
1075 
1076 
1082 sangoma_status_t _LIBSNG_CALL sangoma_get_driver_version_from_registry(char *out_buffer, int out_buffer_length)
1083 {
1084  int i, iRegistryReturnCode;
1085  SP_DEVINFO_DATA deid = {sizeof(SP_DEVINFO_DATA)};
1086  HDEVINFO hdi = SetupDiGetClassDevs((struct _GUID *)&GUID_DEVCLASS_SANGOMA_ADAPTER, NULL, NULL, DIGCF_PRESENT);
1087  DWORD dwTemp;
1088  HKEY hKeyTmp = (struct HKEY__ *)INVALID_HANDLE_VALUE;
1089 
1090  TCHAR szTmp[MAX_COMP_DESC];
1091  BOOL fSuccess = FALSE;
1092 
1093  /* search for ANY Sangoma device of class GUID_DEVCLASS_SANGOMA_ADAPTER */
1094  for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &deid); i++){
1095 
1096  fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid, (PSTR)szTmp, sizeof(szTmp), NULL);
1097  if (!fSuccess){
1098  break;
1099  }
1100  DBG_REGISTRY("%s(): Device Instance Id: %s\n", __FUNCTION__, szTmp);
1101  /* Device Instance Id: COMMSADAPTER\SANGOMAADAPTER_AFT_LINE8\5&32E1B75F&0&13
1102  Device Instance Id: PCI\VEN_1923&DEV_0100&SUBSYS_4113A114&REV_00\4&31B6CD7&0&10F0 */
1103 
1104  hKeyTmp = SetupDiOpenDevRegKey( hdi, &deid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_SET_VALUE );
1105  if(hKeyTmp == INVALID_HANDLE_VALUE){
1106  DBG_REGISTRY("Error: Failed to open Registry key!!\n");
1107  fSuccess = FALSE;
1108  break;
1109  }
1110 
1111  iRegistryReturnCode = registry_get_string_value(hKeyTmp, "DriverVersion", szTmp, &dwTemp);
1112  if(iRegistryReturnCode){
1113  fSuccess = FALSE;
1114  break;
1115  }
1116 
1117  wp_snprintf(out_buffer, out_buffer_length, szTmp);
1118 
1119  RegCloseKey(hKeyTmp);
1120 
1121  /* it is enough to read the version only once, so break here */
1122  break; /* breaking here will generate "warning C4702: unreachable code" - it is ok */
1123  }/* for() */
1124 
1125  SetupDiDestroyDeviceInfoList(hdi);
1126 
1127  if (!fSuccess){
1129  }else{
1130  return SANG_STATUS_SUCCESS;
1131  }
1132 }
1133 
1139 sangoma_status_t _LIBSNG_CALL sangoma_set_driver_mode_of_all_hw_devices(int driver_mode)
1140 {
1141  sangoma_status_t rc;
1142  int i, iRegistryReturnCode;
1143  SP_DEVINFO_DATA deid = {sizeof(SP_DEVINFO_DATA)};
1144  HDEVINFO hdi;
1145  TCHAR szInstanceId[MAX_COMP_INSTID];
1146  HKEY hKeyTmp = (struct HKEY__ *)INVALID_HANDLE_VALUE;
1147 
1148  const TCHAR *szAftSearchSubStr = "PCI\\VEN_1923"; /* Sangoma PCI Vendor ID is 1923 */
1149 
1150  hdi = SetupDiGetClassDevs((struct _GUID *)&GUID_DEVCLASS_SANGOMA_ADAPTER, NULL, NULL, DIGCF_PRESENT);
1151  if(INVALID_HANDLE_VALUE == hdi){
1152  /* no sangoma cards installed on the system */
1154  }
1155 
1156  /* search for all AFT Cards: */
1157  for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &deid); i++){
1158 
1159  BOOL fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid, (PSTR)szInstanceId, sizeof(szInstanceId), NULL);
1160  if (!fSuccess){
1162  break;
1163  }
1164  if(!strstr(szInstanceId, szAftSearchSubStr)){
1165  /* Found Sangoma Port, but we are interested only Cards. */
1166  continue;
1167  }
1168 
1169  hKeyTmp = SetupDiOpenDevRegKey(hdi, &deid, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_SET_VALUE );
1170  if(hKeyTmp == INVALID_HANDLE_VALUE){
1172  break;
1173  }
1174 
1175  iRegistryReturnCode = registry_set_integer_value(hKeyTmp, "driver_mode", driver_mode);
1176  if(iRegistryReturnCode){
1178  break;
1179  }
1180 
1181  RegCloseKey(hKeyTmp);
1182 
1183  }/* for() */
1184 
1185  SetupDiDestroyDeviceInfoList(hdi);
1186 
1187  return SANG_STATUS_SUCCESS;
1188 }
1189 
1190 
1191 #endif /* __WINDOWS__ */
1192 
1193 
1194 /*********************************************************************/
1198 /*************************************************/
1199 /* private functions for accessing wan_udp_hdr_t */
1200 /*************************************************/
1201 /* return POINTER to DATA at offset 'off' */
1202 static unsigned char* sangoma_get_wan_udphdr_data_ptr(wan_udp_hdr_t *wan_udp_ptr, unsigned char off)
1203 {
1204  unsigned char *p_data = &wan_udp_ptr->wan_udphdr_data[0];
1205  p_data += off;
1206  return p_data;
1207 }
1208 
1209 /* set a single byte of DATA at offset 'off' */
1210 static unsigned char sangoma_set_wan_udphdr_data_byte(wan_udp_hdr_t *wan_udp_ptr, unsigned char off, unsigned char data)
1211 {
1212  unsigned char *p_data = &wan_udp_ptr->wan_udphdr_data[0];
1213  p_data[off] = data;
1214  return 0;
1215 }
1216 
1217 /* return a single byte of DATA at offset 'off' */
1218 static unsigned char sangoma_get_wan_udphdr_data_byte(wan_udp_hdr_t *wan_udp_ptr, unsigned char off)
1219 {
1220  unsigned char *p_data = &wan_udp_ptr->wan_udphdr_data[0];
1221  return p_data[off];
1222 }
1223 /*************************************************/
1224 
1225 
1226 /************************************************************/
1239 sangoma_status_t _LIBSNG_CALL sangoma_wait_obj_create(sangoma_wait_obj_t **sangoma_wait_object, sng_fd_t fd, sangoma_wait_obj_type_t object_type)
1240 {
1241  int err = 0;
1242  sangoma_wait_obj_t *sng_wait_obj = NULL;
1243 
1244  if (!sangoma_wait_object) {
1246  }
1247  *sangoma_wait_object = NULL;
1248  sng_wait_obj = malloc(sizeof(**sangoma_wait_object));
1249  if (!sng_wait_obj) {
1251  }
1252 
1253  memset(sng_wait_obj, 0x00, sizeof(*sng_wait_obj));
1254  /* it is a first initialization of the object */
1255  sng_wait_obj->init_flag = LIBSNG_MAGIC_NO;
1256 
1257  sng_wait_obj->fd = fd;
1258  sng_wait_obj->object_type = object_type;
1259 
1260 #if defined(__WINDOWS__)
1261  if (!SANGOMA_OBJ_HAS_DEVICE(sng_wait_obj)) {
1262  sng_wait_obj->signal_object = CreateEvent(NULL, FALSE, FALSE, NULL);
1263  if(!sng_wait_obj->signal_object){
1265  goto failed;
1266  }
1267  err = SANG_STATUS_SUCCESS;
1268  } else {
1269  err = init_sangoma_event_object(sng_wait_obj, fd);
1270  if(SANG_STATUS_SUCCESS != err){
1271  goto failed;
1272  }
1273  }
1274 #else
1275  int flags;
1276  int filedes[2];
1277  if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
1278  sng_wait_obj->signal_read_fd = INVALID_HANDLE_VALUE;
1279  sng_wait_obj->signal_write_fd = INVALID_HANDLE_VALUE;
1280  /* if we want cross-process event notification we can use a named pipe with mkfifo() */
1281  if (pipe(filedes)) {
1283  goto failed;
1284  }
1285  sng_wait_obj->signal_read_fd = filedes[0];
1286  sng_wait_obj->signal_write_fd = filedes[1];
1287  /* make the read fd non-blocking, multiple threads can wait for it but just one
1288  * wil read the dummy notify character, the others would block otherwise and that's
1289  * not what we want */
1290  flags = fcntl(sng_wait_obj->signal_read_fd, F_GETFL, 0);
1291  if (flags < 0) {
1293  goto failed;
1294  }
1295  flags |= O_NONBLOCK;
1296  fcntl(sng_wait_obj->signal_read_fd, F_SETFL, flags);
1297  flags = fcntl(sng_wait_obj->signal_read_fd, F_GETFL, 0);
1298  if (flags < 0 || !(flags & O_NONBLOCK)) {
1300  goto failed;
1301  }
1302  }
1303 #endif
1304  *sangoma_wait_object = sng_wait_obj;
1305  return err;
1306 
1307 failed:
1308  if (sng_wait_obj) {
1309  sangoma_wait_obj_delete(&sng_wait_obj);
1310  }
1311  return err;
1312 }
1313 
1320 sangoma_status_t _LIBSNG_CALL sangoma_wait_obj_delete(sangoma_wait_obj_t **sangoma_wait_object)
1321 {
1322  sangoma_wait_obj_t *sng_wait_obj = *sangoma_wait_object;
1323 
1324  if(sng_wait_obj->init_flag != LIBSNG_MAGIC_NO){
1325  /* error. object was not initialized by sangoma_wait_obj_init() */
1327  }
1328 
1329 #if defined(__WINDOWS__)
1330  if (sng_wait_obj->signal_object &&
1331  sng_wait_obj->signal_object != INVALID_HANDLE_VALUE) {
1332  sangoma_close(&sng_wait_obj->signal_object);
1333  }
1334 #else
1335  if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
1336  sangoma_close(&sng_wait_obj->signal_read_fd);
1337  sangoma_close(&sng_wait_obj->signal_write_fd);
1338  }
1339 #endif
1340  sng_wait_obj->init_flag = 0;
1341  sng_wait_obj->object_type = UNKNOWN_WAIT_OBJ;
1342  free(sng_wait_obj);
1343  *sangoma_wait_object = NULL;
1344  return SANG_STATUS_SUCCESS;
1345 }
1346 
1353 int _LIBSNG_CALL sangoma_wait_obj_signal(sangoma_wait_obj_t *sng_wait_obj)
1354 {
1355  if (!SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_obj)) {
1356  /* even when Windows objects are always signalable for the sake of providing
1357  * a consistent interface to the user we downgrade the capabilities of Windows
1358  * objects unless the sangoma wait object is explicitly initialized as signalable */
1360  }
1361 #if defined(__WINDOWS__)
1362  if(sng_wait_obj->signal_object){
1363  if (!SetEvent(sng_wait_obj->signal_object)) {
1365  }
1366  }
1367 #else
1368  /* at this point we know is a signalable object and has a signal_write_fd */
1369  if (write(sng_wait_obj->signal_write_fd, "s", 1) < 1) {
1371  }
1372 #endif
1373  return SANG_STATUS_SUCCESS;
1374 }
1375 
1382 sng_fd_t _LIBSNG_CALL sangoma_wait_obj_get_fd(sangoma_wait_obj_t *sng_wait_obj)
1383 {
1384  return sng_wait_obj->fd;
1385 }
1386 
1395 void _LIBSNG_CALL sangoma_wait_obj_set_context(sangoma_wait_obj_t *sng_wait_obj, void *context)
1396 {
1397  sng_wait_obj->context = context;
1398 }
1399 
1406 PVOID _LIBSNG_CALL sangoma_wait_obj_get_context(sangoma_wait_obj_t *sng_wait_obj)
1407 {
1408  return sng_wait_obj->context;
1409 }
1410 
1421 sangoma_status_t _LIBSNG_CALL sangoma_waitfor_many(sangoma_wait_obj_t *sng_wait_objects[], uint32_t in_flags[], uint32_t out_flags[],
1422  uint32_t number_of_sangoma_wait_objects, int32_t system_wait_timeout)
1423 {
1424 #if defined(__WINDOWS__)
1425  HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
1426  DWORD dwResult;
1427  int at_least_one_poll_set_flags_out, err;
1428  sangoma_wait_obj_t *sangoma_wait_object;
1429 #else
1430  uint32_t j = 0;
1431 #endif
1432  uint32_t i = 0;
1433 
1434  memset(out_flags, 0x00, number_of_sangoma_wait_objects * sizeof(out_flags[0]));
1435 #if defined(__WINDOWS__)
1436 
1437  if(sangoma_check_number_of_wait_objects(number_of_sangoma_wait_objects)){
1438  /* error - most likely the user did not initialize sng_wait_objects[] */
1440  }
1441 
1442  for(i = 0; i < MAXIMUM_WAIT_OBJECTS; i++){
1443  hEvents[i] = INVALID_HANDLE_VALUE;
1444  }
1445 
1446  /* This loop will initialize 'hEvents[]' based on
1447  * 'number_of_sangoma_wait_objects' and sng_wait_objects[]. */
1448  for(i = 0; i < number_of_sangoma_wait_objects; i++){
1449 
1450  sangoma_wait_object = sng_wait_objects[i];
1451 
1452  if(LIBSNG_MAGIC_NO != sangoma_wait_object->init_flag){
1454  }
1455 
1456  if(sangoma_wait_object->signal_object){
1457  hEvents[i] = sangoma_wait_object->signal_object;
1458  }
1459 
1460  }/* for() */
1461 
1462  at_least_one_poll_set_flags_out = FALSE;
1463 
1464  /* It is important to get 'out flags' BEFORE the WaitForMultipleObjects()
1465  * because it allows to keep API driver's TRANSMIT queue full. */
1466  err = get_out_flags(sng_wait_objects, INVALID_INDEX, in_flags, out_flags, number_of_sangoma_wait_objects, &at_least_one_poll_set_flags_out);
1467  if(SANG_ERROR(err)){
1468  return err;
1469  }
1470 
1471  if(TRUE == at_least_one_poll_set_flags_out){
1472  return SANG_STATUS_SUCCESS;
1473  }
1474 
1475  /* wait untill at least one of the events is signaled OR a 'system_wait_timeout' occured */
1476  dwResult = WaitForMultipleObjects(number_of_sangoma_wait_objects, &hEvents[0], FALSE, system_wait_timeout);
1477  if (WAIT_TIMEOUT == dwResult){
1479  }
1480 
1481  if( dwResult >= (DWORD)number_of_sangoma_wait_objects ) {
1483  }
1484 
1485  /* WaitForMultipleObjects() was waken by a Sangoma or by a non-Sangoma wait object. */
1486  err = get_out_flags(sng_wait_objects,
1487  dwResult, /* Array index of the signalled object with the smallest index
1488  * value of all the signalled objects, from array. */
1489  in_flags, out_flags, number_of_sangoma_wait_objects, NULL);
1490  if(SANG_ERROR(err)){
1491  return err;
1492  }
1493 
1494  return SANG_STATUS_SUCCESS;
1495 #else
1496  struct pollfd pfds[number_of_sangoma_wait_objects*2]; /* we need twice as many polls because of the sangoma signalable objects */
1497  char dummy_buf[1];
1498  int res;
1499  j = 0;
1500 
1501  memset(pfds, 0, sizeof(pfds));
1502 
1503  for(i = 0; i < number_of_sangoma_wait_objects; i++){
1504 
1505  if (SANGOMA_OBJ_HAS_DEVICE(sng_wait_objects[i])) {
1506  pfds[i].fd = sng_wait_objects[i]->fd;
1507  pfds[i].events = in_flags[i];
1508  }
1509 
1510  if (SANGOMA_OBJ_IS_SIGNALABLE(sng_wait_objects[i])) {
1511  pfds[number_of_sangoma_wait_objects+j].fd = sng_wait_objects[i]->signal_read_fd;
1512  pfds[number_of_sangoma_wait_objects+j].events = POLLIN;
1513  j++;
1514  }
1515  }
1516 
1517  poll_try_again:
1518 
1519  res = poll(pfds, (number_of_sangoma_wait_objects + j), system_wait_timeout);
1520  if (res > 0) {
1521  for(i = 0; i < number_of_sangoma_wait_objects; i++){
1522  out_flags[i] = pfds[i].revents;
1523  /* POLLIN, POLLOUT, POLLPRI have same values as SANG_WAIT_OBJ_ HAS_INPUT, CAN_OUTPUT and HAS_EVENTS, no need to set them */
1524  }
1525  for(i = 0; i < j; i++){
1526  if (pfds[number_of_sangoma_wait_objects+i].revents & POLLIN) {
1527  /* read and discard the signal byte */
1528  read(pfds[number_of_sangoma_wait_objects+i].fd, &dummy_buf, 1);
1529  /* set the proper flag so users may know this object was signaled */
1530  out_flags[i] |= SANG_WAIT_OBJ_IS_SIGNALED;
1531  }
1532  }
1533  } else if (res < 0 && errno == EINTR) {
1534  /* TODO: decrement system_wait_timeout */
1535  goto poll_try_again;
1536  }
1537  if (res < 0) {
1539  }
1540  if (res == 0) {
1542  }
1543  return SANG_STATUS_SUCCESS;
1544 #endif
1545 }
1546 
1547 
1555 sangoma_status_t _LIBSNG_CALL sangoma_waitfor(sangoma_wait_obj_t *sangoma_wait_obj, uint32_t inflags, uint32_t *outflags, int32_t timeout)
1556 {
1557  return sangoma_waitfor_many(&sangoma_wait_obj, &inflags, outflags, 1, timeout);
1558 }
1559 
1560 
1561 /************************************************************/
1566 int _LIBSNG_CALL sangoma_span_chan_toif(int span, int chan, char *interface_name)
1567 {
1568 #if defined(__WINDOWS__)
1569  /* Form the Interface Name from span and chan number (i.e. wanpipe1_if1). */
1570  sprintf(interface_name, WP_INTERFACE_NAME_FORM, span, chan);
1571 #else
1572  sprintf(interface_name,"s%ic%i",span,chan);
1573 #endif
1574  return 0;
1575 }
1576 
1577 int _LIBSNG_CALL sangoma_interface_toi(char *interface_name, int *span, int *chan)
1578 {
1579  char *p=NULL, *sp = NULL, *ch = NULL;
1580  int ret = 0;
1581  char data[FNAME_LEN];
1582 
1583  strncpy(data, interface_name, FNAME_LEN);
1584  if ((data[0])) {
1585  for (p = data; *p; p++) {
1586  if (sp && *p == 'g') {
1587  *p = '\0';
1588  ch = (p + 1);
1589  break;
1590  } else if (*p == 'w') {
1591  sp = (p + 1);
1592  }
1593  }
1594 
1595  if(ch && sp) {
1596  *span = atoi(sp);
1597  *chan = atoi(ch);
1598  ret = 1;
1599  } else {
1600  *span = -1;
1601  *chan = -1;
1602  }
1603  }
1604 
1605  return ret;
1606 }
1607 
1608 int _LIBSNG_CALL sangoma_interface_wait_up(int span, int chan, int sectimeout)
1609 {
1610 #if defined(__WINDOWS__)
1611  /* Windows does not need to wait for interfaces to come up */
1612  return 0;
1613 #else
1614  char interface_name[FNAME_LEN];
1615  struct stat statbuf;
1616  struct timeval endtime = {0,0};
1617  struct timeval curtime = {0,0};
1618  int counter;
1619  int rc;
1620  if (sectimeout >= 0 && gettimeofday(&endtime, NULL)) {
1621  return -1;
1622  }
1623  snprintf(interface_name, sizeof(interface_name), "/dev/" WP_INTERFACE_NAME_FORM, span, chan);
1624  endtime.tv_sec += sectimeout;
1625  do {
1626  counter = 0;
1627  while ((rc = stat(interface_name, &statbuf)) && errno == ENOENT && counter != 10) {
1628  poll(0, 0, 100); // test in 100ms increments
1629  counter++;
1630  }
1631  if (!rc || errno != ENOENT) break;
1632  if (gettimeofday(&curtime, NULL)) {
1633  return -1;
1634  }
1635  } while (sectimeout < 0 || timercmp(&endtime, &curtime,>));
1636  return rc;
1637 #endif
1638 }
1639 
1640 int _LIBSNG_CALL sangoma_span_chan_fromif(char *interface_name, int *span, int *chan)
1641 {
1642  char *p = NULL, *sp = NULL, *ch = NULL;
1643  int ret = 0;
1644  char data[FNAME_LEN];
1645 
1646  /* Windows: Accept WANPIPEx_IFy or wanpipex_ify
1647  * where x is the span and y is the chan. */
1648 
1649  strncpy(data, interface_name, FNAME_LEN);
1650  if ((data[0])) {
1651  for (p = data; *p; p++) {
1652 #if defined(__WINDOWS__)
1653  if (sp && (*p == 'F'||*p == 'f')) {
1654 #else
1655  if (sp && *p == 'c') {
1656 #endif
1657  *p = '\0';
1658  ch = (p + 1);
1659  break;
1660 #if defined(__WINDOWS__)
1661  } else if (*p == 'E'||*p == 'e') {
1662 #else
1663  } else if (*p == 's') {
1664 #endif
1665  sp = (p + 1);
1666  }
1667  }
1668 
1669  if(ch && sp) {
1670  *span = atoi(sp);
1671  *chan = atoi(ch);
1672  ret = 1;
1673  } else {
1674  *span = -1;
1675  *chan = -1;
1676  }
1677  }
1678 
1679  return ret;
1680 }
1681 
1683 {
1685  wanpipe_api_t tdm_api;
1686  int err;
1687 
1688  fd = __sangoma_open_api_span_chan(span, chan);
1689 
1690 #if defined(__WINDOWS__)
1691  if(fd == INVALID_HANDLE_VALUE){
1692  return fd;
1693  }
1694 #else
1695  if (fd < 0) {
1696  return fd;
1697  }
1698 #endif
1699 
1700  memset(&tdm_api,0,sizeof(tdm_api));
1701  tdm_api.wp_cmd.cmd = WP_API_CMD_OPEN_CNT;
1702  err=sangoma_cmd_exec(fd,&tdm_api);
1703  if (err){
1704  sangoma_close(&fd);
1705  return fd;
1706  }
1707 
1708  if (tdm_api.wp_cmd.open_cnt > 1) {
1709  /* this is NOT the first open request for this span/chan */
1710  sangoma_close(&fd);
1711  fd = INVALID_HANDLE_VALUE;/* fd is NOT valid anymore */
1712  }
1713 
1714  return fd;
1715 }
1716 
1718 {
1719  char fname[FNAME_LEN];
1720 
1721 #if defined(__WINDOWS__)
1722  _snprintf(fname , FNAME_LEN, "\\\\.\\%s", dev_name);
1723 
1724  return CreateFile( fname,
1725  GENERIC_READ | GENERIC_WRITE,
1726  FILE_SHARE_READ | FILE_SHARE_WRITE,
1727  (LPSECURITY_ATTRIBUTES)NULL,
1728  OPEN_EXISTING,
1729  FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
1730  (HANDLE)NULL
1731  );
1732 #else
1733  sprintf(fname,"/dev/%s", dev_name);
1734 
1735  return open(fname, O_RDWR);
1736 #endif
1737 }
1738 
1739 /* no checks done for multiple open */
1741 {
1742  char tmp_fname[FNAME_LEN];
1743 
1744  /* Form the Interface Name from span and chan number (i.e. wanpipe1_if1). */
1745  _snprintf(tmp_fname, DEV_NAME_LEN, WP_INTERFACE_NAME_FORM, span, chan);
1746 
1747  return sangoma_open_dev_by_name(tmp_fname);
1748 }
1749 
1751 {
1752  return sangoma_open_dev_by_name(WP_CTRL_DEV_NAME);
1753 }
1754 
1755 #ifdef WP_API_FEATURE_LOGGER
1757 {
1758  return sangoma_open_dev_by_name(WP_LOGGER_DEV_NAME);
1759 }
1760 #endif
1761 
1763 {
1764  int err;
1765 
1766  WANPIPE_API_INIT_CHAN(tdm_api, 0);
1768  tdm_api->wp_cmd.cmd = WP_API_CMD_OPEN_CNT;
1769 
1770  err=sangoma_cmd_exec(fd,tdm_api);
1771  if (err){
1772  return -1;
1773  }
1774 
1775  return tdm_api->wp_cmd.open_cnt;
1776 }
1777 
1779 {
1780  int span,chan;
1781  sangoma_interface_toi(device,&span,&chan);
1782 
1783  return sangoma_open_api_span_chan(span,chan);
1784 }
1785 
1786 
1787 sng_fd_t _LIBSNG_CALL sangoma_open_api_span(int span)
1788 {
1789  int i=0;
1791 
1792  for(i = 1; i < 32; i++){
1793 
1794  fd = sangoma_open_api_span_chan(span, i);
1795 
1796 #if defined(__WINDOWS__)
1797  if(fd != INVALID_HANDLE_VALUE){
1798 #else
1799  if (fd >= 0) {
1800 #endif
1801 
1802  /* found free chan */
1803  break;
1804  }
1805 
1806  }/*for()*/
1807 
1808  return fd;
1809 }
1810 
1811 
1819 {
1820  if (!fd) {
1821  return;
1822  }
1823 #if defined(__WINDOWS__)
1824  if (*fd != INVALID_HANDLE_VALUE){
1825  CloseHandle(*fd);
1826  *fd = INVALID_HANDLE_VALUE;
1827  }
1828 #else
1829  if (*fd >= 0) {
1830  close(*fd);
1831  *fd = -1;
1832  }
1833 #endif
1834 }
1835 
1836 
1837 
1838 /************************************************************/
1842 int _LIBSNG_CALL sangoma_readmsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
1843 {
1844  int rx_len=0;
1845 
1846 #if defined(__WINDOWS__)
1847  wp_api_hdr_t *rx_hdr = (wp_api_hdr_t*)hdrbuf;
1848  wan_iovec_list_t iovec_list;
1849 
1850  if (hdrlen != sizeof(wp_api_hdr_t)) {
1851  /*error*/
1852  DBG_ERR("hdrlen (%i) != sizeof(wp_api_hdr_t) (%i)\n", hdrlen, sizeof(wp_api_hdr_t));
1853  return -1;
1854  }
1855 
1856  memset(&iovec_list, 0x00, sizeof(iovec_list));
1857 
1858  iovec_list.iovec_list[0].iov_base = hdrbuf;
1859  iovec_list.iovec_list[0].iov_len = hdrlen;
1860 
1861  iovec_list.iovec_list[1].iov_base = databuf;
1862  iovec_list.iovec_list[1].iov_len = datalen;
1863 
1864  if (DoReadCommand(fd, &iovec_list)) {
1865  /*error*/
1866  DBG_ERR("DoReadCommand() failed! Check messages log.\n");
1867  return -4;
1868  }
1869 
1870  switch(rx_hdr->operation_status)
1871  {
1873  /* ok */
1874  break;
1876  /* Note that SANG_STATUS_NO_DATA_AVAILABLE is NOT an error becase
1877  * read() is non-blocking and can be called at any time (by some polling code)*/
1878  return 1; /* return positive value to indicate IOCTL success, user must check 'rx_hdr->operation_status' */
1879  default:
1880  if(libsng_dbg_level)DBG_ERR("Operation Status: %s(%d)\n",
1882  return -5;
1883  }
1884 
1885  rx_len = rx_hdr->data_length;
1886 #else
1887  wan_msghdr_t msg;
1888  wan_iovec_t iov[2];
1889 
1890  memset(&msg,0,sizeof(msg));
1891  memset(&iov[0],0,sizeof(iov[0])*2);
1892 
1893  iov[0].iov_len=hdrlen;
1894  iov[0].iov_base=hdrbuf;
1895 
1896  iov[1].iov_len=datalen;
1897  iov[1].iov_base=databuf;
1898 
1899  msg.msg_iovlen=2;
1900  msg.msg_iov=iov;
1901 
1902  rx_len = read(fd,&msg,sizeof(msg));
1903 
1904  if (rx_len <= sizeof(wp_api_hdr_t)){
1905  return -EINVAL;
1906  }
1907 
1908  rx_len -= sizeof(wp_api_hdr_t);
1909 #endif
1910  return rx_len;
1911 }
1912 
1913 int _LIBSNG_CALL sangoma_writemsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
1914 {
1915  int bsent=-1;
1916  wp_api_hdr_t *wp_api_hdr = hdrbuf;
1917 #if defined(__WINDOWS__)
1918  wan_iovec_list_t iovec_list;
1919 #endif
1920 
1921  if (hdrlen != sizeof(wp_api_hdr_t)) {
1922  /* error. Possible cause is a mismatch between versions of API header files. */
1923  DBG_ERR("hdrlen (%i) != sizeof(wp_api_hdr_t) (%i)\n", hdrlen, sizeof(wp_api_hdr_t));
1924  return -1;
1925  }
1926 
1927 #if defined(__WINDOWS__)
1928 
1929  wp_api_hdr->data_length = datalen;
1930 
1931  memset(&iovec_list, 0x00, sizeof(iovec_list));
1932 
1933  iovec_list.iovec_list[0].iov_base = hdrbuf;
1934  iovec_list.iovec_list[0].iov_len = hdrlen;
1935 
1936  iovec_list.iovec_list[1].iov_base = databuf;
1937  iovec_list.iovec_list[1].iov_len = datalen;
1938 
1939  /* queue data for transmission */
1940  if (DoWriteCommand(fd, &iovec_list)) {
1941  /*error*/
1942  DBG_ERR("DoWriteCommand() failed!! Check messages log.\n");
1943  return -1;
1944  }
1945 
1946  bsent=0;
1947  /*check that frame was transmitted*/
1948  switch(wp_api_hdr->operation_status)
1949  {
1950  case SANG_STATUS_SUCCESS:
1951  bsent = datalen;
1952  break;
1953  default:
1954  DBG_ERR("Operation Status: %s(%d)\n",
1955  SDLA_DECODE_SANG_STATUS(wp_api_hdr->operation_status), wp_api_hdr->operation_status);
1956  break;
1957  }/*switch()*/
1958 #else
1959  wan_msghdr_t msg;
1960  wan_iovec_t iov[2];
1961 
1962  memset(&msg,0,sizeof(msg));
1963  memset(&iov[0],0,sizeof(iov[0])*2);
1964 
1965  iov[0].iov_len=hdrlen;
1966  iov[0].iov_base=hdrbuf;
1967 
1968  iov[1].iov_len=datalen;
1969  iov[1].iov_base=databuf;
1970 
1971  msg.msg_iovlen=2;
1972  msg.msg_iov=iov;
1973 
1974  bsent = write(fd,&msg,sizeof(msg));
1975 
1976  if (bsent == (datalen+hdrlen)){
1977  wp_api_hdr->wp_api_hdr_operation_status=SANG_STATUS_SUCCESS;
1978  bsent-=sizeof(wp_api_hdr_t);
1979  } else if (errno == EBUSY){
1980  wp_api_hdr->wp_api_hdr_operation_status=SANG_STATUS_DEVICE_BUSY;
1981  } else {
1982  wp_api_hdr->wp_api_hdr_operation_status=SANG_STATUS_IO_ERROR;
1983  }
1984  wp_api_hdr->wp_api_hdr_data_length=bsent;
1985 
1986 #endif
1987  return bsent;
1988 }
1989 
1990 
1991 #ifdef WANPIPE_TDM_API
1992 
1993 
1994 /************************************************************/
2000 /*========================================================
2001  * Execute TDM command
2002  *
2003  */
2005 {
2006  int err;
2007 
2008 #if defined(__WINDOWS__)
2009  err = tdmv_api_ioctl(fd, &tdm_api->wp_cmd);
2010 #else
2011  err = ioctl(fd,WANPIPE_IOCTL_API_CMD,&tdm_api->wp_cmd);
2012  if (err < 0){
2013  char tmp[50];
2014  sprintf(tmp,"TDM API: CMD: %i\n",tdm_api->wp_cmd.cmd);
2015  perror(tmp);
2016  return -1;
2017  }
2018 #endif
2019  return err;
2020 }
2021 
2022 /*========================================================
2023  * Get Full TDM API configuration per channel
2024  *
2025  */
2027 {
2028  int err;
2029 
2030  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2032  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FULL_CFG;
2033 
2034  err=sangoma_cmd_exec(fd,tdm_api);
2035  if (err){
2036  return err;
2037  }
2038 
2039 #if 0
2040  printf("TDM API CFG:\n");
2041  printf("\thw_tdm_coding:\t%d\n",tdm_api->wp_cmd.hw_tdm_coding);
2042  printf("\thw_mtu_mru:\t%d\n",tdm_api->wp_cmd.hw_mtu_mru);
2043  printf("\tusr_period:\t%d\n",tdm_api->wp_cmd.usr_period);
2044  printf("\ttdm_codec:\t%d\n",tdm_api->wp_cmd.tdm_codec);
2045  printf("\tpower_level:\t%d\n",tdm_api->wp_cmd.power_level);
2046  printf("\trx_disable:\t%d\n",tdm_api->wp_cmd.rx_disable);
2047  printf("\ttx_disable:\t%d\n",tdm_api->wp_cmd.tx_disable);
2048  printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_cmd.usr_mtu_mru);
2049  printf("\tidle flag:\t0x%02X\n",tdm_api->wp_cmd.idle_flag);
2050 
2051 #ifdef WP_API_FEATURE_FE_ALARM
2052  printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_cmd.fe_alarms);
2053 #endif
2054 
2055  printf("\trx pkt\t%d\ttx pkt\t%d\n",tdm_api->wp_cmd.stats.rx_packets,
2056  tdm_api->wp_cmd.stats.tx_packets);
2057  printf("\trx err\t%d\ttx err\t%d\n",
2058  tdm_api->wp_cmd.stats.rx_errors,
2059  tdm_api->wp_cmd.stats.tx_errors);
2060 #ifndef __WINDOWS__
2061  printf("\trx ovr\t%d\ttx idl\t%d\n",
2062  tdm_api->wp_cmd.stats.rx_fifo_errors,
2063  tdm_api->wp_cmd.stats.tx_carrier_errors);
2064 #endif
2065 #endif
2066 
2067  return 0;
2068 }
2069 
2070 /*========================================================
2071  * SET Codec on a particular Channel.
2072  *
2073  * Available codecs are defined in
2074  * /usr/src/linux/include/linux/wanpipe_cfg.h
2075  *
2076  * enum wan_codec_format {
2077  * WP_NONE,
2078  * WP_SLINEAR
2079  * }
2080  *
2081  */
2083 {
2084  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2086  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_CODEC;
2087  tdm_api->wp_cmd.tdm_codec = codec;
2088  return sangoma_cmd_exec(fd,tdm_api);
2089 }
2090 
2091 /*========================================================
2092  * GET Codec from a particular Channel.
2093  *
2094  * Available codecs are defined in
2095  * /usr/src/linux/include/linux/wanpipe_cfg.h
2096  *
2097  * enum wan_codec_format {
2098  * WP_NONE,
2099  * WP_SLINEAR
2100  * }
2101  *
2102  */
2104 {
2105  int err;
2106 
2107  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2109  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_CODEC;
2110 
2111  err=sangoma_cmd_exec(fd,tdm_api);
2112  if (err){
2113  return err;
2114  }
2115 
2116  return tdm_api->wp_cmd.tdm_codec;
2117 }
2118 
2119 /*========================================================
2120  * SET Rx/Tx Hardware Period in milliseconds.
2121  *
2122  * Available options are:
2123  * 10,20,30,40,50 ms
2124  *
2125  */
2127 {
2128  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2131  tdm_api->wp_cmd.usr_period = period;
2132  return sangoma_cmd_exec(fd,tdm_api);
2133 }
2134 
2135 /*========================================================
2136  * GET Rx/Tx Hardware Period in milliseconds.
2137  *
2138  * Available options are:
2139  * 10,20,30,40,50 ms
2140  *
2141  */
2143 {
2144  int err;
2145 
2146  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2149 
2150  err=sangoma_cmd_exec(fd,tdm_api);
2151  if (err){
2152  return err;
2153  }
2154 
2155  return tdm_api->wp_cmd.usr_period;
2156 }
2157 
2158 /*========================================================
2159  * GET Current User Hardware Coding Format
2160  *
2161  * Coding Format will be ULAW/ALAW based on T1/E1
2162  */
2163 
2165 {
2166  int err;
2167 
2168  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2170  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_CODING;
2171  err=sangoma_cmd_exec(fd,tdm_api);
2172  if (err){
2173  return err;
2174  }
2175  return tdm_api->wp_cmd.hw_tdm_coding;
2176 }
2177 
2178 #ifdef WP_API_FEATURE_DTMF_EVENTS
2179 /*========================================================
2180  * GET Current User Hardware DTMF Enabled/Disabled
2181  *
2182  * Will return true if HW DTMF is enabled on Octasic
2183  */
2184 
2186 {
2187  int err;
2188 
2189  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2191  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_DTMF;
2192  err=sangoma_cmd_exec(fd,tdm_api);
2193  if (err){
2194  return err;
2195  }
2196  return tdm_api->wp_cmd.hw_dtmf;
2197 }
2198 
2199 /*========================================================
2200  * GET status of echo canceler chip.
2201  *
2202  * Will return true if HW EC is available
2203  */
2204 
2206 {
2207  int err;
2208 
2209  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2211  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_HW_EC;
2212  err=sangoma_cmd_exec(fd,tdm_api);
2213  if (err){
2214  return err;
2215  }
2216  return tdm_api->wp_cmd.hw_ec;
2217 }
2218 #endif
2219 
2220 
2221 #ifdef WP_API_FEATURE_EC_CHAN_STAT
2222 /*========================================================
2223  * GET status of the echo canceler for current channel.
2224  *
2225  * Will return true if HW EC is enabled
2226  */
2227 
2229 {
2230  int err;
2231 
2232  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2235  err=sangoma_cmd_exec(fd,tdm_api);
2236  if (err){
2237  return err;
2238  }
2239  return tdm_api->wp_cmd.hw_ec;
2240 }
2241 
2242 #endif
2243 
2244 #ifdef WP_API_FEATURE_HWEC_PERSIST
2245 /*========================================================
2246  * Check if hwec persist is enabled or disabled.
2247  * If persist is on: then hwec will always stay enabled for
2248  * all channes.
2249  * If persist is off: hwec will not be enabled by default.
2250  *
2251  * Will return true if HW EC is persist mode is on
2252  */
2253 
2255 {
2256  int err;
2257 
2258  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2261  err=sangoma_cmd_exec(fd,tdm_api);
2262  if (err){
2263  return err;
2264  }
2265  return tdm_api->wp_cmd.hw_ec;
2266 }
2267 #endif
2268 
2269 
2270 /*========================================================
2271  * GET Current User MTU/MRU values in bytes.
2272  *
2273  * The USER MTU/MRU values will change each time a PERIOD
2274  * or CODEC is adjusted.
2275  */
2277 {
2278  int err;
2279 
2280  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2283 
2284  err=sangoma_cmd_exec(fd,tdm_api);
2285  if (err){
2286  return err;
2287  }
2288 
2289  return tdm_api->wp_cmd.usr_mtu_mru;
2290 }
2291 
2292 /*========================================================
2293  * SET TDM Power Level
2294  *
2295  * This option is not implemented yet
2296  *
2297  */
2299 {
2300  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2303  tdm_api->wp_cmd.power_level = power;
2304  return sangoma_cmd_exec(fd,tdm_api);
2305 }
2306 
2307 /*========================================================
2308  * GET TDM Power Level
2309  *
2310  * This option is not implemented yet
2311  *
2312  */
2314 {
2315  int err;
2316 
2317  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2320 
2321  err=sangoma_cmd_exec(fd,tdm_api);
2322  if (err){
2323  return err;
2324  }
2325 
2326  return tdm_api->wp_cmd.power_level;
2327 }
2328 
2330 {
2331  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2333  tdm_api->wp_cmd.cmd = WP_API_CMD_FLUSH_BUFFERS;
2334  return sangoma_cmd_exec(fd,tdm_api);
2335 }
2336 
2338 {
2339  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2342  return sangoma_cmd_exec(fd,tdm_api);
2343 }
2344 
2346 {
2347  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2350  return sangoma_cmd_exec(fd,tdm_api);
2351 }
2352 
2354 {
2355  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2358  return sangoma_cmd_exec(fd,tdm_api);
2359 }
2360 
2362 {
2363  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2366  tdm_api->wp_cmd.rbs_poll = poll_in_sec;
2367  return sangoma_cmd_exec(fd,tdm_api);
2368 }
2369 
2371 
2372  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2375  return sangoma_cmd_exec(fd,tdm_api);
2376 }
2377 
2378 int _LIBSNG_CALL sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel, unsigned char rbs)
2379 {
2380  WANPIPE_API_INIT_CHAN(tdm_api, channel);
2383  tdm_api->wp_cmd.rbs_tx_bits=rbs;
2384  return sangoma_cmd_exec(fd,tdm_api);
2385 }
2386 
2387 int _LIBSNG_CALL sangoma_tdm_read_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel, unsigned char *rbs)
2388 {
2389  int err;
2390  WANPIPE_API_INIT_CHAN(tdm_api, channel);
2392  tdm_api->wp_cmd.cmd = WP_API_CMD_READ_RBS_BITS;
2393  tdm_api->wp_cmd.rbs_tx_bits=0;
2394 
2395  err=sangoma_cmd_exec(fd,tdm_api);
2396  if (err){
2397  return err;
2398  }
2399 
2400  *rbs=(unsigned char)tdm_api->wp_cmd.rbs_rx_bits;
2401  return 0;
2402 }
2403 
2404 #ifdef WP_API_FEATURE_BUFFER_MULT
2405 
2406 int _LIBSNG_CALL sangoma_tdm_set_buffer_multiplier(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned int multiplier)
2407 {
2408 
2409  int err;
2410  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2413  *((unsigned int*)&tdm_api->wp_cmd.data[0]) = multiplier;
2414 
2415  err=sangoma_cmd_exec(fd,tdm_api);
2416  if (err){
2417  return err;
2418  }
2419 
2420  return 0;
2421 }
2422 
2423 #endif
2424 
2425 
2427 {
2428 
2429 #ifdef WP_API_FEATURE_EVENTS
2430  wp_api_event_t *rx_event;
2431  int err;
2432 
2433  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2435  tdm_api->wp_cmd.cmd = WP_API_CMD_READ_EVENT;
2436 
2437  err=sangoma_cmd_exec(fd,tdm_api);
2438  if (err){
2439  return err;
2440  }
2441 
2442  rx_event = &tdm_api->wp_cmd.event;
2443 
2444 #ifdef WP_API_DEPRECATED_FEATURE_READ_CALLBACK_FUNCTIONS
2445  /*
2446  The use of callbacks here is purely optional and is left
2447  here for backward compatibility purposes. By default user
2448  should handle events outside this funciton. This function
2449  should only be used to read the event
2450  */
2451 
2452  switch (rx_event->wp_api_event_type){
2453 
2454  case WP_API_EVENT_RBS:
2455  if (tdm_api->wp_callback.wp_rbs_event) {
2456  tdm_api->wp_callback.wp_rbs_event(fd,rx_event->wp_api_event_rbs_bits);
2457  }
2458  break;
2459 
2460 #ifdef WP_API_FEATURE_DTMF_EVENTS
2461  case WP_API_EVENT_DTMF:
2462  if (tdm_api->wp_callback.wp_dtmf_event) {
2463  tdm_api->wp_callback.wp_dtmf_event(fd,
2464  rx_event->wp_api_event_dtmf_digit,
2465  rx_event->wp_api_event_dtmf_type,
2466  rx_event->wp_api_event_dtmf_port);
2467  }
2468  break;
2469 #endif
2470 
2471  case WP_API_EVENT_RXHOOK:
2472  if (tdm_api->wp_callback.wp_rxhook_event) {
2473  tdm_api->wp_callback.wp_rxhook_event(fd,
2474  rx_event->wp_api_event_hook_state);
2475  }
2476  break;
2477 
2478  case WP_API_EVENT_RING_DETECT:
2479  if (tdm_api->wp_callback.wp_ring_detect_event) {
2480  tdm_api->wp_callback.wp_ring_detect_event(fd,
2481  rx_event->wp_api_event_ring_state);
2482  }
2483  break;
2484 
2485  case WP_API_EVENT_RING_TRIP_DETECT:
2486  if (tdm_api->wp_callback.wp_ring_trip_detect_event) {
2487  tdm_api->wp_callback.wp_ring_trip_detect_event(fd,
2488  rx_event->wp_api_event_ring_state);
2489  }
2490  break;
2491 
2492 #ifdef WP_API_FEATURE_FE_ALARM
2493  case WP_API_EVENT_ALARM:
2494  if (tdm_api->wp_callback.wp_fe_alarm_event) {
2495  tdm_api->wp_callback.wp_fe_alarm_event(fd,
2496  rx_event->wp_api_event_alarm);
2497  }
2498  break;
2499 #endif
2500 
2501 #ifdef WP_API_FEATURE_LINK_STATUS
2502  /* Link Status */
2503  case WP_API_EVENT_LINK_STATUS:
2504  if(tdm_api->wp_callback.wp_link_status_event){
2505  tdm_api->wp_callback.wp_link_status_event(fd,
2506  rx_event->wp_api_event_link_status);
2507  }
2508 
2509  break;
2510 #endif
2511 
2512 #ifdef WP_API_FEATURE_POL_REV
2513  case WP_API_EVENT_POLARITY_REVERSE:
2514  break;
2515 #endif
2516  default:
2517 #ifdef __WINDOWS__
2518  if(0)printf("Warning: libsangoma: %s fd=0x%p: Unknown TDM event!", __FUNCTION__,fd);
2519 #else
2520  if(0)printf("Warning: libsangoma: %s fd=%d: Unknown TDM event!", __FUNCTION__, fd);
2521 #endif
2522  break;
2523  }
2524 
2525 #endif
2526 
2527 
2528  return 0;
2529 #else
2530  printf("Error: Read Event not supported!\n");
2531  return -1;
2532 #endif
2533 }
2534 
2535 
2536 #ifdef WP_API_FEATURE_LOGGER
2537 /*========================================================
2538  * Execute Wanpipe Logger command
2539  */
2540 sangoma_status_t _LIBSNG_CALL sangoma_logger_cmd_exec(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
2541 {
2542 #if defined(__WINDOWS__)
2543  return logger_api_ioctl(fd, logger_cmd);
2544 #else
2545  int err = ioctl(fd,WANPIPE_IOCTL_LOGGER_CMD,logger_cmd);
2546  if (err < 0){
2547  char tmp[50];
2548  sprintf(tmp,"Logger CMD: %i\n",logger_cmd->cmd);
2549  perror(tmp);
2550  return -1;
2551  }
2552  return err;
2553 #endif
2554 }
2555 
2557 {
2558  logger_cmd->cmd = WP_API_LOGGER_CMD_READ_EVENT;
2559  return sangoma_logger_cmd_exec(fd, logger_cmd);
2560 }
2561 
2563 {
2564  logger_cmd->cmd = WP_API_LOGGER_CMD_FLUSH_BUFFERS;
2565  return sangoma_logger_cmd_exec(fd, logger_cmd);
2566 }
2567 
2569 {
2570  logger_cmd->cmd = WP_API_LOGGER_CMD_GET_STATS;
2571  return sangoma_logger_cmd_exec(fd, logger_cmd);
2572 }
2573 
2575 {
2576  logger_cmd->cmd = WP_API_LOGGER_CMD_RESET_STATS;
2577  return sangoma_logger_cmd_exec(fd, logger_cmd);
2578 }
2579 
2581 {
2582  logger_cmd->cmd = WP_API_LOGGER_CMD_OPEN_CNT;
2583  return sangoma_logger_cmd_exec(fd, logger_cmd);
2584 }
2585 
2587 {
2588  logger_cmd->cmd = WP_API_LOGGER_CMD_GET_LOGGER_LEVEL;
2589  return sangoma_logger_cmd_exec(fd, logger_cmd);
2590 }
2591 
2593 {
2594  logger_cmd->cmd = WP_API_LOGGER_CMD_SET_LOGGER_LEVEL;
2595  return sangoma_logger_cmd_exec(fd, logger_cmd);
2596 }
2597 
2598 #endif /* WP_API_FEATURE_LOGGER */
2599 
2600 #ifdef WP_API_FEATURE_FAX_EVENTS
2602 {
2603  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2605  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2606  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_FAX_DETECT;
2607  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2608  return sangoma_cmd_exec(fd,tdm_api);
2609 }
2610 
2612 {
2613  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2615  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2616  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_FAX_DETECT;
2617  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2618  return sangoma_cmd_exec(fd,tdm_api);
2619 }
2620 
2622 {
2623  int err;
2624  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2627  err=sangoma_cmd_exec(fd,tdm_api);
2628  if (err){
2629  return err;
2630  }
2631  return tdm_api->wp_cmd.hw_fax;
2632 }
2633 #endif
2634 
2635 #ifdef WP_API_FEATURE_DTMF_EVENTS
2637 {
2638  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2640  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2641  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_DTMF;
2642  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2643  return sangoma_cmd_exec(fd,tdm_api);
2644 }
2645 
2647 {
2648  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2650  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2651  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_DTMF;
2652  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2653  return sangoma_cmd_exec(fd,tdm_api);
2654 }
2655 
2657 {
2658  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2660  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2661  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RM_DTMF;
2662  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2663  return sangoma_cmd_exec(fd,tdm_api);
2664 }
2665 
2667 {
2668  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2670  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2671  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RM_DTMF;
2672  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2673  return sangoma_cmd_exec(fd,tdm_api);
2674 }
2675 
2677 {
2678  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2680  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2681  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RXHOOK;
2682  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2683  return sangoma_cmd_exec(fd,tdm_api);
2684 }
2685 
2687 {
2688  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2690  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2691  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RXHOOK;
2692  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2693  return sangoma_cmd_exec(fd,tdm_api);
2694 }
2695 
2697 {
2698  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2700  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2701  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING;
2702  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2703  return sangoma_cmd_exec(fd,tdm_api);
2704 }
2705 
2707 {
2708  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2710  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2711  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING;
2712  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2713  return sangoma_cmd_exec(fd,tdm_api);
2714 }
2715 
2717 {
2718  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2720  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2721  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
2722  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2723  return sangoma_cmd_exec(fd,tdm_api);
2724 }
2725 
2727 {
2728  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2730  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2731  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_DETECT;
2732  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2733  return sangoma_cmd_exec(fd,tdm_api);
2734 }
2735 
2737 {
2738  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2740  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2741  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_TRIP_DETECT;
2742  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2743  return sangoma_cmd_exec(fd,tdm_api);
2744 }
2745 
2747 {
2748  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2750  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2751  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_RING_TRIP_DETECT;
2752  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2753  return sangoma_cmd_exec(fd,tdm_api);
2754 }
2755 
2757 {
2758  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2760  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2761  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_KEWL;
2762  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2763  return sangoma_cmd_exec(fd,tdm_api);
2764 }
2765 
2767 {
2768  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2770  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2771  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_START;
2772  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2773  return sangoma_cmd_exec(fd,tdm_api);
2774 }
2775 
2777 {
2778  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2780  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2781  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_ONHOOK;
2782  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2783  return sangoma_cmd_exec(fd,tdm_api);
2784 }
2785 
2787 {
2788  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2790  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2791  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TXSIG_OFFHOOK;
2792  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2793  return sangoma_cmd_exec(fd,tdm_api);
2794 }
2795 
2797 {
2798  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2800  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2801  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TONE;
2802  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2803  tdm_api->wp_cmd.event.wp_api_event_tone_type = tone_id;
2804  return sangoma_cmd_exec(fd,tdm_api);
2805 }
2806 
2808 {
2809  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2811  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2812  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_TONE;
2813  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2814  tdm_api->wp_cmd.event.wp_api_event_tone_type = 0x00;
2815  return sangoma_cmd_exec(fd,tdm_api);
2816 }
2817 #endif
2818 
2820 {
2821  /* intentionally NOT initializing chan - caller must do it */
2823  tdm_api->wp_cmd.cmd = WP_API_CMD_ENABLE_HWEC;
2824  return sangoma_cmd_exec(fd,tdm_api);
2825 }
2826 
2828 {
2829  /* intentionally NOT initializing chan - caller must do it */
2831  tdm_api->wp_cmd.cmd = WP_API_CMD_DISABLE_HWEC;
2832  return sangoma_cmd_exec(fd,tdm_api);
2833 }
2834 
2835 
2836 /*========================================================
2837  * GET Front End Alarms
2838  *
2839  */
2840 #ifdef WP_API_FEATURE_FE_ALARM
2841 int _LIBSNG_CALL sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned int *alarms)
2842 {
2843  int err;
2844 
2845  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2847  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_ALARMS;
2848 
2849  err=sangoma_cmd_exec(fd,tdm_api);
2850  if (err){
2851  return err;
2852  }
2853 
2854  *alarms=tdm_api->wp_cmd.fe_alarms;
2855 
2856  return 0;
2857 }
2858 
2859 /* get current Line Connection state - Connected/Disconnected */
2860 int _LIBSNG_CALL sangoma_get_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
2861 {
2862  int err;
2863 
2864  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2866  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_STATUS;
2867  err = sangoma_cmd_exec(fd, tdm_api);
2868  *current_status = tdm_api->wp_cmd.fe_status;
2869 
2870  return err;
2871 }
2872 #endif
2873 
2874 /* get current Line Connection state - Connected/Disconnected */
2875 #ifdef WP_API_FEATURE_LINK_STATUS
2876 int _LIBSNG_CALL sangoma_get_link_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
2877 {
2878  int err;
2879 
2880  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2882  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_FE_STATUS;
2883  err = sangoma_cmd_exec(fd, tdm_api);
2884  *current_status = tdm_api->wp_cmd.fe_status;
2885 
2886  return err;
2887 }
2888 
2889 /* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */
2890 int _LIBSNG_CALL sangoma_set_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char new_status)
2891 {
2892  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2894  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_FE_STATUS;
2895  tdm_api->wp_cmd.fe_status = new_status;
2896  return sangoma_cmd_exec(fd, tdm_api);
2897 }
2898 #endif
2899 
2901 {
2902  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2904  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2905  tdm_api->wp_cmd.event.channel = (unsigned char)channel;
2906  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_BRI_CHAN_LOOPBACK;
2907  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_DISABLE;
2908  return sangoma_cmd_exec(fd, tdm_api);
2909 }
2910 
2912 {
2913  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2915  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
2916  tdm_api->wp_cmd.event.channel = (unsigned char)channel;
2917  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_BRI_CHAN_LOOPBACK;
2918  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
2919  return sangoma_cmd_exec(fd, tdm_api);
2920 }
2921 
2923 {
2924  int err;
2925 
2926  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2928  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_TX_Q_SIZE;
2929  tdm_api->wp_cmd.tx_queue_sz = 0;
2930 
2931  err=sangoma_cmd_exec(fd, tdm_api);
2932  if (err < 0) {
2933  return err;
2934  }
2935 
2936  return tdm_api->wp_cmd.tx_queue_sz;
2937 }
2938 
2940 {
2941  if (size < 0) {
2942  return -1;
2943  }
2944  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2946  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_TX_Q_SIZE;
2947  tdm_api->wp_cmd.tx_queue_sz = size;
2948  return sangoma_cmd_exec(fd, tdm_api);
2949 }
2950 
2952 {
2953  int err;
2954 
2955  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2957  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_RX_Q_SIZE;
2958  tdm_api->wp_cmd.rx_queue_sz = 0;
2959 
2960  err=sangoma_cmd_exec(fd, tdm_api);
2961  if (err < 0) {
2962  return err;
2963  }
2964 
2965  return tdm_api->wp_cmd.rx_queue_sz;
2966 
2967 }
2968 
2970 {
2971  if (size < 0) {
2972  return -1;
2973  }
2974 
2975  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2977  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_RX_Q_SIZE;
2978  tdm_api->wp_cmd.rx_queue_sz = size;
2979  return sangoma_cmd_exec(fd, tdm_api);
2980 }
2981 
2983 {
2984  int err;
2985 
2986  WANPIPE_API_INIT_CHAN(tdm_api, 0);
2989 
2990  err = sangoma_cmd_exec(fd, tdm_api);
2991  if (err == 0) {
2992  if (tdm_api->wp_cmd.data_len == sizeof(wan_driver_version_t)) {
2993  if (drv_ver) {
2994  memcpy(drv_ver,&tdm_api->wp_cmd.version,sizeof(wan_driver_version_t));
2995  }
2996  } else {
2997  return -1;
2998  }
2999  }
3000 
3001  return err;
3002 }
3003 
3005 {
3006  int err;
3007 
3008  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3011 
3012  err = sangoma_cmd_exec(fd, tdm_api);
3013  if (err == 0) {
3014  if (tdm_api->wp_cmd.data_len == sizeof(unsigned char)) {
3015  *ver = tdm_api->wp_cmd.data[0];
3016  } else {
3017  return -1;
3018  }
3019  }
3020 
3021  return err;
3022 }
3023 
3024 int _LIBSNG_CALL sangoma_get_cpld_version(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *ver)
3025 {
3026  int err;
3027 
3028  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3030  tdm_api->wp_cmd.cmd = WP_API_CMD_CPLD_VERSION;
3031 
3032  err = sangoma_cmd_exec(fd, tdm_api);
3033  if (err == 0) {
3034  if (tdm_api->wp_cmd.data_len == sizeof(unsigned char)) {
3035  *ver = tdm_api->wp_cmd.data[0];
3036  } else {
3037  return -1;
3038  }
3039  }
3040 
3041  return err;
3042 }
3043 
3044 int _LIBSNG_CALL sangoma_get_aft_customer_id(sng_fd_t fd, unsigned char *out_customer_id)
3045 {
3046  wan_udp_hdr_t wan_udp;
3047 
3048  memset(&wan_udp, 0x00, sizeof(wan_udp));
3049 
3050  wan_udp.wan_udphdr_command = WANPIPEMON_AFT_CUSTOMER_ID;
3051  wan_udp.wan_udphdr_return_code = SANG_STATUS_UNSUPPORTED_FUNCTION;
3052  wan_udp.wan_udphdr_data_len = 0;
3053 
3054  if (sangoma_mgmt_cmd(fd, &wan_udp)) {
3055  return SANG_STATUS_IO_ERROR;
3056  }
3057 
3058  if (wan_udp.wan_udphdr_return_code) {
3060  }
3061 
3062  *out_customer_id = sangoma_get_wan_udphdr_data_byte(&wan_udp, 0);
3063 
3064  return 0;
3065 }
3066 
3067 #ifdef WP_API_FEATURE_LED_CTRL
3068 int _LIBSNG_CALL sangoma_port_led_ctrl(sng_fd_t fd, unsigned char led_ctrl)
3069 {
3070  wan_udp_hdr_t wan_udp;
3071 
3072  memset(&wan_udp, 0x00, sizeof(wan_udp));
3073 
3074  wan_udp.wan_udphdr_command = WANPIPEMON_LED_CTRL;
3075  wan_udp.wan_udphdr_return_code = SANG_STATUS_UNSUPPORTED_FUNCTION;
3076  wan_udp.wan_udphdr_data_len = 1;
3077  wan_udp.wan_udphdr_data[0] = led_ctrl;
3078 
3079  if (sangoma_mgmt_cmd(fd, &wan_udp)) {
3080  return SANG_STATUS_IO_ERROR;
3081  }
3082 
3083  if (wan_udp.wan_udphdr_return_code) {
3085  }
3086 
3087  return 0;
3088 }
3089 #endif
3090 
3091 #ifdef WP_API_FEATURE_FE_RW
3092 int _LIBSNG_CALL sangoma_fe_reg_write(sng_fd_t fd, uint32_t offset, uint8_t data)
3093 {
3094  int chan=0;
3095  wan_udp_hdr_t wan_udp;
3096  sdla_fe_debug_t *fe_debug;
3097  memset(&wan_udp, 0x00, sizeof(wan_udp));
3098 
3099  {
3100  int err;
3101  wanpipe_api_t tdm_api;
3102  memset(&tdm_api,0,sizeof(tdm_api));
3103  err=sangoma_get_full_cfg(fd, &tdm_api);
3104  if (err) {
3105  return err;
3106  }
3107  chan=tdm_api.wp_cmd.chan;
3108  if (chan)
3109  chan--;
3110  }
3111 
3112  wan_udp.wan_udphdr_command = WAN_FE_SET_DEBUG_MODE;
3113  wan_udp.wan_udphdr_data_len = sizeof(sdla_fe_debug_t);
3114  wan_udp.wan_udphdr_return_code = 0xaa;
3115  fe_debug = (sdla_fe_debug_t*)wan_udp.wan_udphdr_data;
3116 
3117  fe_debug->type = WAN_FE_DEBUG_REG;
3118  fe_debug->mod_no = chan;
3119  fe_debug->fe_debug_reg.reg = offset;
3120  fe_debug->fe_debug_reg.value = data;
3121  fe_debug->fe_debug_reg.read = 0;
3122 
3123  if (sangoma_mgmt_cmd(fd, &wan_udp)) {
3124  return SANG_STATUS_IO_ERROR;
3125  }
3126 
3127  if (wan_udp.wan_udphdr_return_code) {
3129  }
3130 
3131  return 0;
3132 }
3133 
3134 int _LIBSNG_CALL sangoma_fe_reg_read(sng_fd_t fd, uint32_t offset, uint8_t *data)
3135 {
3136  int chan=0;
3137  wan_udp_hdr_t wan_udp;
3138  sdla_fe_debug_t *fe_debug;
3139  memset(&wan_udp, 0x00, sizeof(wan_udp));
3140 
3141  {
3142  int err;
3143  wanpipe_api_t tdm_api;
3144  memset(&tdm_api,0,sizeof(tdm_api));
3145  err=sangoma_get_full_cfg(fd, &tdm_api);
3146  if (err) {
3147  return err;
3148  }
3149  chan=tdm_api.wp_cmd.chan;
3150  if (chan)
3151  chan--;
3152  }
3153 
3154  wan_udp.wan_udphdr_command = WAN_FE_SET_DEBUG_MODE;
3155  wan_udp.wan_udphdr_data_len = sizeof(sdla_fe_debug_t);
3156  wan_udp.wan_udphdr_return_code = 0xaa;
3157  fe_debug = (sdla_fe_debug_t*)wan_udp.wan_udphdr_data;
3158 
3159  fe_debug->type = WAN_FE_DEBUG_REG;
3160  fe_debug->mod_no = chan;
3161  fe_debug->fe_debug_reg.reg = offset;
3162  fe_debug->fe_debug_reg.read = 1;
3163 
3164  if (sangoma_mgmt_cmd(fd, &wan_udp)) {
3165  return SANG_STATUS_IO_ERROR;
3166  }
3167 
3168  if (wan_udp.wan_udphdr_return_code) {
3170  }
3171 
3172  *data = fe_debug->fe_debug_reg.value;
3173 
3174  return 0;
3175 }
3176 #endif
3177 
3178 int _LIBSNG_CALL sangoma_analog_fxo_stats(sng_fd_t fd, uint8_t *data)
3179 {
3180  int chan=0;
3181  wan_remora_udp_t *rm_udp;
3182  wan_udp_hdr_t wan_udp;
3183 
3184  memset(&wan_udp, 0x00, sizeof(wan_udp));
3185 
3186  {
3187  int err;
3188  wanpipe_api_t tdm_api;
3189  memset(&tdm_api,0,sizeof(tdm_api));
3190  err=sangoma_get_full_cfg(fd, &tdm_api);
3191  if (err) {
3192  return err;
3193  }
3194  chan=tdm_api.wp_cmd.chan;
3195  if (chan)
3196  chan--;
3197  }
3198 
3199  rm_udp = (wan_remora_udp_t *)wan_udp.wan_udphdr_data;
3200  rm_udp->mod_no = chan;
3201  wan_udp.wan_udphdr_command = WAN_FE_STATS;
3202  wan_udp.wan_udphdr_return_code = 0xaa;
3203  wan_udp.wan_udphdr_data_len = sizeof(wan_remora_udp_t);
3204 
3205  if (sangoma_mgmt_cmd(fd, &wan_udp)) {
3206  return SANG_STATUS_IO_ERROR;
3207  }
3208 
3209  if (wan_udp.wan_udphdr_return_code) {
3211  }
3212 
3213 
3214  rm_udp = (wan_remora_udp_t *)wan_udp.wan_udphdr_data;
3215  if (rm_udp->type == MOD_TYPE_FXO){
3216  unsigned char volt = rm_udp->u.stats.volt;
3217  if (volt & 0x80){
3218  volt = ~volt + 1;
3219  }
3220  *data=volt;
3221  } else {
3222  return SANG_STATUS_IO_ERROR;
3223  }
3224 
3225  return 0;
3226 }
3227 
3228 int _LIBSNG_CALL sangoma_analog_fxs_stats(sng_fd_t fd, float *tip, float *ring, float *bat)
3229 {
3230  int chan=0;
3231  wan_remora_udp_t *rm_udp;
3232  wan_udp_hdr_t wan_udp;
3233 
3234  memset(&wan_udp, 0x00, sizeof(wan_udp));
3235  {
3236  int err;
3237  wanpipe_api_t tdm_api;
3238  memset(&tdm_api,0,sizeof(tdm_api));
3239  err=sangoma_get_full_cfg(fd, &tdm_api);
3240  if (err) {
3241  return err;
3242  }
3243  chan=tdm_api.wp_cmd.chan;
3244  if (chan)
3245  chan--;
3246  }
3247 
3248  rm_udp = (wan_remora_udp_t *)wan_udp.wan_udphdr_data;
3249  rm_udp->mod_no = chan;
3250  wan_udp.wan_udphdr_command = WAN_FE_STATS;
3251  wan_udp.wan_udphdr_return_code = 0xaa;
3252  wan_udp.wan_udphdr_data_len = sizeof(wan_remora_udp_t);
3253 
3254  if (sangoma_mgmt_cmd(fd, &wan_udp)) {
3255  return SANG_STATUS_IO_ERROR;
3256  }
3257 
3258  if (wan_udp.wan_udphdr_return_code) {
3260  }
3261 
3262 
3263  rm_udp = (wan_remora_udp_t *)wan_udp.wan_udphdr_data;
3264  if (rm_udp->type == MOD_TYPE_FXS){
3265  *tip=(float)(rm_udp->u.stats.tip_volt*376)/1000;
3266  *ring=(float)(rm_udp->u.stats.ring_volt*376)/1000;
3267  *bat=(float)(rm_udp->u.stats.bat_volt*376)/1000;
3268 #if 0
3269  printf("TIP\t: -%7.4f Volts\n", (float)(rm_udp->u.stats.tip_volt*376)/1000);
3270  printf("RING\t: -%7.4f Volts\n", (float)(rm_udp->u.stats.ring_volt*376)/1000);
3271  printf("VBAT\t: -%7.4f Volts\n", (float)(rm_udp->u.stats.bat_volt*376)/1000);
3272 #endif
3273  } else {
3274  return SANG_STATUS_IO_ERROR;
3275  }
3276 
3277  return 0;
3278 }
3279 
3280 
3282 {
3283  int err;
3284 
3285  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3287  tdm_api->wp_cmd.cmd = WP_API_CMD_GET_STATS;
3288 
3289  err = sangoma_cmd_exec(fd, tdm_api);
3290  if (err == 0) {
3291  if (stats) {
3292  memcpy(stats, &tdm_api->wp_cmd.stats, sizeof(wanpipe_chan_stats_t));
3293  }
3294  }
3295 
3296  return err;
3297 }
3298 
3300 {
3301  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3303  tdm_api->wp_cmd.cmd = WP_API_CMD_RESET_STATS;
3304  return sangoma_cmd_exec(fd, tdm_api);
3305 }
3306 
3308 {
3309  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3312  tdm_api->wp_cmd.rxflashtime=rxflashtime;
3313  return sangoma_cmd_exec(fd, tdm_api);
3314 }
3315 
3316 #ifdef WP_API_FEATURE_RM_GAIN
3318 {
3319  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3321  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
3322  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_SET_RM_TX_GAIN;
3323  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
3324  tdm_api->wp_cmd.event.wp_api_event_gain_value = value;
3325  return sangoma_cmd_exec(fd, tdm_api);
3326 }
3327 
3329 {
3330  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3332  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
3333  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_SET_RM_RX_GAIN;
3334  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
3335  tdm_api->wp_cmd.event.wp_api_event_gain_value = value;
3336  return sangoma_cmd_exec(fd, tdm_api);
3337 }
3338 #endif /* WP_API_FEATURE_RM_GAIN */
3339 
3340 int _LIBSNG_CALL sangoma_tdm_set_polarity(sng_fd_t fd, wanpipe_api_t *tdm_api, int polarity)
3341 {
3342  int err;
3343 
3344  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3346  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
3347  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_SETPOLARITY;
3348  tdm_api->wp_cmd.event.wp_api_event_polarity = polarity;
3349  err = sangoma_cmd_exec(fd, tdm_api);
3350  return err;
3351 
3352 }
3353 
3354 
3355 int _LIBSNG_CALL sangoma_tdm_txsig_onhooktransfer(sng_fd_t fd, wanpipe_api_t *tdm_api)
3356 {
3357  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3359  tdm_api->wp_cmd.cmd = WP_API_CMD_SET_EVENT;
3360  tdm_api->wp_cmd.event.wp_api_event_type = WP_API_EVENT_ONHOOKTRANSFER;
3361  tdm_api->wp_cmd.event.wp_api_event_mode = WP_API_EVENT_ENABLE;
3362  return sangoma_cmd_exec(fd,tdm_api);
3363 }
3364 
3365 #ifdef WP_API_FEATURE_LOOP
3366 
3368 {
3369  int err;
3370 
3371  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3373  tdm_api->wp_cmd.cmd = WP_API_CMD_ENABLE_LOOP;
3374  err = sangoma_cmd_exec(fd, tdm_api);
3375  return err;
3376 }
3377 
3379 {
3380  int err;
3381 
3382  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3384  tdm_api->wp_cmd.cmd = WP_API_CMD_DISABLE_LOOP;
3385  err = sangoma_cmd_exec(fd, tdm_api);
3386  return err;
3387 }
3388 
3389 #endif
3390 
3391 #ifdef WP_API_FEATURE_HWEC_PERSIST
3392 
3393 
3394 
3395 
3396 #endif
3397 
3398 
3399 #ifdef WP_API_FEATURE_SS7_FORCE_RX
3401 {
3402  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3404  tdm_api->wp_cmd.cmd = WP_API_CMD_SS7_FORCE_RX;
3405  return sangoma_cmd_exec(fd, tdm_api);
3406 }
3407 #endif
3408 
3409 #ifdef WP_API_FEATURE_SS7_CFG_STATUS
3411 {
3412  int err;
3413 
3414  WANPIPE_API_INIT_CHAN(tdm_api, 0);
3417 
3418  err = sangoma_cmd_exec(fd, tdm_api);
3419  if (err == 0) {
3420  if (ss7_cfg_status) {
3421  memcpy(ss7_cfg_status, &tdm_api->wp_cmd.ss7_cfg_status, sizeof(wan_api_ss7_cfg_status_t));
3422  }
3423  }
3424 
3425  return err;
3426 }
3427 #endif
3428 
3429 
3430 #endif /* WANPIPE_TDM_API */
sng_fd_t _LIBSNG_CALL __sangoma_open_api_span_chan(int span, int chan)
Open a Device based on Span/Chan values.
Definition: libsangoma.c:1740
sangoma_status_t _LIBSNG_CALL sangoma_logger_get_logger_level(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Get current level (types of events) of Wanpipe Logger.
Definition: libsangoma.c:2586
unsigned int rbs_rx_bits
int _LIBSNG_CALL sangoma_wait_obj_signal(sangoma_wait_obj_t *sng_wait_obj)
Set wait object to a signaled state.
Definition: libsangoma.c:1353
int _LIBSNG_CALL sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable RX HOOK Events (Analog Only)
Definition: libsangoma.c:2686
int _LIBSNG_CALL sangoma_tdm_enable_ring_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable RING Events (Analog Only)
Definition: libsangoma.c:2696
#define INVALID_HANDLE_VALUE
Invalid file handle value -1, Ported from Windows.
Definition: libsangoma.h:191
int _LIBSNG_CALL sangoma_flush_stats(sng_fd_t fd, wanpipe_api_t *tdm_api)
Flush/Reset device statistics.
Definition: libsangoma.c:3299
int _LIBSNG_CALL sangoma_get_full_cfg(sng_fd_t fd, wanpipe_api_t *tdm_api)
Read tdm api device configuration.
Definition: libsangoma.c:2026
unsigned char fe_status
unsigned int rxflashtime
#define FALSE
FALSE value is 0, Ported from Windows.
Definition: libsangoma.h:244
int _LIBSNG_CALL sangoma_disable_bri_bchan_loopback(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel)
Disable BRI Bchannel loopback - used when debugging bri device.
Definition: libsangoma.c:2900
#define _snprintf
_snprintf type mapped to snprintf, Ported from Windows
Definition: libsangoma.h:255
int _LIBSNG_CALL sangoma_get_driver_version(sng_fd_t fd, wanpipe_api_t *tdm_api, wan_driver_version_t *drv_ver)
Get Device Driver Version Number.
Definition: libsangoma.c:2982
int _LIBSNG_CALL sangoma_tdm_get_hwec_persist_status(sng_fd_t fd, wanpipe_api_t *tdm_api)
Check if hwec persis mode is on: On persist mode hwec is always enabled.
Definition: libsangoma.c:2254
int _LIBSNG_CALL sangoma_read_event(sng_fd_t fd, wanpipe_api_t *tdm_api)
Read API Events.
Definition: libsangoma.c:2426
enum _sangoma_wait_obj_type sangoma_wait_obj_type_t
Wait object type definition.
int _LIBSNG_CALL sangoma_port_led_ctrl(sng_fd_t fd, unsigned char led_ctrl)
Control the LED ligths of the TDM port. On (led set based on link status) Off (turn off all led)...
Definition: libsangoma.c:3068
sangoma_status_t _LIBSNG_CALL sangoma_logger_reset_statistics(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Reset Wanpipe Logger statistics.
Definition: libsangoma.c:2574
int _LIBSNG_CALL sangoma_mgmt_cmd(sng_fd_t fd, wan_udp_hdr_t *wan_udp)
Execute Sangoma Management Command.
unsigned int tx_queue_sz
int _LIBSNG_CALL sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable RX HOOK Events (Analog Only)
Definition: libsangoma.c:2676
u_int8_t operation_status
int _LIBSNG_CALL sangoma_set_rm_tx_gain(sng_fd_t fd, wanpipe_api_t *tdm_api, int value)
set tx gain for FXO/FXS module
Definition: libsangoma.c:3317
sng_fd_t _LIBSNG_CALL sangoma_wait_obj_get_fd(sangoma_wait_obj_t *sng_wait_obj)
Get fd device file descriptor which was the &#39;fd&#39; parameter for sangoma_wait_obj_create(), not useful for generic objects.
Definition: libsangoma.c:1382
Memory Descriptor of a single buffer. This structure used internally by libsangoma.
int _LIBSNG_CALL sangoma_get_aft_customer_id(sng_fd_t fd, unsigned char *out_customer_id)
Get Customer-specific ID from AFT hardware, the default value is 0xFF, any change requires special ar...
Definition: libsangoma.c:3044
int _LIBSNG_CALL sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get Tx/Rx Period in Milliseconds.
Definition: libsangoma.c:2142
u_int32_t poll_events_bitmap
int _LIBSNG_CALL sangoma_set_rx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api, int size)
Get Tx Queue Size for this channel.
Definition: libsangoma.c:2969
int _LIBSNG_CALL sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get Configured Power Level.
Definition: libsangoma.c:2313
int _LIBSNG_CALL sangoma_tdm_disable_loop(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable channel loop.
Definition: libsangoma.c:3378
int _LIBSNG_CALL sangoma_get_link_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
Get Device Link Status (Connected/Disconnected)
Definition: libsangoma.c:2876
int _LIBSNG_CALL sangoma_writemsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
Write Data to device.
Definition: libsangoma.c:1913
sng_fd_t _LIBSNG_CALL sangoma_open_api_ctrl(void)
Open a Global Control Device.
Definition: libsangoma.c:1750
unsigned int rx_queue_sz
int _LIBSNG_CALL sangoma_get_firmware_version(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *ver)
Get Hardware/Firmware Version.
Definition: libsangoma.c:3004
int _LIBSNG_CALL sangoma_cmd_exec(sng_fd_t fd, wanpipe_api_t *tdm_api)
Execute Sangoma API Command.
Definition: libsangoma.c:2004
unsigned int usr_mtu_mru
int _LIBSNG_CALL sangoma_tdm_txsig_onhook(sng_fd_t fd, wanpipe_api_t *tdm_api)
Tranmsmit TX SIG ON HOOK (Analog Only)
Definition: libsangoma.c:2776
int _LIBSNG_CALL sangoma_set_tx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api, int size)
Get Tx Queue Size for this channel.
Definition: libsangoma.c:2939
int _LIBSNG_CALL sangoma_interface_toi(char *interface_name, int *span, int *chan)
Convert Span &amp; Chan to interface name.
Definition: libsangoma.c:1577
unsigned int hw_tdm_coding
unsigned int rbs_poll
int _LIBSNG_CALL sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable DTMF Detection on Octasic chip (if hw supports it)
Definition: libsangoma.c:2636
int _LIBSNG_CALL sangoma_flush_event_bufs(sng_fd_t fd, wanpipe_api_t *tdm_api)
Flush only event buffers from current channel.
Definition: libsangoma.c:2353
int _LIBSNG_CALL sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable DTMF Detection on Analog/Remora SLIC Chip.
Definition: libsangoma.c:2666
int sng_fd_t
Windows/Unix file handle abstraction.
sangoma_status_t _LIBSNG_CALL sangoma_logger_get_open_handle_counter(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Get Counter of open Handles/File Descriptors of Wanpipe Logger.
Definition: libsangoma.c:2580
int _LIBSNG_CALL sangoma_tdm_disable_fax_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable FAX Detection on Octasic chip (if hw supports it)
Definition: libsangoma.c:2611
int _LIBSNG_CALL sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_api_t *tdm_api, int power)
Set Power Level - so only data matching the power level would be passed up.
Definition: libsangoma.c:2298
int _LIBSNG_CALL sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_api_t *tdm_api, int period)
Set Tx/Rx Period in Milliseconds.
Definition: libsangoma.c:2126
int _LIBSNG_CALL sangoma_flush_tx_bufs(sng_fd_t fd, wanpipe_api_t *tdm_api)
Flush only tx buffers from current channel.
Definition: libsangoma.c:2345
#define SANGOMA_INIT_TDM_API_CMD_RESULT(_name_)
Initialize the &#39;result&#39; in wanpipe_api_t to SANG_STATUS_GENERAL_ERROR.
Definition: libsangoma.h:104
int _LIBSNG_CALL sangoma_tdm_disable_ring_trip_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable RING TRIP Events (Analog Only)
Definition: libsangoma.c:2746
int HANDLE
file handle type int, Ported from Windows
Definition: libsangoma.h:258
int _LIBSNG_CALL sangoma_span_chan_fromif(char *interface_name, int *span, int *chan)
Convert Interace Name to Span &amp; Chan.
Definition: libsangoma.c:1640
wanpipe_api_cmd_t wp_cmd
u_int32_t msg_iovlen
sangoma_status_t _LIBSNG_CALL sangoma_logger_flush_buffers(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Flush Wanpipe Logger internal buffers.
Definition: libsangoma.c:2562
sng_fd_t _LIBSNG_CALL sangoma_open_api_span_chan(int span, int chan)
Open a Device based on Span/Chan values.
Definition: libsangoma.c:1682
unsigned int rx_disable
Wanpipe UDP Structure used for Maintenance and Debugging.
Definition: wanpipe_api.h:92
int _LIBSNG_CALL sangoma_get_rx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get Rx Queue Size for this channel.
Definition: libsangoma.c:2951
TDM API channel statistics.
int _LIBSNG_CALL sangoma_tdm_enable_ring_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable RING DETECT Events (Analog Only)
Definition: libsangoma.c:2716
int _LIBSNG_CALL sangoma_tdm_enable_tone_events(sng_fd_t fd, wanpipe_api_t *tdm_api, uint16_t tone_id)
Transmit a TONE on this device (Analog Only)
Definition: libsangoma.c:2796
int32_t sangoma_status_t
return status from sangoma APIs
Definition: libsangoma.h:338
int _LIBSNG_CALL sangoma_tdm_enable_ring_trip_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable RING TRIP Events (Analog Only)
Definition: libsangoma.c:2736
#define SDLA_DECODE_SANG_STATUS(status)
Print decode of Sangoma Return Codes.
int _LIBSNG_CALL sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable RBS Events for a device.
Definition: libsangoma.c:2370
wanpipe_api_callbacks_t wp_callback
int _LIBSNG_CALL sangoma_readmsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
Read Data from device.
Definition: libsangoma.c:1842
#define FNAME_LEN
string length of a file name
Definition: libsangoma.h:348
int _LIBSNG_CALL sangoma_set_rm_rxflashtime(sng_fd_t fd, wanpipe_api_t *tdm_api, int rxflashtime)
Set rxflashtime for FXS module Wink-Flash Event.
Definition: libsangoma.c:3307
int _LIBSNG_CALL sangoma_fe_reg_write(sng_fd_t fd, uint32_t offset, uint8_t data)
Write to a front end register.
Definition: libsangoma.c:3092
int _LIBSNG_CALL sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel, unsigned char rbs)
Write RBS Bits on a device.
Definition: libsangoma.c:2378
u_int32_t user_flags_bitmap
int _LIBSNG_CALL sangoma_tdm_get_hw_ec(sng_fd_t fd, wanpipe_api_t *tdm_api)
Check if hw echo cancelation support is available.
Definition: libsangoma.c:2205
unsigned int open_cnt
Wanpipe API Event Structure.
int _LIBSNG_CALL sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable DTMF Detection on Analog/Remora SLIC Chip.
Definition: libsangoma.c:2656
int _LIBSNG_CALL sangoma_tdm_read_rbs(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel, unsigned char *rbs)
Read RBS Bits on a device.
Definition: libsangoma.c:2387
sangoma_status_t _LIBSNG_CALL sangoma_wait_obj_create(sangoma_wait_obj_t **sangoma_wait_object, sng_fd_t fd, sangoma_wait_obj_type_t object_type)
Create a wait object that will be used with sangoma_waitfor_many() API.
Definition: libsangoma.c:1239
#define _LIBSNG_CALL
Not used in Linux.
Definition: libsangoma.h:185
u_int8_t channel
sangoma_status_t _LIBSNG_CALL sangoma_logger_get_statistics(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Get Wanpipe Logger statistics.
Definition: libsangoma.c:2568
int _LIBSNG_CALL sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable HWEC on this channel.
Definition: libsangoma.c:2819
int _LIBSNG_CALL sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable TONE Events (Analog Only)
Definition: libsangoma.c:2807
int _LIBSNG_CALL sangoma_interface_wait_up(int span, int chan, int sectimeout)
Wait for a sangoma device to come up (ie: Linux wait for /dev/wanpipex_1 to come up) ...
Definition: libsangoma.c:1608
int _LIBSNG_CALL sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get Configured TDM Codec per chan.
Definition: libsangoma.c:2103
int _LIBSNG_CALL sangoma_set_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char new_status)
Set Device Link Status (Connected/Disconnected)
Definition: libsangoma.c:2890
int _LIBSNG_CALL sangoma_tdm_get_hw_dtmf(sng_fd_t fd, wanpipe_api_t *tdm_api)
Check if hwdtmf support is available.
Definition: libsangoma.c:2185
Fixed-length List of Memory Descriptors.
unsigned int fe_alarms
int _LIBSNG_CALL sangoma_get_hw_coding(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get HW Voice Coding (ulaw/alaw)
Definition: libsangoma.c:2164
int _LIBSNG_CALL sangoma_tdm_get_hwec_chan_status(sng_fd_t fd, wanpipe_api_t *tdm_api)
Check if hw echo cancelation is enabled on current timeslot.
Definition: libsangoma.c:2228
Variable-length List of Memory Descriptors.
unsigned int hw_mtu_mru
int _LIBSNG_CALL sangoma_tdm_txsig_offhook(sng_fd_t fd, wanpipe_api_t *tdm_api)
Tranmsmit TX SIG OFF HOOK (Analog Only)
Definition: libsangoma.c:2786
wan_iovec_t *WP_POINTER_64 msg_iov
int _LIBSNG_CALL sangoma_get_fe_status(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *current_status)
Get Device Link Status (Connected/Disconnected)
Definition: libsangoma.c:2860
int _LIBSNG_CALL sangoma_tdm_disable_ring_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable RING Events (Analog Only)
Definition: libsangoma.c:2706
int _LIBSNG_CALL sangoma_get_open_cnt(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get device open count.
Definition: libsangoma.c:1762
char TCHAR
TCHAN type mapped to char, Ported from Windows.
Definition: libsangoma.h:260
sangoma_status_t _LIBSNG_CALL sangoma_logger_set_logger_level(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Set current level (types of events) of Wanpipe Logger.
Definition: libsangoma.c:2592
deprecated, use SANGOMA_GENERIC_WAIT_OBJ
Definition: libsangoma.h:367
int _LIBSNG_CALL sangoma_tdm_disable_ring_detect_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable RING DETECT Events (Analog Only)
Definition: libsangoma.c:2726
int DWORD
DWORD type is int, Ported from Windows.
Definition: libsangoma.h:259
int _LIBSNG_CALL sangoma_get_stats(sng_fd_t fd, wanpipe_api_t *tdm_api, wanpipe_chan_stats_t *stats)
Get Device Statistics. Statistics will be available in tdm_api-&gt;wp_cmd.stats structure.
Definition: libsangoma.c:3281
unsigned char chan
int _LIBSNG_CALL sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_api_t *tdm_api, int codec)
Set TDM Codec per chan.
Definition: libsangoma.c:2082
wp_api_event_t event
Wanpipe API Command Structure.
Windows poll structure used to implement blocking poll for read/write/event.
int _LIBSNG_CALL sangoma_span_chan_toif(int span, int chan, char *interface_name)
Convert Span &amp; Chan to interface name.
Definition: libsangoma.c:1566
int _LIBSNG_CALL sangoma_enable_bri_bchan_loopback(sng_fd_t fd, wanpipe_api_t *tdm_api, int channel)
Enable BRI Bchannel loopback - used when debugging bri device.
Definition: libsangoma.c:2911
int _LIBSNG_CALL sangoma_tdm_txsig_kewl(sng_fd_t fd, wanpipe_api_t *tdm_api)
Tranmsmit TX SIG KEWL START (Analog Only)
Definition: libsangoma.c:2756
sangoma_status_t _LIBSNG_CALL sangoma_wait_obj_delete(sangoma_wait_obj_t **sangoma_wait_object)
De-allocate all resources in a wait object.
Definition: libsangoma.c:1320
void _LIBSNG_CALL sangoma_close(sng_fd_t *fd)
Close device file descriptor.
Definition: libsangoma.c:1818
int _LIBSNG_CALL sangoma_get_tx_queue_sz(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get Tx Queue Size for this channel.
Definition: libsangoma.c:2922
#define WP_API_EVENT_ENABLE
Option to enable command.
unsigned int rbs_tx_bits
sng_fd_t _LIBSNG_CALL sangoma_open_dev_by_name(const char *dev_name)
Open API device using it&#39;s name. For example: Linux: w1g1, Windows wanpipe1_if1.
Definition: libsangoma.c:1717
int _LIBSNG_CALL sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned int *alarms)
Get Front End Alarms (T1/E1 Only)
Definition: libsangoma.c:2841
int _LIBSNG_CALL sangoma_ss7_force_rx(sng_fd_t fd, wanpipe_api_t *tdm_api)
Force the firmware to pass up a repeating frame.
Definition: libsangoma.c:3400
PVOID _LIBSNG_CALL sangoma_wait_obj_get_context(sangoma_wait_obj_t *sng_wait_obj)
Retrieve the user context (if any) that was set via sangoma_wait_obj_set_context. ...
Definition: libsangoma.c:1406
sng_fd_t _LIBSNG_CALL sangoma_logger_open(void)
Open a Global Logger Device.
Definition: libsangoma.c:1756
#define WP_INTERFACE_NAME_FORM
String define of a wanpipe interface name.
wanpipe_chan_stats_t stats
unsigned int tx_disable
int _LIBSNG_CALL sangoma_tdm_enable_fax_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable FAX Detection on Octasic chip (if hw supports it)
Definition: libsangoma.c:2601
sng_fd_t _LIBSNG_CALL sangoma_create_socket_by_name(char *device, char *card)
Open a device based on a interface and card name.
Definition: libsangoma.c:1778
int _LIBSNG_CALL sangoma_tdm_enable_loop(sng_fd_t fd, wanpipe_api_t *tdm_api)
Enable channel loop: All rx data will be transmitted back out.
Definition: libsangoma.c:3367
int _LIBSNG_CALL sangoma_tdm_txsig_start(sng_fd_t fd, wanpipe_api_t *tdm_api)
Tranmsmit TX SIG START (Analog Only)
Definition: libsangoma.c:2766
#define TRUE
TRUE value is 1, Ported from Windows.
Definition: libsangoma.h:248
unsigned int usr_period
int _LIBSNG_CALL sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_api_t *tdm_api, int poll_in_sec)
Enable RBS Events on a device.
Definition: libsangoma.c:2361
unsigned int tdm_codec
Wanpipe API Header Structure.
sangoma_status_t _LIBSNG_CALL sangoma_logger_read_event(sng_fd_t fd, wp_logger_cmd_t *logger_cmd)
Read Wanpipe Logger Events.
Definition: libsangoma.c:2556
#define WP_API_EVENT_DISABLE
Option to disable command.
int _LIBSNG_CALL sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get Tx/Rx MTU/MRU in bytes.
Definition: libsangoma.c:2276
u_int16_t data_length
int _LIBSNG_CALL sangoma_tdm_get_hw_fax(sng_fd_t fd, wanpipe_api_t *tdm_api)
Get HW FAX Detection State (Enable or Disabled) on Octasic chip (if hw supports it) ...
Definition: libsangoma.c:2621
unsigned char operation_status
int _LIBSNG_CALL sangoma_tdm_set_buffer_multiplier(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned int multiplier)
Set voice tx/rx buffer multiplier.
Definition: libsangoma.c:2406
int _LIBSNG_CALL sangoma_fe_reg_read(sng_fd_t fd, uint32_t offset, uint8_t *data)
Read front end register.
Definition: libsangoma.c:3134
int _LIBSNG_CALL sangoma_ss7_get_cfg_status(sng_fd_t fd, wanpipe_api_t *tdm_api, wan_api_ss7_cfg_status_t *ss7_cfg_status)
Get current ss7 hw configuration.
Definition: libsangoma.c:3410
unsigned int idle_flag
wan_iovec_t iovec_list[WAN_IOVEC_LIST_LEN]
int _LIBSNG_CALL sangoma_get_cpld_version(sng_fd_t fd, wanpipe_api_t *tdm_api, unsigned char *ver)
Get AFT CPLD Version.
Definition: libsangoma.c:3024
int _LIBSNG_CALL sangoma_flush_bufs(sng_fd_t fd, wanpipe_api_t *tdm_api)
Flush all (tx/rx/event) buffers from current channel.
Definition: libsangoma.c:2329
unsigned int hw_dtmf
int _LIBSNG_CALL sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable HWEC on this channel.
Definition: libsangoma.c:2827
int _LIBSNG_CALL sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_api_t *tdm_api)
Disable DTMF Detection on Octasic chip (if hw supports it)
Definition: libsangoma.c:2646
int _LIBSNG_CALL sangoma_set_rm_rx_gain(sng_fd_t fd, wanpipe_api_t *tdm_api, int value)
set rx gain for FXO/FXS module
Definition: libsangoma.c:3328
int _LIBSNG_CALL sangoma_flush_rx_bufs(sng_fd_t fd, wanpipe_api_t *tdm_api)
Flush only rx buffers from current channel.
Definition: libsangoma.c:2337
struct wp_api_hdr wp_api_hdr_t
Wanpipe API Header Structure.
unsigned int power_level