sample.c

Go to the documentation of this file.
00001 /******************************************************************************/
00035 #include "libsangoma.h"
00036 #include "lib_api.h"        
00037 
00038 u_int32_t       poll_events_bitmap = 0;
00039 
00049 #define TEST_NUMBER_OF_OBJECTS 1
00050 
00051 sangoma_wait_obj_t sangoma_wait_objects[TEST_NUMBER_OF_OBJECTS];
00052 wp_api_element_t Rx_data[TEST_NUMBER_OF_OBJECTS];
00053 wp_api_element_t Tx_data[TEST_NUMBER_OF_OBJECTS];
00054 
00055 /* IOCTL management structures and variables*/
00056 wan_udp_hdr_t   wan_udp;
00057 wanpipe_api_t   tdm_api; 
00058 
00059 unsigned char rx_rbs_bits = WAN_RBS_SIG_A;
00060 
00061 FILE    *pRxFile;
00062 
00063 /***************************************************************/
00067 int __cdecl main(int argc, char* argv[]);
00068 int open_sangoma_devices(int *open_device_counter);
00069 void handle_span_chan(int open_device_counter);
00070 int handle_tdm_event(uint32_t dev_index);
00071 int handle_data(uint32_t    dev_index);
00072 int read_data(uint32_t dev_index);
00073 int write_data(uint32_t dev_index, wp_api_hdr_t *tx_hdr, void *tx_data);
00074 int dtmf_event(sng_fd_t fd,unsigned char digit,unsigned char type,unsigned char port);
00075 int rbs_event(sng_fd_t fd,unsigned char rbs_bits);
00076 int rxhook_event(sng_fd_t fd,unsigned char hook_state);
00077 int rxring_event(sng_fd_t fd,unsigned char ring_state);
00078 int ringtrip_event (sng_fd_t fd, unsigned char ring_state);
00079 void print_rx_data(unsigned char *data, int datalen);
00080 int write_data_to_file(unsigned char *data, unsigned int data_length);
00081 void cleanup(int interface_no);
00082 
00083 #ifdef WIN32
00084 BOOL TerminateHandler(DWORD dwCtrlType);
00085 #else
00086 void TerminateHandler(int);
00087 #endif
00088 
00089 /***************************************************************/
00100 void print_rx_data(unsigned char *data, int datalen)
00101 {
00102     int i;
00103 
00104     printf("Data:\n");
00105     for(i = 0; i < datalen; i++) {
00106         if((i % 20 == 0)){
00107             if(i){
00108                 printf("\n");
00109             }
00110         }
00111         printf("%02X ", data[i]);
00112         //don't print too much!!
00113         if(i > 100){
00114             printf("...\n");
00115             break;
00116         }
00117     }
00118     printf("\n");
00119 }
00120 
00128 int read_data(uint32_t dev_index)
00129 {
00130     wp_api_element_t    *rx_el  = &Rx_data[dev_index];
00131     wp_api_hdr_t        *rx_hdr = &rx_el->hdr;
00132     sng_fd_t            dev_fd  = sangoma_wait_objects[dev_index].fd;
00133     int                 Rx_lgth = 0;
00134     static int          Rx_count= 0;
00135 
00136     memset(rx_hdr, 0, sizeof(wp_api_hdr_t));
00137 
00138     //read the message
00139     Rx_lgth = sangoma_readmsg(
00140                     dev_fd,
00141                     rx_hdr,                     /* header buffer */
00142                     sizeof(wp_api_hdr_t),       /* header size */
00143                     rx_el->data,                /* data buffer */
00144                     MAX_NO_DATA_BYTES_IN_FRAME, /* data BUFFER size */
00145                     0);   
00146     if(Rx_lgth <= 0) {
00147         printf("Span: %d, Chan: %d: Error receiving data!\n", 
00148             sangoma_wait_objects[dev_index].span, sangoma_wait_objects[dev_index].chan);
00149         return 1;
00150     }
00151         
00152     if (verbose){
00153         print_rx_data(rx_el->data, Rx_lgth);
00154     }
00155             
00156     //use Rx_counter as "write" events trigger:
00157     if(rbs_events == 1 && (Rx_count % 400) == 0){
00158         /*  bitmap - set as needed: WAN_RBS_SIG_A | WAN_RBS_SIG_B | WAN_RBS_SIG_C | WAN_RBS_SIG_D;
00159         
00160             In this example make bits A and B to change each time,
00161             so it's easy to see the change on the receiving side.
00162         */
00163         if(rx_rbs_bits == WAN_RBS_SIG_A){
00164             rx_rbs_bits = WAN_RBS_SIG_B;
00165         }else{
00166             rx_rbs_bits = WAN_RBS_SIG_A;
00167         }
00168         printf("Writing RBS bits (0x%X)...\n", rx_rbs_bits);
00169         sangoma_tdm_write_rbs(dev_fd, &tdm_api, rx_rbs_bits);
00170     }
00171 
00172     //if user needs Rx data to be written into a file:
00173     if(files_used & RX_FILE_USED){
00174         write_data_to_file(rx_el->data, Rx_lgth);
00175     }
00176 
00177     return 0;
00178 }
00179 
00188 int write_data(uint32_t dev_index, wp_api_hdr_t *tx_hdr, void *tx_data)
00189 {
00190     sng_fd_t    dev_fd  = sangoma_wait_objects[dev_index].fd;
00191     int         err;
00192     static int  Tx_count = 0;
00193 
00194     //write a message
00195     err = sangoma_writemsg(
00196                 dev_fd,
00197                 tx_hdr,                 /* header buffer */
00198                 sizeof(wp_api_hdr_t),   /* header size */
00199                 tx_data,                /* data buffer */
00200                 tx_hdr->data_length,    /* DATA size */
00201                 0);
00202 
00203     if (err <= 0){
00204         printf("Span: %d, Chan: %d: Failed to send!\n", 
00205             sangoma_wait_objects[dev_index].span, sangoma_wait_objects[dev_index].chan);
00206         return -1;
00207     }
00208     
00209     Tx_count++;
00210     if (verbose){
00211         printf("Packet sent: counter: %i, len: %i\n", Tx_count, err);
00212     }else{
00213         if(Tx_count && (!(Tx_count % 1000))){
00214             printf("Packet sent: counter: %i, len: %i\n", Tx_count, err);
00215         }
00216     }
00217 
00218 #if 0
00219     if(Tx_count >= tx_cnt){
00220         write_enable=0;
00221         printf("Disabling POLLOUT...\n");
00222         /* No need for POLLOUT, turn it off!! If not turned off, and we
00223          * have nothing for transmission, sangoma_socket_waitfor() will return
00224          * immediately, creating a busy loop. */
00225         sangoma_wait_objects[dev_index].flags_in &= (~POLLOUT);
00226     }
00227 #endif
00228     return 0;
00229 }
00230 
00241 int handle_data(uint32_t    dev_index)
00242 {
00243     wp_api_element_t    *rx_el          = &Rx_data[dev_index];
00244     wp_api_element_t    *tx_el          = &Tx_data[dev_index];
00245     uint32_t            api_poll_status = sangoma_wait_objects[dev_index].flags_out;
00246 
00247     memset(rx_el, 0, sizeof(wp_api_element_t));
00248 
00249     if(api_poll_status & POLLIN){
00250 
00251         if(read_data(dev_index) == 0){
00252 
00253             if(rx2tx){
00254                 /* Send back received data (create a "software loopback"), just a test. */
00255                 write_data(dev_index, &rx_el->hdr, rx_el->data);
00256             }
00257         }
00258     }
00259 
00260     if((api_poll_status & POLLOUT) && write_enable){
00261     
00262         wp_api_hdr_t *api_tx_hdr = &tx_el->hdr;
00263         uint16_t Tx_length = 128;/* 128 is just an example */
00264         static unsigned char tx_test_byte = 0;
00265 
00266         api_tx_hdr->data_length = Tx_length; 
00267         memset(tx_el->data, tx_test_byte, Tx_length);
00268                     
00269         if(write_data(dev_index, api_tx_hdr, tx_el->data) == 0){
00270 
00271             tx_test_byte++;
00272         }
00273 
00274     }//if()
00275     return 0;
00276 }
00277 
00287 int handle_tdm_event(uint32_t dev_index)
00288 {
00289     sng_fd_t    dev_fd = sangoma_wait_objects[dev_index].fd;
00290 
00291 #if 0
00292     printf("sangoma_wait_objects[%d].flags_out:", i);
00293     print_poll_event_bitmap(sangoma_wait_objects[i].flags_out);
00294     printf("\n");
00295 #endif
00296 
00297     return sangoma_read_event(dev_fd, &tdm_api);
00298 }
00299 
00311 void handle_span_chan(int open_device_counter)
00312 {
00313     int iResult, i;
00314 
00315     printf("\n\nSpan/Chan Handler: RxEnable=%s, TxEnable=%s, TxCnt=%i, TxLen=%i\n",
00316         (read_enable? "Yes":"No"), (write_enable?"Yes":"No"),tx_cnt,tx_size);   
00317 
00318     /* Main Rx/Tx/Event loop */
00319     for(;;) 
00320     {   
00321         iResult = sangoma_socket_waitfor_many(sangoma_wait_objects, open_device_counter, SANGOMA_INFINITE_API_POLL_WAIT);
00322 
00323         if(iResult < 0){
00324             //error
00325             break;
00326         }
00327 
00328         if(iResult == 0){
00329             //timeout
00330             continue;
00331         }
00332 
00333         for(i = 0; i < open_device_counter; i++){
00334 
00335             if(sangoma_wait_objects[i].flags_out){
00336 
00337                 if(sangoma_wait_objects[i].flags_out & POLLPRI){
00338                     /* got tdm api event */
00339                     if(handle_tdm_event(i)){
00340                         return;
00341                     }
00342                 }
00343                 
00344                 if(sangoma_wait_objects[i].flags_out & POLLIN){
00345                     /* got data */
00346                     if(handle_data(i)){
00347                         return;
00348                     }
00349                 }
00350             }
00351 
00352         }/* for() */
00353     }/* for() */
00354 }
00355 
00364 int dtmf_event (sng_fd_t fd, unsigned char digit, unsigned char type, unsigned char port)
00365 {
00366     printf("DTMF Event: Digit: %c (Port: %s, Type:%s)!\n",
00367             digit,
00368             (port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT",
00369             (type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP");        
00370     return 0;
00371 }
00372 
00379 int rbs_event (sng_fd_t fd, unsigned char rbs_bits)
00380 {
00381     printf("RBS Event: BITS=0x%X, A:%1d B:%1d C:%1d D:%1d\n",
00382             rbs_bits, 
00383             (rbs_bits & WAN_RBS_SIG_A) ? 1 : 0,
00384             (rbs_bits & WAN_RBS_SIG_B) ? 1 : 0,
00385             (rbs_bits & WAN_RBS_SIG_C) ? 1 : 0,
00386             (rbs_bits & WAN_RBS_SIG_D) ? 1 : 0);
00387 
00388     rx_rbs_bits = rbs_bits;
00389     return 0;
00390 }
00391 
00398 int rxhook_event (sng_fd_t fd, unsigned char hook_state)
00399 {
00400     printf("rxhook_event(): %s (0x%X)\n", 
00401         WAN_EVENT_RXHOOK_DECODE(hook_state), hook_state);
00402     return 0;
00403 }
00404 
00411 int rxring_event (sng_fd_t fd, unsigned char ring_state)
00412 {
00413     printf("rxring_event(): %s (0x%X)\n",
00414         WAN_EVENT_RING_DECODE(ring_state), ring_state);
00415     return 0;
00416 }
00417 
00424 int ringtrip_event (sng_fd_t fd, unsigned char ring_state)
00425 {
00426     printf("ringtrip_event(): %s (0x%X)\n", 
00427         WAN_EVENT_RING_TRIP_DECODE(ring_state), ring_state);
00428     return 0;
00429 }
00430 
00439 int write_data_to_file(unsigned char *data, unsigned int data_length)
00440 {
00441     if(pRxFile == NULL){
00442         return 1;
00443     }
00444 
00445     return fwrite(data, 1, data_length, pRxFile);
00446 }
00447 
00448 #ifdef WIN32
00449 /*
00450  * TerminateHandler() - this handler is called by the system whenever user tries to terminate
00451  *                      the process with Ctrl+C, Ctrl+Break or closes the console window.
00452  *                      Perform a clean-up here.
00453  */
00454 BOOL TerminateHandler(DWORD dwCtrlType)
00455 {
00456     int i;
00457 
00458     printf("\nProcess terminated by user request.\n");
00459 
00460     //do the cleanup before exiting:
00461     for(i = 0; i < TEST_NUMBER_OF_OBJECTS; i++){
00462         cleanup(i);
00463     }
00464 
00465     //return FALSE so the system will call the dafult handler which will terminate the process.
00466     return FALSE;
00467 }
00468 #else
00469 
00474 void TerminateHandler (int sig)
00475 {
00476     int i;
00477 
00478     printf("\nProcess terminated by user request.\n");
00479 
00480     //do the cleanup before exiting:
00481     for(i = 0; i < TEST_NUMBER_OF_OBJECTS; i++){
00482         cleanup(i);
00483     }
00484 
00485     return;
00486 }
00487 
00488 #endif
00489 
00497 void cleanup(int dev_no)
00498 {
00499     printf("cleanup()...\n");
00500 
00501     if(dtmf_enable_octasic == 1){
00502         /* Disable dtmf detection on Octasic chip */
00503         sangoma_tdm_disable_dtmf_events(sangoma_wait_objects[dev_no].fd, &tdm_api);
00504     }
00505 
00506     if(dtmf_enable_remora == 1){
00507         /* Disable dtmf detection on Sangoma's Remora SLIC chip */
00508         sangoma_tdm_disable_rm_dtmf_events(sangoma_wait_objects[dev_no].fd, &tdm_api);
00509     }
00510 
00511     if(remora_hook == 1){
00512         sangoma_tdm_disable_rxhook_events(sangoma_wait_objects[dev_no].fd, &tdm_api);
00513     }
00514 
00515     if(rbs_events == 1){
00516         sangoma_tdm_disable_rbs_events(sangoma_wait_objects[dev_no].fd, &tdm_api);
00517     }
00518 
00519     //call sangoma_close() for EACH open Device Handle
00520     sangoma_close(&sangoma_wait_objects[dev_no].fd);
00521 }
00522 
00523 
00537 int open_sangoma_devices(int *open_device_counter)
00538 {
00539     int i, span, chan, err = -1;
00540     sng_fd_t    dev_fd = INVALID_HANDLE_VALUE;
00541 
00542     *open_device_counter = 0;
00543 
00544     /* open and initialize all devices */
00545     for(span = 0; span < max_number_of_ports; span++){
00546 
00547         for(chan = 0; chan < max_number_of_interfaces; chan++){
00548             
00549             /* span and chan are 1-based */
00550             dev_fd = sangoma_open_api_span_chan(span + 1, chan + 1 );
00551             if( dev_fd == INVALID_HANDLE_VALUE){
00552                 printf("Failed to open span %d, chan %d\n", span + 1, chan + 1);
00553                 return -1;
00554             }
00555 
00556             if(*open_device_counter < TEST_NUMBER_OF_OBJECTS){
00557 
00558                 sangoma_init_wait_obj(&sangoma_wait_objects[*open_device_counter], dev_fd, span + 1, chan + 1, 1000, poll_events_bitmap, SANGOMA_WAIT_OBJ);
00559                 (*open_device_counter)++;
00560             }else{
00561                 printf("Warning: Number of requested channels greater than the pre-compiled maximum of %d\n", TEST_NUMBER_OF_OBJECTS);
00562                 break;
00563             }
00564         }
00565     }
00566 
00567     /* */
00568     for(i = 0; i < *open_device_counter; i++){
00569 
00570         printf("HANDLING SPAN %i CHAN %i\n", sangoma_wait_objects[i].span, sangoma_wait_objects[i].chan);
00571 
00572         dev_fd = sangoma_wait_objects[i].fd;
00573 
00574         if((err=sangoma_get_full_cfg(dev_fd, &tdm_api))){
00575             break;
00576         }
00577 
00578         if(set_codec_slinear){
00579             printf("Setting SLINEAR codec\n");
00580             if((err=sangoma_tdm_set_codec(dev_fd, &tdm_api, WP_SLINEAR))){
00581                 break;
00582             }
00583         }
00584 
00585         if(set_codec_none){
00586             printf("Disabling codec\n");
00587             if((err=sangoma_tdm_set_codec(dev_fd, &tdm_api, WP_NONE))){
00588                 break;
00589             }
00590         }
00591 
00592         if(usr_period){
00593             printf("Setting user period: %d\n", usr_period);
00594             if((err=sangoma_tdm_set_usr_period(dev_fd, &tdm_api, usr_period))){
00595                 break;
00596             }
00597         }
00598 
00599         if(set_codec_slinear || usr_period || set_codec_none){
00600             //display new configuration AFTER it was changed
00601             if((err=sangoma_get_full_cfg(dev_fd, &tdm_api))){
00602                 break;
00603             }
00604         }
00605 
00606         if(dtmf_enable_octasic == 1){
00607             poll_events_bitmap |= POLLPRI;
00608             /* enable dtmf detection on Octasic chip */
00609             if((err=sangoma_tdm_enable_dtmf_events(dev_fd, &tdm_api))){
00610                 break;
00611             }
00612         }
00613 
00614         if(dtmf_enable_remora == 1){
00615             poll_events_bitmap |= POLLPRI;
00616             /* enable dtmf detection on Sangoma's Remora SLIC chip (A200 ONLY) */
00617             if((err=sangoma_tdm_enable_rm_dtmf_events(dev_fd, &tdm_api))){
00618                 break;
00619             }
00620         }
00621 
00622         if(remora_hook == 1){
00623             poll_events_bitmap |= POLLPRI;
00624             if((err=sangoma_tdm_enable_rxhook_events(dev_fd, &tdm_api))){
00625                 break;
00626             }
00627         }
00628 
00629         if(rbs_events == 1){
00630             poll_events_bitmap |= POLLPRI;
00631             if((err=sangoma_tdm_enable_rbs_events(dev_fd, &tdm_api, 20))){
00632                 break;
00633             }
00634         }
00635     }
00636 
00637     printf("Enabling Poll Events:\n");
00638 #ifdef WIN32
00639     print_poll_event_bitmap(poll_events_bitmap);
00640 #endif
00641 
00642     return err;
00643 }
00644 
00649 void close_sangoma_devices(void)
00650 {
00651     int i;
00652 
00653     for(i = 0; i < TEST_NUMBER_OF_OBJECTS; i++){
00654         if(sangoma_wait_objects[i].fd != INVALID_HANDLE_VALUE){
00655             cleanup(i);
00656         }
00657     }
00658 }
00659 
00666 int __cdecl main(int argc, char* argv[])
00667 {
00668     int proceed, i, open_device_counter;
00669 
00670     proceed=init_args(argc,argv);
00671     if (proceed != WAN_TRUE){
00672         usage(argv[0]);
00673         return -1;
00674     }
00675 
00676     /* register Ctrl+C handler - we want a clean termination */
00677 #if defined(__WINDOWS__)
00678     if (!SetConsoleCtrlHandler(TerminateHandler, TRUE)) {
00679         printf("ERROR : Unable to register terminate handler ( %d ).\nProcess terminated.\n", 
00680             GetLastError());
00681         return -1;
00682     }
00683 #else
00684     signal(SIGHUP,TerminateHandler);
00685     signal(SIGTERM,TerminateHandler);
00686 #endif
00687 
00688     for(i = 0; i < TEST_NUMBER_OF_OBJECTS; i++){
00689         sangoma_wait_objects[i].fd = INVALID_HANDLE_VALUE;
00690     }
00691 
00692     poll_events_bitmap = 0;
00693     if(read_enable  == 1){
00694         poll_events_bitmap |= POLLIN;
00695     }
00696     
00697     if(write_enable == 1){
00698         poll_events_bitmap |= POLLOUT;
00699     }
00700 
00701     /* always need to know about Front End connect/disconnect */
00702     poll_events_bitmap |= POLLHUP;
00703 
00704     if(dtmf_enable_octasic || dtmf_enable_remora || remora_hook || rbs_events){
00705         poll_events_bitmap |= POLLPRI;
00706     }
00707 
00708     printf("Using max_number_of_ports: %d, max_number_of_interfaces: %d\n", max_number_of_ports, max_number_of_interfaces);
00709 
00710     /*  For optimal performance of Analog event detection, it is recommended
00711         to use MTU/MRU of 80 bytes on A200/A400 (Analog) cards. */
00712     memset(&tdm_api,0,sizeof(tdm_api));
00713     tdm_api.wp_callback.wp_dtmf_event = &dtmf_event;
00714     tdm_api.wp_callback.wp_rbs_event = &rbs_event;
00715     tdm_api.wp_callback.wp_rxhook_event = &rxhook_event;
00716     tdm_api.wp_callback.wp_ring_detect_event = &rxring_event;
00717     tdm_api.wp_callback.wp_ring_trip_detect_event = &ringtrip_event;
00718 
00719     if(open_sangoma_devices(&open_device_counter)){
00720         return -1;
00721     }
00722 
00723     printf("********************************\n");
00724     printf("files_used: 0x%x\n", files_used);
00725     printf("********************************\n");
00726     if(files_used & RX_FILE_USED){
00727         pRxFile = fopen( (const char*)&rx_file[0], "wb" );
00728         if(pRxFile == NULL){
00729             printf("Can't open Rx file: [%s]!!\n", rx_file);
00730         }else{
00731             printf("Open Rx file: %s. OK.\n", rx_file);
00732         }
00733     }
00734 
00735     handle_span_chan(open_device_counter);
00736 
00737     //returned from main loop, do the cleanup before exiting:
00738     close_sangoma_devices();
00739 
00740     printf("\nSample application exiting.(press any key)\n");
00741     _getch();
00742     return 0;
00743 }
00744 
00745  
00746 
00747 

Generated on Tue Jan 6 18:08:59 2009 for libsangoma by  doxygen 1.4.7