sample.cpp

Go to the documentation of this file.
00001 /*******************************************************************************/
00035 #include "sangoma_port.h"
00036 #include "sangoma_port_configurator.h"  
00037 #include "sangoma_interface.h"
00038 
00039 #if defined(__LINUX__)
00040 #include "sample_linux_compat.h"
00041 #endif
00042 
00043 #ifndef MAX_PATH
00044 #define MAX_PATH 100
00045 #endif
00046 
00047 
00048 /*****************************************************************
00049  * Global Variables
00050  *****************************************************************/
00051 
00052 wp_program_settings_t   program_settings;
00053 callback_functions_t    callback_functions;
00054 
00055 
00056 
00057 /*****************************************************************
00058  * Prototypes & Defines
00059  *****************************************************************/
00060 
00061 static int got_rx_data(void *sang_if_ptr, void *rx_data);
00062 static void got_TdmApiEvent(void *sang_if_ptr, void *event_data);
00063 
00064 typedef struct{
00065     void                *sang_if_ptr;
00066     wp_api_event_t      event;
00067 }TDM_API_EVENT_THREAD_PARAM;
00068 
00069 
00070 #if USE_STELEPHONY_API
00071 //Sangoma Telephony API (Stelephony.dll) provides the following telephony services:
00072 //1. FSK Caller ID detection for Analog FXO.
00073 //2. Software DTMF detection.
00074 //3. Q931 decoding
00075 static void FSKCallerIDEvent(void *callback_context, char * Name, char * CallerNumber, char * CalledNumber, char * DateTime);
00076 static void DTMFEvent(void *callback_context, long Key);
00077 static void Q931Event(void *callback_context, stelephony_q931_event *pQ931Event);
00078 static void FSKCallerIDTransmit (void *callback_context, void* buffer);
00079 static void SwDtmfTransmit (void *callback_context, void* buffer);
00080 #endif
00081 
00082 //critical section for synchronizing access to 'stdout' between the threads
00083 CRITICAL_SECTION    PrintCriticalSection;
00084 //critical section for TDM events
00085 CRITICAL_SECTION    TdmEventCriticalSection;
00086 
00087 #if defined (__WINDOWS__)
00088 DWORD TdmApiEventThreadFunc(LPDWORD lpdwParam);
00089 #else
00090 void *TdmApiEventThreadFunc(void *lpdwParam);
00091 #endif
00092 
00093 
00094 /*****************************************************************
00095  * Debugging Macros
00096  *****************************************************************/
00097 
00098 #define DBG_MAIN    if(1)printf
00099 #define ERR_MAIN    printf("%s():line:%d:Error:", __FUNCTION__, __LINE__);printf
00100 #define INFO_MAIN   if(1)printf
00101 
00102 #define MAIN_FUNC() if(1)printf("%s():line:%d\n", __FUNCTION__, __LINE__)
00103 
00104 static int set_port_configuration();
00105 
00114 sangoma_interface* init(int wanpipe_number, int interface_number)
00115 {
00116     sangoma_interface   *sang_if = NULL;
00117     DBG_MAIN("init()\n");
00118     sang_if = new sangoma_interface(wanpipe_number, interface_number);
00119     if(sang_if->init(&callback_functions)){
00120         delete sang_if;
00121         return NULL;
00122     }
00123     DBG_MAIN("init(): OK\n");
00124     return sang_if;
00125 }
00126 
00133 void cleanup(sangoma_interface  *sang_if)
00134 {
00135     DBG_MAIN("cleanup()\n");
00136     if(sang_if){
00137         delete sang_if;
00138     }
00139 }
00140 
00147 int start(sangoma_interface *sang_if)
00148 {
00149     DBG_MAIN("start()\n");
00150     return sang_if->run();
00151 }
00152 
00159 void stop(sangoma_interface *sang_if)
00160 {
00161     DBG_MAIN("stop()\n");
00162     sang_if->stop();
00163 }
00164 
00171 void PrintRxData(wp_api_hdr_t *hdr, void *pdata)
00172 {
00173     USHORT          datlen;
00174     PUCHAR          data;
00175     static unsigned int rx_counter = 0;
00176 
00177     //NOTE: if running in BitStream mode, there will be TOO MUCH to print 
00178     datlen = hdr->data_length;
00179     data = (unsigned char*)pdata;
00180 
00181     rx_counter++;
00182     if(program_settings.silent){
00183         if((rx_counter % 1000) == 0){
00184             INFO_MAIN("Rx counter:%d, Rx datlen : %d\n", rx_counter, datlen);
00185         }
00186         return;
00187     }else{
00188         INFO_MAIN("Rx counter:%d, Rx datlen : %d. Data :\n", rx_counter, datlen);
00189     }
00190 
00191 #if 1
00192     for(int ln = 0; ln < datlen; ln++){
00193         if((ln % 20 == 0)){
00194             if(ln){
00195                 INFO_MAIN("\n");
00196             }
00197             INFO_MAIN("%04d ", ln/20);
00198         }
00199         INFO_MAIN("%02X ", data[ln]);
00200     }
00201     INFO_MAIN("\n");
00202 #endif
00203 }
00204 
00205 
00213 static int got_rx_data(void *sang_if_ptr, void *rxhdr, void *rx_data)
00214 {
00215     sangoma_interface *sang_if = (sangoma_interface*)sang_if_ptr;
00216 
00217 #if 0
00218 #ifdef __LINUX__
00219     static struct timeval tv_start;
00220     static int elapsed_b4=0;
00221     struct timeval last;
00222     int elapsed;
00223 
00224     last=tv_start;
00225     gettimeofday(&tv_start, NULL);
00226     elapsed = abs(elapsed_b4);
00227     elapsed_b4 = abs((((last.tv_sec * 1000) + last.tv_usec / 1000) - ((tv_start.tv_sec * 1000) + tv_start.tv_usec / 1000)));
00228     if (abs(elapsed - elapsed_b4) > 1) {
00229         INFO_MAIN("wanpipe%d: Elapsed %i %i diff=%i\n", program_settings.wanpipe_number, elapsed,elapsed_b4,abs(elapsed-elapsed_b4));
00230     }
00231 #endif
00232 #endif
00233     //Do something with data received from Sangoma interface.
00234     //Fore example, transimit back everything what was received:
00235 
00236     if(program_settings.Rx_to_Tx_loopback == 1){
00237         sang_if->transmit((wp_api_hdr_t*)rxhdr, rx_data);
00238     }
00239 
00240     EnterCriticalSection(&PrintCriticalSection);
00241     PrintRxData((wp_api_hdr_t*)rxhdr, rx_data);
00242     LeaveCriticalSection(&PrintCriticalSection);
00243     return 0;
00244 }
00245 
00256 static void got_TdmApiEvent(void *sang_if_ptr, void *event_data)
00257 {
00258     TDM_API_EVENT_THREAD_PARAM  *param =
00259         (TDM_API_EVENT_THREAD_PARAM*)malloc(sizeof(TDM_API_EVENT_THREAD_PARAM));
00260 
00261     if(param == NULL){
00262         ERR_MAIN("Failed to allocate memory for 'Event Thread parameter'!!\n");
00263         return;
00264     }
00265 
00266     memcpy(&param->event, event_data, sizeof(wp_api_event_t));
00267     param->sang_if_ptr = sang_if_ptr;
00268 
00270     //Handling of Events must be done OUTSIDE of the REAL-TIME Rx thread//
00271     //because it may make take a lot of time.                           //
00272     //Create a special thread for Event hadling.                        //
00274 #if defined(__WINDOWS__)
00275     DWORD   dwThreadId;
00276 
00277     if(CreateThread(
00278         NULL,                       /* no security attributes        */ 
00279         0,                          /* use default stack size        */ 
00280         (LPTHREAD_START_ROUTINE)TdmApiEventThreadFunc, /* thread function     */ 
00281         param,                      /* argument to thread function   */ 
00282         0,                          /* use default creation flags    */ 
00283         &dwThreadId                 /* returns the thread identifier */ 
00284         ) == NULL){
00285         ERR_MAIN("Failed to create 'TdmApiEvent' thread!!\n");
00286     }
00287 #else
00288     //FIXME: implement the thread. Consider using sangoma_cthread class.
00289     TdmApiEventThreadFunc(param);
00290 #endif
00291 }
00292 
00299 #if defined(__WINDOWS__)
00300 DWORD TdmApiEventThreadFunc(LPDWORD lpdwParam)
00301 #else
00302 void *TdmApiEventThreadFunc(void *lpdwParam)
00303 #endif
00304 { 
00305     TDM_API_EVENT_THREAD_PARAM  *param;
00306     sangoma_interface           *sang_if;
00307     wp_api_event_t          *wp_tdm_api_event;
00308 
00309     EnterCriticalSection(&TdmEventCriticalSection);
00310 
00311     param = (TDM_API_EVENT_THREAD_PARAM*)lpdwParam;
00312 
00313     wp_tdm_api_event = &param->event;
00314     sang_if = (sangoma_interface*)param->sang_if_ptr;
00315 
00316     DBG_MAIN( "TdmApiEventThreadFunc():ifname: %s: Channel: %d\n",
00317         sang_if->device_name, wp_tdm_api_event->channel);
00318 
00319     switch(wp_tdm_api_event->wp_api_event_type)
00320     {
00321     case WP_API_EVENT_DTMF:/* DTMF detected by Hardware */
00322         DBG_MAIN("DTMF Event: Digit: %c (Port: %s, Type:%s)!\n",
00323             wp_tdm_api_event->wp_api_event_dtmf_digit,
00324             (wp_tdm_api_event->wp_api_event_dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT",
00325             (wp_tdm_api_event->wp_api_event_dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP");
00326 
00327         break;
00328 
00329     case WP_API_EVENT_RXHOOK:
00330         DBG_MAIN("RXHOOK Event: %s! (0x%X)\n", 
00331             WAN_EVENT_RXHOOK_DECODE(wp_tdm_api_event->wp_api_event_hook_state),
00332             wp_tdm_api_event->wp_api_event_hook_state);
00333         break;
00334 
00335     case WP_API_EVENT_RING_DETECT:
00336         DBG_MAIN("RING Event: %s! (0x%X)\n",
00337             WAN_EVENT_RING_DECODE(wp_tdm_api_event->wp_api_event_ring_state),
00338             wp_tdm_api_event->wp_api_event_ring_state);
00339         break;
00340 
00341     case WP_API_EVENT_RING_TRIP_DETECT:
00342         DBG_MAIN("RING TRIP Event: %s! (0x%X)\n", 
00343             WAN_EVENT_RING_TRIP_DECODE(wp_tdm_api_event->wp_api_event_ring_state),
00344             wp_tdm_api_event->wp_api_event_ring_state);
00345         break;
00346 
00347     case WP_API_EVENT_RBS:
00348         DBG_MAIN("RBS Event: New bits: 0x%X!\n",    wp_tdm_api_event->wp_api_event_rbs_bits);
00349         DBG_MAIN( "RX RBS: A:%1d B:%1d C:%1d D:%1d\n",
00350             (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_A) ? 1 : 0,
00351             (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_B) ? 1 : 0,
00352             (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_C) ? 1 : 0,
00353             (wp_tdm_api_event->wp_api_event_rbs_bits & WAN_RBS_SIG_D) ? 1 : 0);
00354         break;
00355 
00356     case WP_API_EVENT_LINK_STATUS:
00357         DBG_MAIN("Link Status Event: %s! (0x%X)\n", 
00358             WAN_EVENT_LINK_STATUS_DECODE(wp_tdm_api_event->wp_api_event_link_status),
00359             wp_tdm_api_event->wp_api_event_link_status);
00360         break;
00361 
00362     case WP_API_EVENT_ALARM:
00363         DBG_MAIN("New Alarm State: 0x%X\n", wp_tdm_api_event->wp_api_event_alarm);
00364         break;
00365 
00366     default:
00367         ERR_MAIN("Unknown TDM API Event: %d\n", wp_tdm_api_event->wp_api_event_type);
00368         break;
00369     }
00370 
00371     free(lpdwParam);
00372     LeaveCriticalSection(&TdmEventCriticalSection);
00373     //Done with the Event, exit the thread.
00374     return 0;
00375 }
00376 
00377 
00385 int tx_file(sangoma_interface *sang_if)
00386 {
00387     FILE            *pFile;
00388     unsigned int    tx_counter=0, bytes_read_from_file, total_bytes_read_from_file=0;
00389     wp_api_hdr_t    hdr;
00390     unsigned char   local_tx_data[MAX_NO_DATA_BYTES_IN_FRAME];
00391 
00392     pFile = fopen( program_settings.szTxFileName, "rb" );
00393     if( pFile == NULL){
00394         ERR_MAIN( "Can't open file: [%s]\n", program_settings.szTxFileName );
00395         return 1;
00396     }
00397 
00398     do
00399     {
00400         //read tx data from the file. if 'bytes_read_from_file != txlength', end of file is reached
00401         bytes_read_from_file = fread( local_tx_data, 1, program_settings.txlength /* MTU size */, pFile );
00402         total_bytes_read_from_file += bytes_read_from_file;
00403 
00404         hdr.data_length = program_settings.txlength;//ALWAYS transmit MTU size over the BitStream/Voice interface
00405         hdr.operation_status = SANG_STATUS_TX_TIMEOUT;
00406         
00407         if(SANG_STATUS_SUCCESS != sang_if->transmit(&hdr, local_tx_data)){
00408             //error
00409             break;
00410         }
00411         
00412         tx_counter++;
00413         
00414         //DBG_MAIN("tx_counter: %u\r",tx_counter);
00415 
00416     }while(bytes_read_from_file == program_settings.txlength);
00417 
00418     INFO_MAIN("%s: Finished transmitting file \"%s\" (tx_counter: %u, total_bytes_read_from_file: %d)\n",
00419         sang_if->device_name, program_settings.szTxFileName, tx_counter, total_bytes_read_from_file);
00420 
00421     fclose( pFile );
00422     return 0;
00423 }
00424 
00430 static int get_user_decimal_number()
00431 {
00432     int result = 1;
00433     int retry_counter = 0;
00434 
00435     while(scanf("%d", &result) == 0){
00436         fflush( stdin );
00437         INFO_MAIN("\nError: Not a numerical input!!\n");
00438         if(retry_counter++ > 10){
00439             INFO_MAIN("giving up...\n");
00440             result = 1;
00441             break;
00442         }
00443     }//while()
00444 
00445     INFO_MAIN("User input: %d\n", result);
00446     return result;
00447 }
00448 
00454 static int get_user_hex_number()
00455 {
00456     int result = 1;
00457     int retry_counter = 0;
00458 
00459     while(scanf("%x", &result) == 0){
00460         fflush( stdin );
00461         INFO_MAIN("\nError: Not a HEX input!!\n");
00462         if(retry_counter++ > 10){
00463             INFO_MAIN("giving up...\n");
00464             result = 1;
00465             break;
00466         }
00467     }//while()
00468 
00469     INFO_MAIN("User input: 0x%X\n", result);
00470     return result;
00471 }
00472 
00481 static int parse_command_line_args(int argc, char* argv[])
00482 {
00483     int i;
00484     const char *USAGE_STR =
00485 "\n"
00486 "Usage: sample [-c] [-i] [-silent]\n"
00487 "\n"
00488 "Options:\n"
00489 "\t-c       number  Wanpipe number: 1,2,3...\n"
00490 "\t-i       number  Interface number 0,1,2,3,....\n"
00491 "\t-driver_config   configure start/stop driver using volatile....\n"
00492 "\t-silent          Disable display of Rx data\n"
00493 "\t-rx2tx           All received data automatically transmitted on the SAME interface\n"
00494 "\t-txlength\tnumber\tLength of data frames to be transmitted when 't' key is pressed\n"
00495 "\t-txcount\tnumber Number of test data frames to be transmitted when 't' key is pressed\n"
00496 "\t-tx_file_name\tstring\tFile to be transmitted when 't' key is pressed\n"
00497 #if USE_STELEPHONY_API
00498 "\t-decode_fsk_cid\t\tDecode FSK Caller ID on an Analog line. For Voice data only.\n"
00499 "\t-encode_fsk_cid\t\tEncode FSK Caller ID on an Analog line. For Voice data only.\n"
00500 "\t-encode_sw_dtmf\t\tEncode SW DTMF on an line. For Voice data only.\n"
00501 "\t-sw_dtmf     Enable Sangoma Software DTMF decoder. For Voice data only.\n"
00502 "\t-decode_q931     Enable Sangoma Q931 decoder. For HDLC (Dchannel) data only.\n"
00503 "\t-alaw\t\t    Use Alaw codec instead of default MuLaw codec for Voice data.\n"
00504 #endif
00505 "\n"
00506 "Example: sample -c 1 -i 1\n";
00507 
00508     memset(&program_settings, 0, sizeof(wp_program_settings_t));
00509     program_settings.wanpipe_number = 1;
00510     program_settings.interface_number = 1;
00511     program_settings.txlength = 128;
00512     program_settings.txcount = 1;
00513 
00514     
00515     for(i = 1; i < argc;){
00516     
00517         if(_stricmp(argv[i], "-silent") == 0){
00518             INFO_MAIN("disabling Rx data display...\n");
00519             program_settings.silent = 1;
00520         }else if(_stricmp(argv[i], "help") == 0 || _stricmp(argv[i], "?") == 0 || _stricmp(argv[i], "/?") == 0){
00521             INFO_MAIN(USAGE_STR);
00522             return 1;
00523         }else if(_stricmp(argv[i], "-c") == 0){
00524             if (i+1 > argc-1){
00525                 INFO_MAIN("No Wanpipe number was provided!\n");
00526                 return 1;
00527             }
00528             program_settings.wanpipe_number = (uint16_t)atoi(argv[i+1]);
00529             INFO_MAIN("Using wanpipe number %d\n", program_settings.wanpipe_number);
00530             i++;
00531         }else if(_stricmp(argv[i], "-i") == 0){
00532             if (i+1 > argc-1){
00533                 INFO_MAIN("No Interface number was provided!\n");
00534                 return 1;
00535             }
00536             program_settings.interface_number = (uint16_t)atoi(argv[i+1]);
00537             INFO_MAIN("Using interface number %d\n", program_settings.interface_number);
00538             if(program_settings.interface_number < 1){
00539                 ERR_MAIN("Invalid interface number %d!!\n", program_settings.interface_number);
00540                 return 1;
00541             }
00542             i++;
00543         }else if(strcmp(argv[i], "-rx2tx") == 0){
00544             INFO_MAIN("enabling Rx to Tx loopback...\n");
00545             program_settings.Rx_to_Tx_loopback = 1;
00546         }else if(strcmp(argv[i], "-driver_config") == 0){
00547             INFO_MAIN("enabling driver config start/stop\n");
00548             program_settings.driver_config = 1;
00549 
00550         }else if(_stricmp(argv[i], "-txlength") == 0){
00551             if (i+1 > argc-1){
00552                 INFO_MAIN("No txlength provided!\n");
00553                 return 1;
00554             }
00555             program_settings.txlength = (uint16_t)atoi(argv[i+1]);
00556             INFO_MAIN("Setting txlength to %d bytes.\n", program_settings.txlength);
00557             i++;
00558         }else if(_stricmp(argv[i], "-txcount") == 0){
00559             if (i+1 > argc-1){
00560                 INFO_MAIN("No txcount provided!\n");
00561                 return 1;
00562             }
00563             program_settings.txcount = atoi(argv[i+1]);
00564             i++;
00565             INFO_MAIN("Setting txcount to %d.\n", program_settings.txcount);
00566 #if USE_STELEPHONY_API
00567         }else if(_stricmp(argv[i], "-decode_fsk_cid") == 0){
00568             INFO_MAIN("enabling FSK Caller ID decoder...\n");
00569             program_settings.decode_fsk_cid = 1;
00570             callback_functions.FSKCallerIDEvent = FSKCallerIDEvent;
00571         }else if(_stricmp(argv[i], "-sw_dtmf") == 0){
00572             INFO_MAIN("enabling Software DTMF decoder...\n");
00573             program_settings.sw_dtmf = 1;
00574             callback_functions.DTMFEvent = DTMFEvent;
00575         }else if(_stricmp(argv[i], "-decode_q931") == 0){
00576             INFO_MAIN("enabling Q931 decoder...\n");
00577             program_settings.decode_q931 = 1;
00578             callback_functions.Q931Event = Q931Event;
00579         }else if(_stricmp(argv[i], "-encode_fsk_cid") == 0){
00580             INFO_MAIN("enabling FSK Caller ID encoder...\n");
00581             program_settings.encode_fsk_cid = 1;
00582             callback_functions.FSKCallerIDTransmit = FSKCallerIDTransmit;
00583         }else if(_stricmp(argv[i], "-encode_sw_dtmf") == 0){
00584             INFO_MAIN("enabling Software DTMF encoder...\n");
00585             program_settings.encode_sw_dtmf = 1;
00586             callback_functions.SwDtmfTransmit = SwDtmfTransmit;
00587         }else if(_stricmp(argv[i], "-alaw") == 0){
00588             INFO_MAIN("enabling ALaw codec...\n");
00589             program_settings.voice_codec_alaw = 1;
00590 #endif//USE_STELEPHONY_API
00591         }else if(_stricmp(argv[i], "-tx_file_name") == 0){
00592             if (i+1 > argc-1){
00593                 INFO_MAIN("No TxFileName provided!\n");
00594                 return 1;
00595             }
00596             strcpy(program_settings.szTxFileName, argv[i+1]);
00597             i++;
00598             INFO_MAIN("Setting szTxFileName to '%s'.\n", program_settings.szTxFileName);
00599         }else{
00600             INFO_MAIN("Error: Invalid Argument %s\n",argv[i]);
00601             return 1;
00602         }
00603         i++;
00604     }
00605     return 0;
00606 }
00607 
00608 
00624 int __cdecl main(int argc, char* argv[])
00625 {
00626     int     rc, user_selection,err;
00627     sangoma_interface   *sang_if = NULL;
00628     wp_api_hdr_t        hdr;
00629     unsigned char       local_tx_data[MAX_NO_DATA_BYTES_IN_FRAME];
00630     UCHAR               tx_test_byte = 0;
00631 
00633     memset(&callback_functions, 0x00, sizeof(callback_functions));
00634     callback_functions.got_rx_data = got_rx_data;
00635     callback_functions.got_TdmApiEvent = got_TdmApiEvent;
00636 
00638     if(parse_command_line_args(argc, argv)){
00639         return 1;
00640     }
00641 
00643     //An OPTIONAL step of setting the port configuration to different values from
00644     //what is set in "Device Manager"-->"Sangoma Hardware Abstraction Driver".
00645 
00646     //set port configration and exit
00647     if (program_settings.driver_config) {
00648         err=set_port_configuration();
00649         if (err) {
00650             return err;
00651         }
00652     }
00653 
00655     //initialize critical section objects
00656     InitializeCriticalSection(&PrintCriticalSection);
00657     InitializeCriticalSection(&TdmEventCriticalSection);
00658 
00660     //User may provide Wanpipe Number and Interface Number as a command line arguments:
00661     INFO_MAIN("Using wanpipe_number: %d, interface_number: %d\n", program_settings.wanpipe_number, program_settings.interface_number);
00662 
00663     sang_if = init(program_settings.wanpipe_number, program_settings.interface_number);
00664 
00665     if(sang_if == NULL){
00666         return 1;
00667     }
00668 
00669     rc = start(sang_if);
00670     if(rc){
00671         cleanup(sang_if);
00672         return rc;
00673     }
00674 
00675     do{
00676         EnterCriticalSection(&PrintCriticalSection);
00677         INFO_MAIN("Press 'q' to quit the program.\n");
00678         INFO_MAIN("Press 't' to transmit data.\n");
00679         INFO_MAIN("Press 's' to get Operational Statistics.\n");
00680         INFO_MAIN("Press 'f' to reset (flush) Operational Statistics.\n");
00681         INFO_MAIN("Press 'v' to get API driver version.\n");
00682 
00683         if(sang_if->get_adapter_type() == WAN_MEDIA_T1 || sang_if->get_adapter_type() == WAN_MEDIA_E1){
00684             INFO_MAIN("Press 'a' to get T1/E1 alarms.\n");
00685             //RBS (CAS) commands
00686             INFO_MAIN("Press 'g' to get RBS bits.\n");
00687             INFO_MAIN("Press 'r' to set RBS bits.\n");
00688             INFO_MAIN("Press '1' to read FE register. Warning: used by Sangoma Techsupport only!\n");
00689             INFO_MAIN("Press '2' to write FE register.  Warning: used by Sangoma Techsupport only!\n");
00690         }
00691         INFO_MAIN("Press 'i' to set Tx idle data buffer (BitStream only).\n");
00692         switch(sang_if->get_adapter_type())
00693         {
00694         case WAN_MEDIA_T1:
00695             //those commands valid only for T1
00696             INFO_MAIN("Press 'l' to send 'activate remote loop back' signal.\n");
00697             INFO_MAIN("Press 'd' to send 'deactivate remote loop back' signal.\n");
00698             break;
00699         case WAN_MEDIA_FXOFXS:
00700             switch(sang_if->get_sub_media())
00701             {
00702             case MOD_TYPE_FXS:
00703                 INFO_MAIN("Press 'e' to listen to test tones on a phone connected to the A200-FXS\n");
00704                 INFO_MAIN("Press 'c' to ring/stop ring phone connected to the A200-FXS\n");
00705                 INFO_MAIN("Press 'n' to enable/disable reception of ON/OFF Hook events on A200-FXS\n");
00706                 INFO_MAIN("Press 'm' to enable DTMF events (on SLIC chip) on A200-FXS\n");
00707                 INFO_MAIN("Press 'j' to enable/disable reception of Ring Trip events on A200-FXS\n");
00708                 break;
00709 
00710             case MOD_TYPE_FXO:
00711                 INFO_MAIN("Press 'u' to enable/disable reception of Ring Detect events on A200-FXO\n");
00712                 INFO_MAIN("Press 'h' to transmit ON/OFF hook signals on A200-FXO\n");
00713                 INFO_MAIN("Press 'a' to get Line Status (Connected/Disconnected)\n");
00714                 break;
00715             }
00716             break;
00717         case WAN_MEDIA_BRI:
00718             INFO_MAIN("Press 'k' to Activate/Deactivate ISDN BRI line\n");
00719             INFO_MAIN("Press 'l' to enable  bri bchan loopback\n");
00720             INFO_MAIN("Press 'd' to disable bri bchan loopback\n");
00721             break;
00722         }
00723         INFO_MAIN("Press 'o' to enable DTMF events (on Octasic chip)\n");
00724         if (program_settings.encode_sw_dtmf) {
00725             INFO_MAIN("Press 'x' to send software DTMF\n");
00726         }
00727         if (program_settings.encode_fsk_cid) {
00728             INFO_MAIN("Press 'z' to send software FSK Caller ID\n");
00729         }
00730 
00731         LeaveCriticalSection(&PrintCriticalSection);
00732 
00733         user_selection = tolower(_getch());
00734         switch(user_selection)
00735         {
00736         case 'q':
00737             break;
00738         case 't':
00739             for(u_int32_t cnt = 0; cnt < program_settings.txcount; cnt++){
00740                 if(program_settings.szTxFileName[0]){
00741                     tx_file(sang_if);
00742                 }else{
00743                     hdr.data_length = program_settings.txlength;
00744                     hdr.operation_status = SANG_STATUS_TX_TIMEOUT;
00745                     //set the actual data for transmission
00746                     memset(local_tx_data, tx_test_byte, program_settings.txlength);
00747                     sang_if->transmit(&hdr, local_tx_data);
00748                     tx_test_byte++;
00749                 }
00750             }
00751             break;
00752         case 's':
00753             {
00754                 wanpipe_chan_stats_t stats;
00755                 sang_if->get_operational_stats(&stats);
00756             }
00757             break;
00758         case 'f':
00759             sang_if->flush_operational_stats();
00760             break;
00761         case 'v':
00762             {
00763                 DRIVER_VERSION version;
00764                 //read API driver version
00765                 sang_if->get_api_driver_version(&version);
00766                 INFO_MAIN("\nAPI version\t: %d,%d,%d,%d\n",
00767                     version.major, version.minor, version.minor1, version.minor2);
00768 
00769                 u_int8_t customer_id = 0;
00770                 sang_if->get_card_customer_id(&customer_id);
00771                 INFO_MAIN("\ncustomer_id\t: 0x%02X\n", customer_id);
00772             }
00773             break;
00774         case 'a':
00775             unsigned char cFeStatus;
00776 
00777             switch(sang_if->get_adapter_type())
00778             {
00779             case WAN_MEDIA_T1:
00780             case WAN_MEDIA_E1:
00781                 //read T1/E1/56k alarms
00782                 sang_if->get_te1_56k_stat();
00783                 break;
00784 
00785             case WAN_MEDIA_FXOFXS:
00786                 switch(sang_if->get_sub_media())
00787                 {
00788                 case MOD_TYPE_FXO:
00789                     cFeStatus = 0;
00790                     sang_if->tdm_get_front_end_status(&cFeStatus);
00791                     INFO_MAIN("cFeStatus: %s (%d)\n", FE_STATUS_DECODE(cFeStatus), cFeStatus);
00792                     break;
00793                 }
00794             }
00795             break;
00796         case 'l':
00797             switch(sang_if->get_adapter_type())
00798             {
00799             case WAN_MEDIA_T1:
00800             case WAN_MEDIA_E1:
00801                 //Activate Line/Remote Loopback mode:
00802                 sang_if->set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE);
00803                 //Activate Diagnostic Digital Loopback mode:
00804                 //sang_if->set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE);
00805                 //sang_if->set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE);
00806                 break;
00807             case WAN_MEDIA_BRI:
00808                 sang_if->tdm_enable_bri_bchan_loopback(WAN_BRI_BCHAN1);
00809                 break;
00810             }
00811             break;
00812         case 'd':
00813             switch(sang_if->get_adapter_type())
00814             {
00815             case WAN_MEDIA_T1:
00816             case WAN_MEDIA_E1:
00817                 //Deactivate Line/Remote Loopback mode:
00818                 sang_if->set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE);
00819                 //Deactivate Diagnostic Digital Loopback mode:
00820                 //sang_if->set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE);
00821                 //sang_if->set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE);
00822                 break;
00823             case WAN_MEDIA_BRI:
00824                 sang_if->tdm_disable_bri_bchan_loopback(WAN_BRI_BCHAN1);
00825                 break;
00826             }
00827             break;
00828         case 'g'://read RBS bits
00829             switch(sang_if->get_adapter_type())
00830             {
00831             case WAN_MEDIA_T1:
00832             case WAN_MEDIA_E1:
00833                 {
00834                     rbs_management_t rbs_management_struct = {0,0};
00835 
00836                     sang_if->enable_rbs_monitoring();
00837 
00838                     INFO_MAIN("Type Channel number and press <Enter>:\n");
00839                     rbs_management_struct.channel = get_user_decimal_number();//channels (Time Slots). Valid values: 1 to 24.
00840                     if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 24){
00841                         INFO_MAIN("Invalid RBS Channel number!\n");
00842                         break;
00843                     }
00844                     sang_if->get_rbs(&rbs_management_struct);
00845                 }
00846                 break;
00847             default:
00848                 INFO_MAIN("Command invalid for card type\n");
00849                 break;
00850             }//switch()
00851             break;
00852         case 'r'://set RBS bits
00853             switch(sang_if->get_adapter_type())
00854             {
00855             case WAN_MEDIA_T1:
00856             case WAN_MEDIA_E1:
00857                 {
00858                     static rbs_management_t rbs_management_struct = {0,0};
00859 
00860                     sang_if->enable_rbs_monitoring();
00861 
00862                     INFO_MAIN("Type Channel number and press <Enter>:\n");
00863                     rbs_management_struct.channel = get_user_decimal_number();//channels (Time Slots). Valid values: 1 to 24.
00864                     if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 24){
00865                         INFO_MAIN("Invalid RBS Channel number!\n");
00866                         break;
00867                     }
00868                     /*  bitmap - set as needed: WAN_RBS_SIG_A | WAN_RBS_SIG_B | WAN_RBS_SIG_C | WAN_RBS_SIG_D;
00869 
00870                     In this example make bits A and B to change each time,
00871                     so it's easy to see the change on the receiving side.
00872                     */
00873                     if(rbs_management_struct.ABCD_bits == WAN_RBS_SIG_A){
00874                         rbs_management_struct.ABCD_bits = WAN_RBS_SIG_B;
00875                     }else{
00876                         rbs_management_struct.ABCD_bits = WAN_RBS_SIG_A;
00877                     }
00878                     sang_if->set_rbs(&rbs_management_struct);
00879                 }
00880             default:
00881                 INFO_MAIN("Command invalid for card type\n");
00882                 break;
00883             }//switch()
00884             break;
00885         case 'i':
00886             {
00887                 INFO_MAIN("Type Idle Flag (HEX, for example: FE) and press <Enter>:\n");
00888                 unsigned char new_idle_flag = (unsigned char)get_user_hex_number();
00889                 sang_if->set_tx_idle_flag(new_idle_flag);
00890             }
00891             break;
00892         case 'c':
00893 user_retry_ring_e_d:
00894             INFO_MAIN("Press 'e' to START ring, 'd' to STOP ring, 't' to Toggle\n");
00895             INFO_MAIN("\n");
00896             user_selection = tolower(_getch());
00897             switch(user_selection)
00898             {
00899             case 'e':
00900                 INFO_MAIN("Starting Ring ...%c\n",user_selection);
00901                 sang_if->start_ringing_phone();//start
00902                 break;
00903             case 'd':
00904                 INFO_MAIN("Stopping Ring ... %c\n",user_selection);
00905                 sang_if->stop_ringing_phone();//stop
00906                 break;
00907             case 't':
00908                 {
00909                     int x;
00910                     for (x=0;x<500;x++) {
00911                         sang_if->start_ringing_phone();
00912                         sang_if->start_ringing_phone();
00913                         //sangoma_msleep(500);
00914                         sang_if->stop_ringing_phone();//stop
00915                         sang_if->stop_ringing_phone();//stop
00916                         //sangoma_msleep(500);
00917                         sang_if->start_busy_tone();
00918                         sangoma_msleep(50);
00919                         sang_if->stop_all_tones();
00920                         sangoma_msleep(50);
00921                     }
00922                 }
00923                 break;
00924             default:
00925                 goto user_retry_ring_e_d;
00926                 break;
00927             }
00928             break;
00929         case 'e':
00930             INFO_MAIN("Press 'e' to START a Tone, 'd' to STOP a Tone.\n");
00931             INFO_MAIN("\n");
00932 
00933             switch(tolower(_getch()))
00934             {
00935             case 'e':
00936                 INFO_MAIN("Press 'r' for Ring Tone, 'd' for Dial Tone, 'b' for Busy Tone, 'c' for Congestion Tone.\n");
00937                 INFO_MAIN("\n");
00938                 switch(tolower(_getch()))
00939                 {
00940                 case 'r':
00941                     sang_if->start_ring_tone();
00942                     break;
00943                 case 'd':
00944                     sang_if->start_dial_tone();
00945                     break;
00946                 case 'b':
00947                     sang_if->start_busy_tone();
00948                     break;
00949                 case 'c':
00950                 default:
00951                     sang_if->start_congestion_tone();
00952                     break;
00953                 }
00954                 break;
00955 
00956             case 'd':
00957             default:
00958                 sang_if->stop_all_tones();//stop all tones
00959             }
00960             break;
00961         case 'n':
00962             INFO_MAIN("Press 'e' to ENABLE Rx Hook Events, 'd' to DISABLE Rx Hook Events.\n");
00963             INFO_MAIN("\n");
00964             switch(tolower(_getch()))
00965             {
00966             case 'e':
00967                 sang_if->tdm_enable_rxhook_events();
00968                 break;
00969             case 'd':
00970             default:
00971                 sang_if->tdm_disable_rxhook_events();
00972             }
00973             break;
00974         case 'm':
00975             //Enable/Disable DTMF events on SLIC chip.
00976             //On Analog (A200) card only.
00977             INFO_MAIN("Press 'e' to ENABLE Remora DTMF Events, 'd' to DISABLE Remora DTMF Events.\n");
00978             INFO_MAIN("\n");
00979             switch(tolower(_getch()))
00980             {
00981             case 'e':
00982                 sang_if->tdm_enable_rm_dtmf_events();
00983                 break;
00984             case 'd':
00985             default:
00986                 sang_if->tdm_disable_rm_dtmf_events();
00987             }
00988             break;
00989         case 'o':
00990             {
00991                 //Enable DTMF events on Octasic chip. 
00992                 //For both Analog (A200) and T1/E1 (A104D) cards, but only if the chip is present.
00993                 INFO_MAIN("Press 'e' to ENABLE Octasic DTMF Events, 'd' to DISABLE Octasic DTMF Events.\n");
00994                 uint8_t channel;
00995 
00996                 INFO_MAIN("\n");
00997                 switch(tolower(_getch()))
00998                 {
00999                 case 'e':
01000                     INFO_MAIN("Type Channel number and press <Enter>:\n");
01001                     channel = (uint8_t)get_user_decimal_number();//channels (Time Slots). Valid values: 1 to 31.
01002 
01003                     sang_if->tdm_enable_dtmf_events(channel);
01004                     break;
01005                 case 'd':
01006                 default:
01007                     INFO_MAIN("Type Channel number and press <Enter>:\n");
01008                     channel = (uint8_t)get_user_decimal_number();//channels (Time Slots). Valid values: 1 to 31.
01009 
01010                     sang_if->tdm_disable_dtmf_events(channel);
01011                 }
01012             }
01013             break;
01014         case 'u':
01015             //Enable/Disable Ring Detect events on FXO. 
01016             INFO_MAIN("Press 'e' to ENABLE Rx Ring Detect Events, 'd' to DISABLE Rx Ring Detect Events.\n");
01017             INFO_MAIN("\n");
01018             switch(tolower(_getch()))
01019             {
01020             case 'e':
01021                 sang_if->tdm_enable_ring_detect_events();
01022                 break;
01023             case 'd':
01024             default:
01025                 sang_if->tdm_disable_ring_detect_events();
01026             }
01027             break;
01028         case 'j':
01029             //Enable/Disable Ring Trip events on FXS. 
01030             INFO_MAIN("Press 'e' to ENABLE Rx Ring Trip Events, 'd' to DISABLE Rx Ring Trip Events.\n");
01031             INFO_MAIN("\n");
01032             switch(tolower(_getch()))
01033             {
01034             case 'e':
01035                 sang_if->tdm_enable_ring_trip_detect_events();
01036                 break;
01037             case 'd':
01038             default:
01039                 sang_if->tdm_disable_ring_trip_detect_events();
01040             }
01041             break;
01042         case 'h':
01043             INFO_MAIN("Press 'e' to transmit OFF hook signal, 'd' to transmit ON hook signal.\n");
01044             INFO_MAIN("\n");
01045             switch(tolower(_getch()))
01046             {
01047             case 'e':
01048                 sang_if->fxo_go_off_hook();
01049                 break;
01050             case 'd':
01051             default:
01052                 sang_if->fxo_go_on_hook();
01053             }
01054             break;
01055         case 'k':
01056             INFO_MAIN("Press 'e' to Activate, 'd' to De-Activate line.\n");
01057             INFO_MAIN("\n");
01058             switch(tolower(_getch()))
01059             {
01060             case 'e':
01061                 sang_if->tdm_front_end_activate();
01062                 break;
01063             case 'd':
01064             default:
01065                 sang_if->tdm_front_end_deactivate();
01066             }
01067             break;
01068         case 'p':
01069             {
01070                 int user_period;//Milliseconds interval between receive of Voice Data
01071                 INFO_MAIN("Type User Period and press <Enter>. Valid values are: 10, 20, 40.\n");
01072                 user_period = get_user_decimal_number();
01073                 switch(user_period)
01074                 {
01075                 case 10:
01076                 case 20:
01077                 case 40:
01078                     sang_if->tdm_set_user_period(user_period);
01079                     break;
01080                 default:
01081                     INFO_MAIN("Invalid User Period value! Valid values are: 10, 20, 40.\n");
01082                     break;
01083                 }
01084             }
01085             break;
01086 #if USE_STELEPHONY_API
01087         case 'x':
01088             {   
01089                 INFO_MAIN("Press a key. Valid values are 0-9, A-C\n");
01090                 int user_char = _getch();
01091                 switch(tolower(user_char)) {
01092                     case '1': case '2': case '3':
01093                     case '4': case '5': case '6':
01094                     case '7': case '8': case '9':
01095                     case '0': case 'a': case 'b':
01096                     case 'c':
01097                         INFO_MAIN("Sending DTMF (%c).\n", user_char);
01098                         sang_if->sendSwDTMF((char)user_char);
01099                         break;
01100                     default:
01101                         INFO_MAIN("Invalid DTMF Char! Valid values are: 0-9, A-C\n");
01102                     break;
01103                 }
01104             }
01105             break;
01106         case 'z':
01107             {
01108                 INFO_MAIN("Sending CallerID.\n");
01109                 sang_if->sendCallerID("Sangoma Rocks", "9054741990");
01110             }
01111             break;
01112 #endif
01113         case '1':/* read FE register */
01114             {
01115                 int value;
01116                 sdla_fe_debug_t fe_debug;
01117 
01118                 fe_debug.type = WAN_FE_DEBUG_REG;
01119 
01120                 printf("Type Register number (hex) i.g. F8 and press Enter:");
01121                 value = get_user_hex_number();
01122 
01123                 fe_debug.fe_debug_reg.reg  = value;
01124                 fe_debug.fe_debug_reg.read = 1;
01125 
01126                 sang_if->set_fe_debug_mode(&fe_debug);
01127             }
01128             break;
01129 
01130         case '2':/* write FE register */
01131             {
01132                 int value;
01133                 sdla_fe_debug_t fe_debug;
01134                 fe_debug.type = WAN_FE_DEBUG_REG;
01135 
01136                 printf("WRITE: Type Register number (hex) i.g. F8 and press Enter:");
01137                 value = get_user_hex_number();
01138 
01139                 fe_debug.fe_debug_reg.reg  = value;
01140                 fe_debug.fe_debug_reg.read = 1;
01141 
01142                 printf("WRITE: Type value (hex) i.g. 1A and press Enter:");
01143                 value = get_user_hex_number();
01144 
01145                 fe_debug.fe_debug_reg.read = 0;
01146                 fe_debug.fe_debug_reg.value = (unsigned char)value;
01147 
01148                 sang_if->set_fe_debug_mode(&fe_debug);
01149             }
01150             break;
01151 
01152         default:
01153             INFO_MAIN("Invalid command.\n");
01154         }       
01155     }while(user_selection != 'q');
01156 
01157     stop(sang_if);
01158     cleanup(sang_if);
01159 
01160     return 0;
01161 }//main()
01162 
01163 static int set_port_configuration()
01164 {
01165     int             rc = 0, is_te1_card = 0, user_selection;
01166     hardware_info_t hardware_info;
01167     port_cfg_t      port_cfg;
01168 
01169     sangoma_port_configurator *sng_port_cfg_obj;
01170 
01171     sng_port_cfg_obj = new sangoma_port_configurator();
01172     if(sng_port_cfg_obj == NULL || sng_port_cfg_obj->init((unsigned short)program_settings.wanpipe_number)){
01173         return 2;
01174     }
01175 
01176     rc = sng_port_cfg_obj->get_hardware_info(&hardware_info);
01177 
01178     if(rc == SANG_STATUS_SUCCESS){
01179 
01180         INFO_MAIN("card_model       : %s (0x%08X)\n",
01181             SDLA_ADPTR_NAME(hardware_info.card_model), hardware_info.card_model);
01182         INFO_MAIN("firmware_version\t: 0x%02X\n", hardware_info.firmware_version);
01183         INFO_MAIN("pci_bus_number\t\t: %d\n", hardware_info.pci_bus_number);
01184         INFO_MAIN("pci_slot_number\t\t: %d\n", hardware_info.pci_slot_number);
01185         INFO_MAIN("max_hw_ec_chans\t\t: %d\n", hardware_info.max_hw_ec_chans);
01186         INFO_MAIN("port_number\t\t: %d\n", hardware_info.port_number);
01187 
01188     }else{
01189         delete sng_port_cfg_obj;
01190         return 3;
01191     }
01192 
01193 #if 0
01194 defined(__WINDOWS__)
01195     rc = sng_port_cfg_obj->open_port_registry_key(&hardware_info);
01196     if(rc != SANG_STATUS_SUCCESS){
01197         delete sng_port_cfg_obj;
01198         return 3;
01199     }
01200 #endif
01201 
01202     memset(&port_cfg, 0x00, sizeof(port_cfg_t));
01203 
01204     switch(hardware_info.card_model)
01205     {
01206     case A101_ADPTR_1TE1:
01207     case A101_ADPTR_2TE1:
01208     case A104_ADPTR_4TE1:
01209     case A108_ADPTR_8TE1:
01210         is_te1_card = 1;
01211         break;
01212     }
01213 
01214     if(is_te1_card){
01215 
01216         INFO_MAIN("\n");
01217         INFO_MAIN("Press 't' to set T1 configration.\n");
01218         INFO_MAIN("Press 'e' to set E1 configration.\n");
01219 
01220 try_again:
01221         user_selection = tolower(_getch());
01222 
01223         switch(user_selection)
01224         {
01225         case 't'://T1
01226 
01227             rc=sng_port_cfg_obj->set_t1_tdm_span_voice_api_configration(&port_cfg,&hardware_info,program_settings.wanpipe_number);
01228             break;
01229         case 'e'://E1
01230 
01231             rc=sng_port_cfg_obj->set_e1_tdm_span_voice_api_configration(&port_cfg,&hardware_info,program_settings.wanpipe_number);
01232             break;
01233 
01234         default:
01235             INFO_MAIN("Invalid command %c.\n",user_selection);
01236             goto try_again;
01237             break;
01238         }//switch(user_selection)
01239 
01240     } else { //if(is_te1_card)
01241         INFO_MAIN("Unsupported Card %i\n",hardware_info.card_model);
01242 
01243         rc=1;
01244 #if 0
01245         //print the current configuration:
01246         sng_port_cfg_obj->print_port_cfg_structure(&port_cfg);
01247 
01248         //as an EXAMPLE, set the same configration as the current one:
01249         rc = sng_port_cfg_obj->set_default_configuration(&port_cfg);
01250 #endif
01251 
01252     }
01253 
01254     if (rc==0) {
01255         INFO_MAIN("Stopping PORT!\n");
01256         rc=sng_port_cfg_obj->stop_port();
01257         if (rc == 0) {
01258             INFO_MAIN("Configuring PORT!\n");
01259             rc=sng_port_cfg_obj->set_volatile_configration(&port_cfg);
01260             if (rc == 0) {
01261                 INFO_MAIN("Starting PORT!\n");
01262                 rc=sng_port_cfg_obj->start_port();
01263                 if (rc) {
01264                     INFO_MAIN("Error: Failed to Start Port!\n");
01265                 }
01266             } else {
01267                 INFO_MAIN("Error: Failed to Configure Port!\n");
01268             }
01269         } else {
01270             INFO_MAIN("Error: Failed to Stop Port!\n");
01271         }
01272 
01273     } else {
01274         INFO_MAIN("Error: Failed to Set Configuratoin Port!\n");
01275     }
01276 
01277     if(sng_port_cfg_obj != NULL){
01278         delete sng_port_cfg_obj;
01279     }
01280 
01281     sangoma_msleep(2000);
01282 
01283     return rc;
01284 }
01285 
01286 
01287 #if USE_STELEPHONY_API
01288 static void FSKCallerIDEvent(void *callback_context,
01289                              char * Name, char * CallerNumber,
01290                              char * CalledNumber, char * DateTime)
01291 {
01292     //The "sangoma_interface" object was registered as the callback context in StelSetup() call.
01293     sangoma_interface   *sang_if = (sangoma_interface*)callback_context;
01294 
01295     INFO_MAIN("\n%s: %s() - Start\n", sang_if->device_name, __FUNCTION__);
01296 
01297     if(Name){
01298         INFO_MAIN("Name: %s\n", Name);
01299 #if 1
01300         printf("caller name in SINGLE byte hex:\n");
01301         for(unsigned int ind = 0; ind < strlen(Name); ind++){
01302             printf("Name[%02d]: 0x%02X\n", ind, Name[ind]);
01303         }
01304         printf("\n");
01305 
01306         printf("caller name in DOUBLE byte (unicode) hex:\n");
01307         for(unsigned int ind = 0; ind < strlen(Name); ind += 2){
01308             printf("Name[%02d]: 0x%04X\n", ind, *(unsigned short*)&Name[ind]);
01309         }
01310         printf("\n");
01311 #endif
01312     }
01313     if(CallerNumber){
01314         INFO_MAIN("CallerNumber: %s\n", CallerNumber);
01315     }
01316     if(CalledNumber){
01317         INFO_MAIN("CalledNumber: %s\n", CalledNumber);
01318     }
01319     if(DateTime){
01320         INFO_MAIN("DateTime: %s\n", DateTime);
01321     }
01322 
01323     INFO_MAIN("Resetting FSK Caller ID\n");
01324     sang_if->resetFSKCID();//prepare for next FSK CID detection
01325 
01326     INFO_MAIN("%s() - End\n\n", __FUNCTION__);
01327 }
01328 
01329 static void DTMFEvent(void *callback_context, long Key)
01330 {
01331     //The "sangoma_interface" object was registered as the callback context in StelSetup() call.
01332     sangoma_interface   *sang_if = (sangoma_interface*)callback_context;
01333 
01334     INFO_MAIN("\n%s: %s() - Start\n", sang_if->device_name, __FUNCTION__);
01335 
01336     INFO_MAIN("Key: %c\n", (char) Key);
01337 
01338     INFO_MAIN("%s() - End\n\n", __FUNCTION__);
01339 }
01340 
01341 static void Q931Event(void *callback_context, stelephony_q931_event *pQ931Event)
01342 {
01343     //The "sangoma_interface" object was registered as the callback context in StelSetup() call.
01344     sangoma_interface   *sang_if = (sangoma_interface*)callback_context;
01345     
01346     INFO_MAIN("\n%s: %s() - Start\n", sang_if->device_name, __FUNCTION__);
01347 #if 0
01348     INFO_MAIN("\nFound %d bytes of data: ", pQ931Event->dataLength);
01349     for (int i=0; i < pQ931Event->dataLength;i++){
01350         INFO_MAIN("%02X ",pQ931Event->data[i]);
01351     }
01352     INFO_MAIN("\n");
01353 #endif
01354 
01355 
01356     INFO_MAIN("Message Received on: %02d/%02d/%02d @ %02d:%02d:%02d\n",pQ931Event->tv.wMonth,pQ931Event->tv.wDay,pQ931Event->tv.wYear,
01357         pQ931Event->tv.wHour,pQ931Event->tv.wMinute,pQ931Event->tv.wSecond);
01358     
01359     INFO_MAIN("Message Type is: %s\n",pQ931Event->msg_type);
01360     INFO_MAIN("Length of Call Reference Field is: %d\n", pQ931Event->len_callRef);
01361     INFO_MAIN("Message Call Reference is : 0X%s\n",pQ931Event->callRef);
01362 
01363     if (pQ931Event->cause_code > 0){
01364         INFO_MAIN("Cause code found = %d \n", pQ931Event->cause_code);
01365     }
01366 
01367     if (pQ931Event->chan > 0){
01368         INFO_MAIN("B-channel used = %d \n", pQ931Event->chan);
01369     }
01370 
01371     if (pQ931Event->calling_num_digits_count > 0 ){
01372         INFO_MAIN("Found %d digits for calling number \n", pQ931Event->calling_num_digits_count);
01373         INFO_MAIN("Presentation indicator is = %d \n",pQ931Event->calling_num_presentation);
01374         INFO_MAIN("Screening indicator is = %d \n",pQ931Event->calling_num_screening_ind);
01375         INFO_MAIN("Calling number is = %s\n",pQ931Event->calling_num_digits);
01376     }
01377 
01378     if (pQ931Event->called_num_digits_count > 0 ){
01379         INFO_MAIN("Found %d digits for called number \n", pQ931Event->called_num_digits_count);
01380         INFO_MAIN("Called number is = %s\n",pQ931Event->called_num_digits);
01381     }
01382 
01383     if (pQ931Event->rdnis_digits_count > 0 ){
01384         INFO_MAIN("Found %d digits for RDNIS\n", pQ931Event->rdnis_digits_count);
01385         INFO_MAIN("RDNIS is = %s\n",pQ931Event->rdnis_string);
01386     }
01387     //INFO_MAIN("%s() - End\n\n", __FUNCTION__);
01388 }
01389 
01390 /*  A buffer containing DTMF digit was initialized. In this callback transmit the buffer
01391     by starting the SwDtmfTxThread */
01392 static void SwDtmfTransmit (void *callback_context, void *DtmfBuffer)
01393 {   
01394     sangoma_interface   *sang_if = (sangoma_interface*)callback_context;
01395     DBG_MAIN("%s(): %s:\n", __FUNCTION__, sang_if->device_name);
01396 
01397     /*  DTMF buffer can be very big (long DTMF is not uncommon), we don't want to
01398         block the calling thread, so start a new thread to transmit SW-DTMF. */
01399     sang_if->CreateSwDtmfTxThread(DtmfBuffer);
01400 }
01401 
01402 /* A buffer containing FSK CID was initialized. In this callback transmit the buffer. */
01403 static void FSKCallerIDTransmit (void *callback_context, void *FskCidBuffer)
01404 {
01405     sangoma_interface   *sang_if = (sangoma_interface*)callback_context;
01406     DBG_MAIN("%s(): %s:\n", __FUNCTION__, sang_if->device_name);
01407 
01408     /*  FSK CID buffer can be big (~8000 bytes), we don't want to block the calling thread,
01409         so start a new thread to transmit FSK CID. */
01410     sang_if->CreateSwDtmfTxThread(FskCidBuffer);
01411 }
01412 
01413 #if 0
01414 #warning "REMOVE LATER"
01415 int slin2ulaw(void* data, size_t max, size_t *datalen)
01416 {
01417     int16_t sln_buf[512] = {0}, *sln = sln_buf;
01418     uint8_t *lp = (uint8_t*)data;
01419     uint32_t i;
01420     size_t len = *datalen;
01421 
01422     if (max > len) {
01423         max = len;
01424     }
01425 
01426     memcpy(sln, data, max);
01427     
01428     for(i = 0; i < max; i++) {
01429         *lp++ = linear_to_ulaw(*sln++);
01430     }
01431 
01432     *datalen = max / 2;
01433 
01434     return 0;
01435 }
01436 #endif
01437 
01438 #endif /* USE_STELEPHONY_API */
01439 
01440 #if 0
01441 LONG Win32FaultHandler(struct _EXCEPTION_POINTERS *  ExInfo)
01442 
01443 {   
01444     char  *FaultTx = "";
01445     switch(ExInfo->ExceptionRecord->ExceptionCode)
01446     {
01447     case EXCEPTION_ACCESS_VIOLATION: 
01448         FaultTx = "ACCESS VIOLATION";
01449         break;
01450     case EXCEPTION_DATATYPE_MISALIGNMENT: 
01451         FaultTx = "DATATYPE MISALIGNMENT";
01452         break;
01453     case EXCEPTION_FLT_DIVIDE_BY_ZERO: 
01454         FaultTx = "FLT DIVIDE BY ZERO";
01455         break;
01456     default: FaultTx = "(unknown)";           
01457         break;
01458     }
01459 
01460     FILE *sgLogFile = fopen("Win32Fault.log", "w");
01461     int    wsFault    = ExInfo->ExceptionRecord->ExceptionCode;
01462     PVOID  CodeAddress = ExInfo->ExceptionRecord->ExceptionAddress;
01463 
01464     sgLogFile = fopen("Win32Fault.log", "w");
01465     if(sgLogFile != NULL)
01466     {
01467         fprintf(sgLogFile, "****************************************************\n");
01468         fprintf(sgLogFile, "*** A Program Fault occurred:\n");
01469         fprintf(sgLogFile, "*** Error code %08X: %s\n", wsFault, FaultTx);
01470         fprintf(sgLogFile, "****************************************************\n");
01471         fprintf(sgLogFile, "***   Address: %08X\n", (int)CodeAdress);
01472         fprintf(sgLogFile, "***     Flags: %08X\n", 
01473             ExInfo->ExceptionRecord->ExceptionFlags);
01474         LogStackFrames(CodeAddress, (char *)ExInfo->ContextRecord->Ebp);
01475         fclose(sgLogFile);
01476     }
01477     /*if(want to continue)
01478     {
01479         ExInfo->ContextRecord->Eip++;
01480         return EXCEPTION_CONTINUE_EXECUTION;
01481     }
01482     */ 
01483     return EXCEPTION_EXECUTE_HANDLER;
01484 }
01485 #endif

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