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
00050
00051
00052 wp_program_settings_t program_settings;
00053 callback_functions_t callback_functions;
00054
00055
00056
00057
00058
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
00072
00073
00074
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
00083 CRITICAL_SECTION PrintCriticalSection;
00084
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
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
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
00234
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(¶m->event, event_data, sizeof(wp_api_event_t));
00267 param->sang_if_ptr = sang_if_ptr;
00268
00270
00271
00272
00274 #if defined(__WINDOWS__)
00275 DWORD dwThreadId;
00276
00277 if(CreateThread(
00278 NULL,
00279 0,
00280 (LPTHREAD_START_ROUTINE)TdmApiEventThreadFunc,
00281 param,
00282 0,
00283 &dwThreadId
00284 ) == NULL){
00285 ERR_MAIN("Failed to create 'TdmApiEvent' thread!!\n");
00286 }
00287 #else
00288
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 = ¶m->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:
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
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
00401 bytes_read_from_file = fread( local_tx_data, 1, program_settings.txlength , pFile );
00402 total_bytes_read_from_file += bytes_read_from_file;
00403
00404 hdr.data_length = program_settings.txlength;
00405 hdr.operation_status = SANG_STATUS_TX_TIMEOUT;
00406
00407 if(SANG_STATUS_SUCCESS != sang_if->transmit(&hdr, local_tx_data)){
00408
00409 break;
00410 }
00411
00412 tx_counter++;
00413
00414
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 }
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 }
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
00644
00645
00646
00647 if (program_settings.driver_config) {
00648 err=set_port_configuration();
00649 if (err) {
00650 return err;
00651 }
00652 }
00653
00655
00656 InitializeCriticalSection(&PrintCriticalSection);
00657 InitializeCriticalSection(&TdmEventCriticalSection);
00658
00660
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
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
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
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
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
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
00802 sang_if->set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE);
00803
00804
00805
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
00818 sang_if->set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE);
00819
00820
00821
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':
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();
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 }
00851 break;
00852 case 'r':
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();
00864 if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 24){
00865 INFO_MAIN("Invalid RBS Channel number!\n");
00866 break;
00867 }
00868
00869
00870
00871
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 }
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();
00902 break;
00903 case 'd':
00904 INFO_MAIN("Stopping Ring ... %c\n",user_selection);
00905 sang_if->stop_ringing_phone();
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
00914 sang_if->stop_ringing_phone();
00915 sang_if->stop_ringing_phone();
00916
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();
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
00976
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
00992
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();
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();
01009
01010 sang_if->tdm_disable_dtmf_events(channel);
01011 }
01012 }
01013 break;
01014 case 'u':
01015
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
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;
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':
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':
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 }
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':
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':
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 }
01239
01240 } else {
01241 INFO_MAIN("Unsupported Card %i\n",hardware_info.card_model);
01242
01243 rc=1;
01244 #if 0
01245
01246 sng_port_cfg_obj->print_port_cfg_structure(&port_cfg);
01247
01248
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
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();
01325
01326 INFO_MAIN("%s() - End\n\n", __FUNCTION__);
01327 }
01328
01329 static void DTMFEvent(void *callback_context, long Key)
01330 {
01331
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
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
01388 }
01389
01390
01391
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
01398
01399 sang_if->CreateSwDtmfTxThread(DtmfBuffer);
01400 }
01401
01402
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
01409
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
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
01478
01479
01480
01481
01482
01483 return EXCEPTION_EXECUTE_HANDLER;
01484 }
01485 #endif