libsangoma  1
sample.c
Go to the documentation of this file.
1 /******************************************************************************/
35 #include "libsangoma.h"
36 #include "lib_api.h"
37 
38 static u_int32_t poll_events_bitmap = 0;
39 
50 #define TEST_NUMBER_OF_OBJECTS 1
51 
52 static sangoma_wait_obj_t *sangoma_wait_objects[TEST_NUMBER_OF_OBJECTS];
53 
54 /* This example application has only a single execution thread - it is safe
55  * to use a global buffer for received data and for data to be transmitted. */
56 static unsigned char rxdata[MAX_NO_DATA_BYTES_IN_FRAME];
57 static unsigned char txdata[MAX_NO_DATA_BYTES_IN_FRAME];
58 
59 typedef struct sangoma_chan {
60  int spanno;
61  int channo;
63 sangoma_chan_t sangoma_channels[TEST_NUMBER_OF_OBJECTS];
64 
65 /* Warning: non-thread safe globals. Ok for this single-thread example but not in production. */
66 unsigned char rx_rbs_bits = WAN_RBS_SIG_A;
67 FILE *pRxFile;
68 int application_termination_flag = 0;
69 
70 /*****************************************************************
71  * Prototypes
72  *****************************************************************/
73 
74 int __cdecl main(int argc, char* argv[]);
75 int open_sangoma_device(void);
76 void handle_span_chan(int open_device_counter);
77 int handle_tdm_event(uint32_t dev_index);
78 int handle_data(uint32_t dev_index, int flags_out);
79 int read_data(uint32_t dev_index, wp_api_hdr_t *rx_hdr, void *rx_buffer, int rx_buffer_length);
80 int write_data(uint32_t dev_index, wp_api_hdr_t *tx_hdr, void *tx_buffer, int tx_len);
81 int dtmf_event(sng_fd_t fd,unsigned char digit,unsigned char type,unsigned char port);
82 int rbs_event(sng_fd_t fd,unsigned char rbs_bits);
83 int rxhook_event(sng_fd_t fd,unsigned char hook_state);
84 int rxring_event(sng_fd_t fd,unsigned char ring_state);
85 int ringtrip_event (sng_fd_t fd, unsigned char ring_state);
86 int write_data_to_file(unsigned char *data, unsigned int data_length);
87 int sangoma_print_stats(sng_fd_t sangoma_dev);
88 void cleanup(void);
89 int handle_fe_rw (void);
90 
91 #ifdef __WINDOWS__
92 BOOL WINAPI TerminateHandler(DWORD dwCtrlType);
93 #else
94 void TerminateHandler(int);
95 #endif
96 
97 /*****************************************************************
98  * General Functions
99  *****************************************************************/
100 
108 void print_rxdata(unsigned char *data, int datalen, wp_api_hdr_t *hdr); /* dont remove prototype, gcc complains */
109 void print_rxdata(unsigned char *data, int datalen, wp_api_hdr_t *hdr)
110 {
111  int i;
112  int err=0;
113 
114 #ifdef WP_API_FEATURE_RX_TX_ERRS
115  err=hdr->wp_api_rx_hdr_errors;
116 #endif
117  printf("Data: (Len=%i,Errs=%i)\n",datalen,err);
118  for(i = 0; i < datalen; i++) {
119  if((i % 20 == 0)){
120  if(i){
121  printf("\n");
122  }
123  }
124  printf("%02X ", data[i]);
125 #if 0
126  /* don't print too much!! */
127  if(i > 100){
128  printf("...\n");
129  break;
130  }
131 #endif
132  }
133  printf("\n");
134 }
135 
136 
137 int sangoma_print_stats(sng_fd_t sangoma_dev)
138 {
139  int err;
140  unsigned char firm_ver, cpld_ver;
141  wanpipe_api_t wp_api;
142  wanpipe_chan_stats_t stats_str;
143  wanpipe_chan_stats_t *stats=&stats_str;
144  memset(&wp_api,0,sizeof(wp_api));
145 
146 
147  err=sangoma_get_stats(sangoma_dev, &wp_api, stats);
148  if (err) {
149  printf("sangoma_get_stats(() failed (err: %d (0x%X))!\n", err, err);
150  return 1;
151  }
152 
153  printf( "******* OPERATIONAL_STATS *******\n");
154 
155  printf("\trx_packets\t: %u\n", stats->rx_packets);
156  printf("\ttx_packets\t: %u\n", stats->tx_packets);
157  printf("\trx_bytes\t: %u\n", stats->rx_bytes);
158  printf("\ttx_bytes\t: %u\n", stats->tx_bytes);
159  printf("\trx_errors\t: %u\n", stats->rx_errors); //Total number of Rx errors
160  printf("\ttx_errors\t: %u\n", stats->tx_errors); //Total number of Tx errors
161  printf("\trx_dropped\t: %u\n", stats->rx_dropped);
162  printf("\ttx_dropped\t: %u\n", stats->tx_dropped);
163  printf("\tmulticast\t: %u\n", stats->multicast);
164  printf("\tcollisions\t: %u\n", stats->collisions);
165 
166  printf("\trx_length_errors: %u\n", stats->rx_length_errors);
167  printf("\trx_over_errors\t: %u\n", stats->rx_over_errors);
168  printf("\trx_crc_errors\t: %u\n", stats->rx_crc_errors); //HDLC CRC mismatch
169  printf("\trx_frame_errors\t: %u\n", stats->rx_frame_errors);//HDLC "abort" occured
170  printf("\trx_fifo_errors\t: %u\n", stats->rx_fifo_errors);
171  printf("\trx_missed_errors: %u\n", stats->rx_missed_errors);
172 
173  printf("\ttx_aborted_errors: %u\n", stats->tx_aborted_errors);
174  printf("\tTx Idle Data\t: %u\n", stats->tx_carrier_errors);
175 
176  printf("\ttx_fifo_errors\t: %u\n", stats->tx_fifo_errors);
177  printf("\ttx_heartbeat_errors: %u\n", stats->tx_heartbeat_errors);
178  printf("\ttx_window_errors: %u\n", stats->tx_window_errors);
179 
180  printf("\n\ttx_packets_in_q: %u\n", stats->current_number_of_frames_in_tx_queue);
181  printf("\ttx_queue_size: %u\n", stats->max_tx_queue_length);
182 
183  printf("\n\trx_packets_in_q: %u\n", stats->current_number_of_frames_in_rx_queue);
184  printf("\trx_queue_size: %u\n", stats->max_rx_queue_length);
185 
186  printf("\n\trx_events_in_q: %u\n", stats->current_number_of_events_in_event_queue);
187  printf("\trx_event_queue_size: %u\n", stats->max_event_queue_length);
188  printf("\trx_events: %u\n", stats->rx_events);
189  printf("\trx_events_dropped: %u\n", stats->rx_events_dropped);
190 
191  printf("\tHWEC tone (DTMF) events counter: %u\n", stats->rx_events_tone);
192  printf( "*********************************\n");
193 
194  SANGOMA_INIT_TDM_API_CMD(wp_api);
195  err=sangoma_get_driver_version(sangoma_dev,&wp_api, NULL);
196  if (err) {
197  return 1;
198  }
199  printf("\tDriver Version: %u.%u.%u.%u\n",
200  wp_api.wp_cmd.version.major,
201  wp_api.wp_cmd.version.minor,
202  wp_api.wp_cmd.version.minor1,
203  wp_api.wp_cmd.version.minor2);
204 
205  SANGOMA_INIT_TDM_API_CMD(wp_api);
206  err=sangoma_get_firmware_version(sangoma_dev, &wp_api, &firm_ver);
207  if (err) {
208  return 1;
209  }
210  printf("\tFirmware Version: %X\n",
211  firm_ver);
212 
213  SANGOMA_INIT_TDM_API_CMD(wp_api);
214  err=sangoma_get_cpld_version(sangoma_dev, &wp_api, &cpld_ver);
215  if (err) {
216  return 1;
217  }
218  printf("\tCPLD Version: %X\n",
219  cpld_ver);
220 
221  return 0;
222 }
223 
233 int read_data(uint32_t dev_index, wp_api_hdr_t *rx_hdr, void *rx_buffer, int rx_buffer_length)
234 {
235  sng_fd_t dev_fd = sangoma_wait_obj_get_fd(sangoma_wait_objects[dev_index]);
236  sangoma_chan_t *chan = sangoma_wait_obj_get_context(sangoma_wait_objects[dev_index]);
237  int Rx_lgth = 0;
238  static int Rx_count= 0;
239  wanpipe_api_t tdm_api;
240 
241  memset(&tdm_api, 0x00, sizeof(tdm_api));
242  memset(rx_hdr, 0, sizeof(wp_api_hdr_t));
243 
244  /* read the message */
245  Rx_lgth = sangoma_readmsg(
246  dev_fd,
247  rx_hdr, /* header buffer */
248  sizeof(wp_api_hdr_t), /* header size */
249  rx_buffer, /* data buffer */
250  rx_buffer_length, /* data BUFFER size */
251  0);
252  if(Rx_lgth <= 0) {
253  printf("Span: %d, Chan: %d: Error receiving data!\n",
254  chan->spanno, chan->channo);
255  return 1;
256  }
257 
258 
259 #ifdef WP_API_FEATURE_RX_TX_ERRS
260  if (rx_hdr->wp_api_rx_hdr_error_map) {
261  if (rx_hdr->wp_api_rx_hdr_error_map & 1<<WP_FIFO_ERROR_BIT) {
262  printf("Span: %d, Chan: %d rx fifo error 0x%02X\n",chan->spanno,chan->channo,rx_hdr->wp_api_rx_hdr_error_map);
263  }
264  if (rx_hdr->wp_api_rx_hdr_error_map & 1<<WP_CRC_ERROR_BIT) {
265  printf("Span: %d, Chan: %d rx crc error 0x%02X\n",chan->spanno,chan->channo,rx_hdr->wp_api_rx_hdr_error_map);
266  }
267  if (rx_hdr->wp_api_rx_hdr_error_map & 1<<WP_ABORT_ERROR_BIT) {
268  printf("Span: %d, Chan: %d rx abort error 0x%02X\n",chan->spanno,chan->channo,rx_hdr->wp_api_rx_hdr_error_map);
269  }
270  if (rx_hdr->wp_api_rx_hdr_error_map & 1<<WP_FRAME_ERROR_BIT) {
271  printf("Span: %d, Chan: %d rx framing error 0x%02X\n",chan->spanno,chan->channo,rx_hdr->wp_api_rx_hdr_error_map);
272  }
273  if (rx_hdr->wp_api_rx_hdr_error_map & 1<<WP_DMA_ERROR_BIT) {
274  printf("Span: %d, Chan: %d rx dma error 0x%02X\n",chan->spanno,chan->channo,rx_hdr->wp_api_rx_hdr_error_map);
275  }
276  //return 1;
277  }
278 #endif
279 
280  Rx_count++;
281 
282  if (verbose){
283  print_rxdata(rx_buffer, Rx_lgth,rx_hdr);
284  }
285 
286  if (stats_period && Rx_count % stats_period == 0) {
287  sangoma_print_stats(dev_fd);
288  }
289 
290  /* use Rx_counter as "write" events trigger: */
291  if(rbs_events == 1 && (Rx_count % 400) == 0){
292  /* bitmap - set as needed: WAN_RBS_SIG_A | WAN_RBS_SIG_B | WAN_RBS_SIG_C | WAN_RBS_SIG_D;
293 
294  In this example make bits A and B to change each time,
295  so it's easy to see the change on the receiving side.
296  */
297  if(rx_rbs_bits == WAN_RBS_SIG_A){
298  rx_rbs_bits = WAN_RBS_SIG_B;
299  }else{
300  rx_rbs_bits = WAN_RBS_SIG_A;
301  }
302  printf("Writing RBS bits (0x%X)...\n", rx_rbs_bits);
303  sangoma_tdm_write_rbs(dev_fd, &tdm_api,
304  chan->channo,
305  rx_rbs_bits);
306  }
307 
308  /* if user needs Rx data to be written into a file: */
309  if(files_used & RX_FILE_USED){
310  write_data_to_file(rx_buffer, Rx_lgth);
311  }
312 
313  return 0;
314 }
315 
325 int write_data(uint32_t dev_index, wp_api_hdr_t *tx_hdr, void *tx_buffer, int tx_len)
326 {
327  sng_fd_t dev_fd = sangoma_wait_obj_get_fd(sangoma_wait_objects[dev_index]);
328  sangoma_chan_t *chan = sangoma_wait_obj_get_context(sangoma_wait_objects[dev_index]);
329  int err;
330  static int Tx_count = 0;
331 
332  if (hdlc_repeat) {
333  if (verbose){
334  printf("Repeating Frame\n");
335  }
336  tx_hdr->wp_api_tx_hdr_hdlc_rpt_len=4;
337  memset(tx_hdr->wp_api_tx_hdr_hdlc_rpt_data,Tx_count,4);
338  }
339 
340  /* write a message */
341  err = sangoma_writemsg(
342  dev_fd,
343  tx_hdr, /* header buffer */
344  sizeof(wp_api_hdr_t), /* header size */
345  tx_buffer, /* data buffer */
346  tx_len, /* DATA size */
347  0);
348 
349  if (err <= 0){
350  printf("Span: %d, Chan: %d: Failed to send %s!\n",
351  chan->spanno,
352  chan->channo, strerror(errno));
353  return -1;
354  }
355 
356  Tx_count++;
357  if (verbose){
358  printf("Packet sent: counter: %i, len: %i, errors %i\n", Tx_count, err, tx_hdr->wp_api_tx_hdr_errors);
359  }else{
360  if(Tx_count && (!(Tx_count % 1000))){
361  printf("Packet sent: counter: %i, len: %i\n", Tx_count, err);
362  }
363  }
364 
365  if (tx_delay) {
366  sangoma_msleep(tx_delay);
367  }
368 
369 #if 1
370  if(tx_cnt && Tx_count >= tx_cnt){
371  write_enable=0;
372  printf("Disabling POLLOUT...\n");
373  /* No need for POLLOUT, turn it off!! If not turned off, and we
374  * have nothing for transmission, sangoma_socket_waitfor() will return
375  * immediately, creating a busy loop. */
376  //sangoma_wait_objects[dev_index].flags_in &= (~POLLOUT);
377  return 0;
378  }
379 #endif
380  return 0;
381 }
382 
391 int handle_data(uint32_t dev_index, int flags_out)
392 {
393  wp_api_hdr_t rxhdr;
394  int err=0;
395 
396  memset(&rxhdr, 0, sizeof(rxhdr));
397 
398 #if 0
399  printf("%s(): span: %d, chan: %d\n", __FUNCTION__,
400  sangoma_wait_objects[dev_index].span, sangoma_wait_objects[dev_index].chan);
401 #endif
402 
403  if(flags_out & POLLIN){
404  if(read_data(dev_index, &rxhdr, rxdata, MAX_NO_DATA_BYTES_IN_FRAME) == 0){
405  if(rx2tx){
406  /* Send back received data (create a "software loopback"), just a test. */
407  return write_data(dev_index, &rxhdr, rxdata,rxhdr.data_length);
408  }
409  }
410  }
411 
412  if( (flags_out & POLLOUT) && write_enable ){
413 
414  wp_api_hdr_t txhdr;
415  static unsigned char tx_test_byte = 2;
416 
417  memset(&txhdr, 0, sizeof(txhdr));
418  txhdr.data_length = (unsigned short)tx_size;/* use '-txsize' command line option to change 'tx_size' */
419 
420  /* set data which will be transmitted */
421  memset(txdata, tx_test_byte, txhdr.data_length);
422 
423  err = write_data(dev_index, &txhdr, txdata, tx_size);
424  if (err== 0) {
425  //tx_test_byte++;
426  }
427  }
428  return err;
429 }
430 
436 static void decode_api_event(wp_api_event_t *wp_tdm_api_event)
437 {
438  printf("%s(): span: %d, chan: %d\n", __FUNCTION__,
439  wp_tdm_api_event->span, wp_tdm_api_event->channel);
440 
441  switch(wp_tdm_api_event->wp_api_event_type)
442  {
443  case WP_API_EVENT_DTMF:/* DTMF detected by Hardware */
444  printf("DTMF Event: Channel: %d, Digit: %c (Port: %s, Type:%s)!\n",
445  wp_tdm_api_event->channel,
446  wp_tdm_api_event->wp_api_event_dtmf_digit,
447  (wp_tdm_api_event->wp_api_event_dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT",
448  (wp_tdm_api_event->wp_api_event_dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP");
449  break;
450 
451  case WP_API_EVENT_RXHOOK:
452  printf("RXHOOK Event: Channel: %d, %s! (0x%X)\n",
453  wp_tdm_api_event->channel,
454  WAN_EVENT_RXHOOK_DECODE(wp_tdm_api_event->wp_api_event_hook_state),
455  wp_tdm_api_event->wp_api_event_hook_state);
456  break;
457 
458  case WP_API_EVENT_RING_DETECT:
459  printf("RING Event: %s! (0x%X)\n",
460  WAN_EVENT_RING_DECODE(wp_tdm_api_event->wp_api_event_ring_state),
461  wp_tdm_api_event->wp_api_event_ring_state);
462  break;
463 
464  case WP_API_EVENT_RING_TRIP_DETECT:
465  printf("RING TRIP Event: %s! (0x%X)\n",
466  WAN_EVENT_RING_TRIP_DECODE(wp_tdm_api_event->wp_api_event_ring_state),
467  wp_tdm_api_event->wp_api_event_ring_state);
468  break;
469 
470  case WP_API_EVENT_RBS:
471  printf("RBS Event: Channel: %d, 0x%X!\n",
472  wp_tdm_api_event->channel,
473  wp_tdm_api_event->wp_api_event_rbs_bits);
474  printf( "RX RBS: A:%1d B:%1d C:%1d D:%1d\n",
475  (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_A) ? 1 : 0,
476  (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_B) ? 1 : 0,
477  (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_C) ? 1 : 0,
478  (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_D) ? 1 : 0);
479  break;
480 
481  case WP_API_EVENT_LINK_STATUS:
482  printf("Link Status Event: %s! (0x%X)\n",
483  WAN_EVENT_LINK_STATUS_DECODE(wp_tdm_api_event->wp_api_event_link_status),
484  wp_tdm_api_event->wp_api_event_link_status);
485  break;
486 
487  case WP_API_EVENT_ALARM:
488  printf("New Alarm State: %s! (0x%X)\n", (wp_tdm_api_event->wp_api_event_alarm == 0?"Off":"On"),
489  wp_tdm_api_event->wp_api_event_alarm);
490  break;
491 
492  case WP_API_EVENT_POLARITY_REVERSE:
493  printf("Polarity Reversal Event : %s! (0x%X)\n",
494  WP_API_EVENT_POLARITY_REVERSE_DECODE(wp_tdm_api_event->wp_api_event_polarity_reverse),
495  wp_tdm_api_event->wp_api_event_polarity_reverse);
496  break;
497 
498  default:
499  printf("Unknown TDM API Event: %d\n", wp_tdm_api_event->wp_api_event_type);
500  break;
501  }
502 }
503 
513 int handle_tdm_event(uint32_t dev_index)
514 {
515  wanpipe_api_t tdm_api;
516  sng_fd_t dev_fd = sangoma_wait_obj_get_fd(sangoma_wait_objects[dev_index]);
517 
518 #if 0
519  printf("%s(): dev_index: %d, dev_fd: 0x%p\n", __FUNCTION__, dev_index, dev_fd);
520 #endif
521 
522  memset(&tdm_api, 0x00, sizeof(tdm_api));
523 
524  if(sangoma_read_event(dev_fd, &tdm_api)){
525  return 1;
526  }
527 
528  decode_api_event(&tdm_api.wp_cmd.event);
529  return 0;
530 }
531 
532 
533 int handle_fe_rw (void)
534 {
535  sng_fd_t dev_fd = sangoma_wait_obj_get_fd(sangoma_wait_objects[0]);
536  uint8_t data=0;
537  int err;
538 
539  if (fe_read_cmd) {
540  err=sangoma_fe_reg_read(dev_fd,fe_read_reg,&data);
541  if (err) {
542  fprintf(stderr,"Error, sangoma_fe_reg_read failed %i\n",err);
543  return err;
544  }
545 
546  printf("FE READ Reg=0x%04X Data=%02X\n", fe_read_reg,data);
547  }
548 
549  if (fe_write_cmd) {
550 
551  printf("FE WRITE Reg=0x%04X Data=%02X\n", fe_write_reg,fe_write_data);
552 
553  err=sangoma_fe_reg_write(dev_fd,fe_write_reg,fe_write_data);
554  if (err) {
555  fprintf(stderr,"Error, sangoma_fe_reg_write failed %i\n",err);
556  return err;
557  }
558 
559  }
560 
561  return 0;
562 }
563 
564 
576 void handle_span_chan(int open_device_counter)
577 {
578  int iResult, i;
579  u_int32_t input_flags[TEST_NUMBER_OF_OBJECTS];
580  u_int32_t output_flags[TEST_NUMBER_OF_OBJECTS];
581 
582  printf("\n\nSpan/Chan Handler: RxEnable=%s, TxEnable=%s, TxCnt=%i, TxLen=%i, rx2tx=%s\n",
583  (read_enable? "Yes":"No"), (write_enable?"Yes":"No"),tx_cnt,tx_size, (rx2tx?"Yes":"No"));
584 
585  for (i = 0; i < open_device_counter; i++) {
586  input_flags[i] = poll_events_bitmap;
587  }
588 
589  /* Main Rx/Tx/Event loop */
590  while(!application_termination_flag)
591  {
592  iResult = sangoma_waitfor_many(sangoma_wait_objects,
593  input_flags,
594  output_flags,
595  open_device_counter /* number of wait objects */,
596  5000 /* wait timeout, in milliseconds */);
597  switch(iResult)
598  {
600  /* timeout (not an error) */
601  {
602  sng_fd_t dev_fd = sangoma_wait_obj_get_fd(sangoma_wait_objects[0]);
603  sangoma_print_stats(dev_fd);
604  }
605  printf("Timeout\n");
606  continue;
607 
608  case SANG_STATUS_SUCCESS:
609  for(i = 0; i < open_device_counter; i++){
610 
611  /* a wait object was signaled */
612  if(output_flags[i] & POLLPRI){
613  /* got tdm api event */
614  if(handle_tdm_event(i)){
615  printf("Error in handle_tdm_event()!\n");
616  application_termination_flag=1;
617  break;
618  }
619  }
620 
621  if(output_flags[i] & (POLLIN | POLLOUT)){
622  /* rx data OR a free tx buffer available */
623  if(handle_data(i, output_flags[i])){
624  printf("Error in handle_data()!\n");
625  //application_termination_flag=1;
626  break;
627  }
628  }
629  }/* for() */
630  break;
631 
632  default:
633  /* error */
634  printf("Error: iResult: %s (%d)\n", SDLA_DECODE_SANG_STATUS(iResult), iResult);
635  return;
636  }
637 
638  }/* while() */
639 }
640 
649 int write_data_to_file(unsigned char *data, unsigned int data_length)
650 {
651  if(pRxFile == NULL){
652  return 1;
653  }
654 
655  return fwrite(data, 1, data_length, pRxFile);
656 }
657 
658 #ifdef __WINDOWS__
659 /*
660  * TerminateHandler() - this handler is called by the system whenever user tries to terminate
661  * the process with Ctrl+C, Ctrl+Break or closes the console window.
662  * Perform a clean-up here.
663  */
664 BOOL TerminateHandler(DWORD dwCtrlType)
665 {
666  printf("\nProcess terminated by user request.\n");
667  application_termination_flag = 1;
668  /* do the cleanup before exiting: */
669  cleanup();
670  /* return FALSE so the system will call the dafult handler which will terminate the process. */
671  return FALSE;
672 }
673 #else
674 
679 void TerminateHandler (int sig)
680 {
681  printf("\nProcess terminated by user request.\n");
682  application_termination_flag = 1;
683  /* do the cleanup before exiting: */
684  cleanup();
685  return;
686 }
687 
688 #endif
689 
697 void cleanup()
698 {
699  int dev_no;
700  sng_fd_t fd;
701  sangoma_chan_t *chan;
702  sangoma_wait_obj_t *sng_wait_object;
703  wanpipe_api_t tdm_api;
704 
705  /* do the cleanup before exiting: */
706  for(dev_no = 0; dev_no < TEST_NUMBER_OF_OBJECTS; dev_no++){
707 
708  sng_wait_object = sangoma_wait_objects[dev_no];
709  if(!sng_wait_object){
710  continue;
711  }
712  chan = sangoma_wait_obj_get_context(sng_wait_object);
713  printf("%s(): span: %d, chan: %d ...\n", __FUNCTION__,
714  chan->channo,
715  chan->spanno);
716 
717  fd = sangoma_wait_obj_get_fd(sng_wait_object);
718  memset(&tdm_api, 0x00, sizeof(tdm_api));
719 
720  if(dtmf_enable_octasic == 1){
721  /* Disable dtmf detection on Octasic chip */
722  sangoma_tdm_disable_dtmf_events(fd, &tdm_api);
723  }
724 
725  if(dtmf_enable_remora == 1){
726  /* Disable dtmf detection on Sangoma's Remora SLIC chip */
728  }
729 
730  if(remora_hook == 1){
731  sangoma_tdm_disable_rxhook_events(fd, &tdm_api);
732  }
733 
734  if(rbs_events == 1){
735  sangoma_tdm_disable_rbs_events(fd, &tdm_api);
736  }
737 
738  sangoma_wait_obj_delete(&sng_wait_object);
739 
740  sangoma_close(&fd);
741 
742  }
743 }
744 
745 
761 {
762  int span, chan, err = 0, open_dev_cnt = 0;
763  sangoma_status_t status;
765  wanpipe_api_t tdm_api;
766 
767  span = wanpipe_port_no;
768  chan = wanpipe_if_no;
769 
770  /* span and chan are 1-based */
771  if (force_open) {
772  dev_fd = __sangoma_open_api_span_chan(span, chan);
773  } else {
774  dev_fd = sangoma_open_api_span_chan(span, chan);
775  }
776  if( dev_fd == INVALID_HANDLE_VALUE){
777  printf("Warning: Failed to open span %d, chan %d\n", span , chan);
778  return 1;
779  }else{
780  printf("Successfuly opened span %d, chan %d\n", span , chan);
781  }
782 
783  memset(&tdm_api, 0x00, sizeof(tdm_api));
784 
785  status = sangoma_wait_obj_create(&sangoma_wait_objects[open_dev_cnt], dev_fd, SANGOMA_DEVICE_WAIT_OBJ);
786  if(status != SANG_STATUS_SUCCESS){
787  printf("Error: Failed to create 'sangoma_wait_object'!\n");
788  return 1;
789  }
790  sangoma_channels[open_dev_cnt].channo = chan;
791  sangoma_channels[open_dev_cnt].spanno = span;
792  sangoma_wait_obj_set_context(sangoma_wait_objects[open_dev_cnt], &sangoma_channels[open_dev_cnt]);
793  /* open_dev_cnt++; */
794 
795  if((err = sangoma_get_full_cfg(dev_fd, &tdm_api))){
796  return 1;
797  }
798 
799  if(set_codec_slinear){
800  printf("Setting SLINEAR codec\n");
801  if((err=sangoma_tdm_set_codec(dev_fd, &tdm_api, WP_SLINEAR))){
802  return 1;
803  }
804  }
805 
806  if(set_codec_none){
807  printf("Disabling codec\n");
808  if((err=sangoma_tdm_set_codec(dev_fd, &tdm_api, WP_NONE))){
809  return 1;
810  }
811  }
812 
813  if(usr_period){
814  printf("Setting user period: %d\n", usr_period);
815  if((err=sangoma_tdm_set_usr_period(dev_fd, &tdm_api, usr_period))){
816  return 1;
817  }
818  }
819 
820  if (rx_gain_cmd) {
821  printf("Setting rx gain : %f\n", rx_gain);
822  if (sangoma_set_rx_gain(dev_fd,&tdm_api,rx_gain)) {
823  return 1;
824  }
825  }
826 
827  if (tx_gain_cmd) {
828  printf("Setting tx gain : %f\n", rx_gain);
829  if (sangoma_set_tx_gain(dev_fd,&tdm_api,tx_gain)) {
830  return 1;
831  }
832  }
833 
834  if(set_codec_slinear || usr_period || set_codec_none){
835  /* display new configuration AFTER it was changed */
836  if((err=sangoma_get_full_cfg(dev_fd, &tdm_api))){
837  return 1;
838  }
839  }
840 
841  if(dtmf_enable_octasic == 1){
842  poll_events_bitmap |= POLLPRI;
843  /* enable dtmf detection on Octasic chip */
844  if((err=sangoma_tdm_enable_dtmf_events(dev_fd, &tdm_api))){
845  return 1;
846  }
847  }
848 
849  if(dtmf_enable_remora == 1){
850  poll_events_bitmap |= POLLPRI;
851  /* enable dtmf detection on Sangoma's Remora SLIC chip (A200 ONLY) */
852  if((err=sangoma_tdm_enable_rm_dtmf_events(dev_fd, &tdm_api))){
853  return 1;
854  }
855  }
856 
857  if(remora_hook == 1){
858  poll_events_bitmap |= POLLPRI;
859  if((err=sangoma_tdm_enable_rxhook_events(dev_fd, &tdm_api))){
860  return 1;
861  }
862  }
863 
864  if(rbs_events == 1){
865  poll_events_bitmap |= POLLPRI;
866  if((err=sangoma_tdm_enable_rbs_events(dev_fd, &tdm_api, 20))){
867  return 1;
868  }
869  }
870  if (buffer_multiplier) {
871  printf("Setting buffer multiplier to %i\n",buffer_multiplier);
872  err=sangoma_tdm_set_buffer_multiplier(dev_fd,&tdm_api,buffer_multiplier);
873  if (err) {
874  return 1;
875  }
876  }
877  if (ss7_cfg_status) {
878  wan_api_ss7_cfg_status_t ss7_hw_status;
879  printf("Getting ss7 cfg status\n");
880  err=sangoma_ss7_get_cfg_status(dev_fd,&tdm_api,&ss7_hw_status);
881  if (err) {
882  return 1;
883  }
884  printf("SS7 HW Configuratoin\n");
885  printf("SS7 hw support = %s\n",ss7_hw_status.ss7_hw_enable?"Enabled":"Disabled");
886  printf("SS7 hw mode = %s\n",ss7_hw_status.ss7_hw_mode?"4096":"128");
887  printf("SS7 hw lssu size = %d\n",ss7_hw_status.ss7_hw_lssu_size);
888  printf("SS7 driver repeat= %s\n",ss7_hw_status.ss7_driver_repeat?"Enabled":"Disabled");
889  }
890 
891  if (stats_test) {
892  sangoma_print_stats(dev_fd);
893  exit(0);
894  }
895  if (flush_stats_test) {
896  sangoma_flush_stats(dev_fd, &tdm_api);
897  sangoma_print_stats(dev_fd);
898  exit(0);
899  }
900 
901  if (fe_read_test) {
902  uint8_t data=0;
903  uint8_t prev_data=0;
904  int i;
905  int elapsed=0;
906  int elapsed_cnt=0;
907 
908 
909 #if defined(__WINDOWS__)
910  long started, ended;
911  started = GetTickCount();
912 #else
913  struct timeval started, ended;
914 
915  gettimeofday(&started, NULL);
916 #endif
917 
918  for (i=0;;i++) {
919  elapsed_cnt++;
920  sangoma_fe_reg_read(dev_fd, 0xF8, &data);
921  prev_data=data;
922  if (data==0) {
923  printf("Error: Bad FE Read 0x00 cnt=%i !!!!!!!!!!! \n",i);
924  exit(1);
925  } else {
926  data=(data>>3)&0x1F;
927  if (data != 0x0C) {
928  printf("Error: Bad FE Read Prev Data = 0x%X cnt=%i !!!!!!!!!!!!\n",prev_data,i);
929  exit(1);
930  }
931  }
932 
933 #if defined(__WINDOWS__)
934  ended = GetTickCount();
935 #else
936  gettimeofday(&ended, NULL);
937 #endif
938 
939 #if defined(__WINDOWS__)
940  elapsed = ended - started;
941 #else
942  elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000));
943 #endif
944 
945  if (elapsed > 5000) {
946  printf("FE Reg 0xF8 = Prev Data = 0x%X int_cnt=%08i tot_cnt %08i\n",prev_data,elapsed_cnt,i);
947 #if defined(__WINDOWS__)
948  started = GetTickCount();
949 #else
950  gettimeofday(&started, NULL);
951 #endif
952 
953  elapsed_cnt=0;
954  }
955  }
956  exit(0);
957  }
958 
959  printf("Device Config RxQ=%i TxQ=%i \n",
960  sangoma_get_rx_queue_sz(dev_fd,&tdm_api),
961  sangoma_get_rx_queue_sz(dev_fd,&tdm_api));
962 
963 #if 0
964  sangoma_set_rx_queue_sz(dev_fd,&tdm_api,20);
965  sangoma_set_tx_queue_sz(dev_fd,&tdm_api,30);
966 #endif
967 
968  printf("Device Config RxQ=%i TxQ=%i \n",
969  sangoma_get_rx_queue_sz(dev_fd,&tdm_api),
970  sangoma_get_tx_queue_sz(dev_fd,&tdm_api));
971 
972  sangoma_flush_bufs(dev_fd,&tdm_api);
973 
974  sangoma_print_stats(dev_fd);
975 
976 
977  return err;
978 }
979 
980 
981 static int sangoma_hardware_rescan(void)
982 {
983 
984 #ifdef WP_API_FEATURE_HARDWARE_RESCAN
985  int err;
986  int cnt;
987  port_management_struct_t port;
989  if (fd == INVALID_HANDLE_VALUE) {
990  printf("Hardware Rescan failed to open driver ctrl\n");
991  return -1;
992  }
993 
994  memset(&port,0,sizeof(port));
995 
996  err=sangoma_driver_hw_rescan(fd,&port,&cnt);
997  if (err < 0) {
998  printf("Hardware Rescan error %i\n",err);
999  return err;
1000  }
1001 
1002  printf("Hardware Rescan: Detected Devices %i\n",cnt);
1003 
1004  sangoma_close(&fd);
1005 
1006 #endif
1007 
1008  return err;
1009 }
1010 
1011 
1018 int __cdecl main(int argc, char* argv[])
1019 {
1020  int proceed, i;
1021 
1022 
1023  proceed=init_args(argc,argv);
1024  if (proceed != WAN_TRUE){
1025  usage(argv[0]);
1026  return -1;
1027  }
1028 
1029  if (hw_pci_rescan) {
1030  /* Function used to rescan pci/usb bus.
1031  added here as use example. Uncomment to use.
1032  This function should only be used when all ports
1033  are down. */
1034  return sangoma_hardware_rescan();
1035  }
1036 
1037  /* register Ctrl+C handler - we want a clean termination */
1038 #if defined(__WINDOWS__)
1039  if (!SetConsoleCtrlHandler(TerminateHandler, TRUE)) {
1040  printf("ERROR : Unable to register terminate handler ( %d ).\nProcess terminated.\n",
1041  GetLastError());
1042  return -1;
1043  }
1044 #else
1045  signal(SIGHUP,TerminateHandler);
1046  signal(SIGTERM,TerminateHandler);
1047 #endif
1048 
1049  for(i = 0; i < TEST_NUMBER_OF_OBJECTS; i++){
1050  sangoma_wait_objects[i] = NULL;
1051  }
1052 
1053  poll_events_bitmap = 0;
1054  if(read_enable == 1){
1055  poll_events_bitmap |= POLLIN;
1056  }
1057 
1058  if(write_enable == 1 && rx2tx == 1){
1059  /* These two options are mutually exclusive because 'rx2tx' option
1060  * indicates "use Reciever as the timing source for Transmitter". */
1061  write_enable = 0;
1062  }
1063 
1064  if(write_enable == 1){
1065  poll_events_bitmap |= POLLOUT;
1066  }
1067 
1068  /* Front End connect/disconnect, and other events, such as DTMF... */
1069  poll_events_bitmap |= (POLLHUP | POLLPRI);
1070 #if defined(__WINDOWS__)
1071  printf("Enabling Poll Events:\n");
1072  print_poll_event_bitmap(poll_events_bitmap);
1073 #endif
1074  printf("Connecting to Port/Span: %d, Interface/Chan: %d\n",
1075  wanpipe_port_no, wanpipe_if_no);
1076 
1077 
1078  if(open_sangoma_device()){
1079  return -1;
1080  }
1081 
1082  printf("********************************\n");
1083  printf("files_used: 0x%x\n", files_used);
1084  printf("********************************\n");
1085  if(files_used & RX_FILE_USED){
1086  pRxFile = fopen( (const char*)&rx_file[0], "wb" );
1087  if(pRxFile == NULL){
1088  printf("Can't open Rx file: [%s]!!\n", rx_file);
1089  }else{
1090  printf("Open Rx file: %s. OK.\n", rx_file);
1091  }
1092  }
1093 
1094  if (fe_read_cmd || fe_write_cmd) {
1095  handle_fe_rw();
1096  goto done;
1097  }
1098 
1099  handle_span_chan(1 /* handle a single device */);
1100 
1101 done:
1102  /* returned from main loop, do the cleanup before exiting: */
1103  cleanup();
1104 
1105  printf("\nSample application exiting.(press any key)\n");
1106  _getch();
1107  return 0;
1108 }
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
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
#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
Wanpipe API Library header for Sangoma AFT T1/E1/Analog/BRI/Serial Hardware -.
#define FALSE
FALSE value is 0, Ported from Windows.
Definition: libsangoma.h:244
void cleanup(void)
Protperly shutdown single device.
Definition: sample.c:697
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_read_event(sng_fd_t fd, wanpipe_api_t *tdm_api)
Read API Events.
Definition: libsangoma.c:2426
int write_data_to_file(unsigned char *data, unsigned int data_length)
Write data buffer into a file.
Definition: sample.c:649
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
sng_fd_t _LIBSNG_CALL sangoma_open_driver_ctrl(int port_no)
Open a Global Driver Control Device.
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
#define _getch
get character, Ported from Windows
Definition: libsangoma.h:252
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_writemsg(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
Write Data to device.
Definition: libsangoma.c:1913
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_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_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_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.
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
#define __cdecl
Ported from Windows.
Definition: libsangoma.h:241
Sangoma object associated to some device which cannot be signaled (cannot call sangoma_wait_obj_signa...
Definition: libsangoma.h:371
wanpipe_api_cmd_t wp_cmd
#define sangoma_msleep(x)
milisecond sleep function
Definition: libsangoma.h:251
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
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 handle_data(uint32_t dev_index, int flags_out)
Read data buffer from the device and transmit it back down.
Definition: sample.c:391
int32_t sangoma_status_t
return status from sangoma APIs
Definition: libsangoma.h:338
#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
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
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
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
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
u_int8_t channel
#define SANGOMA_INIT_TDM_API_CMD(_name_)
Initialize the tdm api cmd structure. Set to 0.
Definition: libsangoma.h:101
int _LIBSNG_CALL sangoma_driver_hw_rescan(sng_fd_t fd, port_management_struct_t *port_mgmnt, int *cnt)
Rescan the pci and usb bus for newly added hardware.
int handle_tdm_event(uint32_t dev_index)
Read Event buffer from the device.
Definition: sample.c:513
#define WP_API_EVENT_POLARITY_REVERSE_DECODE(polarity_reverse)
Print out the Polarity state.
#define TEST_NUMBER_OF_OBJECTS
Number of wait objects to define in object array.
Definition: sample.c:50
int __cdecl main(int argc, char *argv[])
Main function that starts the sample code.
Definition: sample.c:1018
int DWORD
DWORD type is int, Ported from Windows.
Definition: libsangoma.h:259
int open_sangoma_device(void)
Open a single span chan device.
Definition: sample.c:760
void handle_span_chan(int open_device_counter)
Write data buffer into a file.
Definition: sample.c:576
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
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.
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
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
void TerminateHandler(int)
Signal handler for graceful shutdown.
Definition: sample.c:679
#define TRUE
TRUE value is 1, Ported from Windows.
Definition: libsangoma.h:248
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
Wanpipe API Header Structure.
int write_data(uint32_t dev_index, wp_api_hdr_t *tx_hdr, void *tx_buffer, int tx_len)
Transmit a data buffer to a device.
Definition: sample.c:325
u_int16_t data_length
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
#define MAX_NO_DATA_BYTES_IN_FRAME
Maximum tx/rx data size.
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
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
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