00001
00035 #include "sample.h"
00036 #include "sangoma_port.h"
00037 #include "sangoma_port_configurator.h"
00038 #include "sangoma_interface.h"
00039
00040 #if defined(__LINUX__)
00041 # include "sample_linux_compat.h"
00042 #else
00043 # include <conio.h>
00044 #endif
00045
00046 #ifndef MAX_PATH
00047 #define MAX_PATH 100
00048 #endif
00049
00050
00051
00052
00053
00054
00055 wp_program_settings_t program_settings;
00056 callback_functions_t callback_functions;
00057
00058
00059
00060
00061
00062
00063 static int got_rx_data(void *sang_if_ptr, void *rxhdr, void *rx_data);
00064 static void got_tdm_api_event(void *sang_if_ptr, void *event_data);
00065 #if USE_WP_LOGGER
00066 static void got_logger_event(void *sang_if_ptr, wp_logger_event_t *logger_event);
00067 #endif
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
00088
00089
00090
00091 #define DBG_MAIN if(1)printf
00092 #define ERR_MAIN printf("%s():line:%d:Error:", __FUNCTION__, __LINE__);printf
00093 #define INFO_MAIN if(1)printf
00094
00095 #define MAIN_FUNC() if(1)printf("%s():line:%d\n", __FUNCTION__, __LINE__)
00096
00097 static int set_port_configuration();
00098
00107 sangoma_interface* init(int wanpipe_number, int interface_number)
00108 {
00109 sangoma_interface *sang_if = NULL;
00110 DBG_MAIN("%s()\n", __FUNCTION__);
00111
00112 if(program_settings.use_ctrl_dev == 1){
00113 sang_if = new sangoma_api_ctrl_dev();
00114 }else if(program_settings.use_logger_dev == 1){
00115 sang_if = new sangoma_api_logger_dev();
00116 }else{
00117 sang_if = new sangoma_interface(wanpipe_number, interface_number);
00118 }
00119
00120 if(sang_if->init(&callback_functions)){
00121 delete sang_if;
00122 return NULL;
00123 }
00124
00125 DBG_MAIN("init(): OK\n");
00126 return sang_if;
00127 }
00128
00135 void cleanup(sangoma_interface *sang_if)
00136 {
00137 DBG_MAIN("cleanup()\n");
00138 if(sang_if){
00139 delete sang_if;
00140 }
00141 }
00142
00149 int start(sangoma_interface *sang_if)
00150 {
00151 DBG_MAIN("start()\n");
00152 return sang_if->run();
00153 }
00154
00161 void stop(sangoma_interface *sang_if)
00162 {
00163 DBG_MAIN("stop()\n");
00164 sang_if->stop();
00165 }
00166
00173 void PrintRxData(wp_api_hdr_t *hdr, void *pdata)
00174 {
00175 unsigned short datlen;
00176 unsigned char * data;
00177 static unsigned int rx_counter = 0;
00178
00179
00180 datlen = hdr->data_length;
00181 data = (unsigned char*)pdata;
00182
00183 rx_counter++;
00184 if(program_settings.silent){
00185 if((rx_counter % 1000) == 0){
00186 INFO_MAIN("Rx counter: %d, Rx datlen: %d\n", rx_counter, datlen);
00187 #if 1
00188 INFO_MAIN("Timestamp: Seconds: %d, Microseconds: %d\n",
00189 hdr->time_stamp_sec, hdr->time_stamp_usec);
00190 #endif
00191 }
00192 return;
00193 }else{
00194 INFO_MAIN("Rx counter: %d, Rx datlen: %d. Data:\n", rx_counter, datlen);
00195 }
00196
00197 #if 1
00198 for(int ln = 0; ln < datlen; ln++){
00199 if((ln % 20 == 0)){
00200 if(ln){
00201 INFO_MAIN("\n");
00202 }
00203 INFO_MAIN("%04d ", ln/20);
00204 }
00205 INFO_MAIN("%02X ", data[ln]);
00206 }
00207 INFO_MAIN("\n");
00208 #endif
00209 }
00210
00211
00222 static int got_rx_data(void *sang_if_ptr, void *rxhdr, void *rx_data)
00223 {
00224 sangoma_interface *sang_if = (sangoma_interface*)sang_if_ptr;
00225
00226 #if 0
00227 #ifdef __LINUX__
00228 static struct timeval tv_start;
00229 static int elapsed_b4=0;
00230 struct timeval last;
00231 int elapsed;
00232
00233 last=tv_start;
00234 gettimeofday(&tv_start, NULL);
00235 elapsed = abs(elapsed_b4);
00236 elapsed_b4 = abs((((last.tv_sec * 1000) + last.tv_usec / 1000) - ((tv_start.tv_sec * 1000) + tv_start.tv_usec / 1000)));
00237 if (abs(elapsed - elapsed_b4) > 1) {
00238 INFO_MAIN("wanpipe%d: Elapsed %i %i diff=%i\n", program_settings.wanpipe_number, elapsed,elapsed_b4,abs(elapsed-elapsed_b4));
00239 }
00240 #endif
00241 #endif
00242
00243
00244
00245 if(program_settings.Rx_to_Tx_loopback == 1){
00246 sang_if->transmit((wp_api_hdr_t*)rxhdr, rx_data);
00247 }
00248
00249 EnterCriticalSection(&PrintCriticalSection);
00250 PrintRxData((wp_api_hdr_t*)rxhdr, rx_data);
00251 LeaveCriticalSection(&PrintCriticalSection);
00252 return 0;
00253 }
00254
00269 static void got_tdm_api_event(void *sang_if_ptr, void *event_data)
00270 {
00271 sangoma_interface *sang_if = (sangoma_interface *)sang_if_ptr;
00272 wp_api_event_t *wp_tdm_api_event = (wp_api_event_t *)event_data;
00273 wan_time_t wan_time;
00274 char *timestamp_str;
00275
00276 EnterCriticalSection(&TdmEventCriticalSection);
00277
00278
00279
00280 wan_time = wp_tdm_api_event->time_stamp_sec;
00281 timestamp_str = sangoma_ctime( &wan_time );
00282
00283
00284
00285
00286 DBG_MAIN("%s(): Span: %d, Channel: %d (Seconds:%u, Microseconds:%u)\n", __FUNCTION__,
00287 wp_tdm_api_event->wp_api_event_span, wp_tdm_api_event->wp_api_event_channel,
00288 wp_tdm_api_event->time_stamp_sec, wp_tdm_api_event->time_stamp_usec);
00289
00290 switch(wp_tdm_api_event->wp_api_event_type)
00291 {
00292 case WP_API_EVENT_DTMF:
00293 DBG_MAIN("DTMF Event: Digit: %c (Port: %s, Type:%s)!\n",
00294 wp_tdm_api_event->wp_api_event_dtmf_digit,
00295 WAN_EC_DECODE_CHANNEL_PORT(wp_tdm_api_event->wp_api_event_dtmf_port),
00296 WAN_EC_DECODE_TONE_TYPE(wp_tdm_api_event->wp_api_event_dtmf_type) );
00297 break;
00298
00299 case WP_API_EVENT_RXHOOK:
00300 DBG_MAIN("RXHOOK Event: %s! (0x%X)\n",
00301 WAN_EVENT_RXHOOK_DECODE(wp_tdm_api_event->wp_api_event_hook_state),
00302 wp_tdm_api_event->wp_api_event_hook_state);
00303 break;
00304
00305 case WP_API_EVENT_RING_DETECT:
00306 DBG_MAIN("RING Event: %s! (0x%X)\n",
00307 WAN_EVENT_RING_DECODE(wp_tdm_api_event->wp_api_event_ring_state),
00308 wp_tdm_api_event->wp_api_event_ring_state);
00309 break;
00310
00311 case WP_API_EVENT_RING_TRIP_DETECT:
00312 DBG_MAIN("RING TRIP Event: %s! (0x%X)\n",
00313 WAN_EVENT_RING_TRIP_DECODE(wp_tdm_api_event->wp_api_event_ring_state),
00314 wp_tdm_api_event->wp_api_event_ring_state);
00315 break;
00316
00317 case WP_API_EVENT_RBS:
00318 DBG_MAIN("RBS Event: New bits: 0x%X!\n", wp_tdm_api_event->wp_api_event_rbs_bits);
00319 DBG_MAIN("RX RBS/CAS: ");
00320 wp_print_rbs_cas_bits(wp_tdm_api_event->wp_api_event_rbs_bits);
00321 break;
00322
00323 case WP_API_EVENT_LINK_STATUS:
00324 DBG_MAIN("Link Status Event: %s! (0x%X)\n",
00325 WAN_EVENT_LINK_STATUS_DECODE(wp_tdm_api_event->wp_api_event_link_status),
00326 wp_tdm_api_event->wp_api_event_link_status);
00327 break;
00328
00329 case WP_API_EVENT_ALARM:
00330 DBG_MAIN("New Alarm State: 0x%X\n", wp_tdm_api_event->wp_api_event_alarm);
00331 break;
00332
00333 case WP_API_EVENT_POLARITY_REVERSE:
00334
00335
00336
00337
00338
00339 DBG_MAIN("Polarity Reversal Event: %s\n",
00340 WP_API_EVENT_POLARITY_REVERSE_DECODE(wp_tdm_api_event->wp_api_event_polarity_reverse));
00341 break;
00342
00343 default:
00344 ERR_MAIN("Unknown TDM API Event: %d\n", wp_tdm_api_event->wp_api_event_type);
00345 break;
00346 }
00347
00348 LeaveCriticalSection(&TdmEventCriticalSection);
00349 return;
00350 }
00351
00352 #if USE_WP_LOGGER
00353
00360 static void got_logger_event(void *sang_if_ptr, wp_logger_event_t *logger_event)
00361 {
00362 char *timestamp_str = sangoma_ctime( &logger_event->time_stamp_sec );
00363
00364 INFO_MAIN("Logger Event Type:\t%s (Logger:%d BitMap: 0x%08X)\n",
00365 wp_decode_logger_event_type(logger_event->logger_type, logger_event->event_type),
00366 logger_event->logger_type, logger_event->event_type);
00367
00368 INFO_MAIN("Time and Date:\t\t%s\n",
00369 (timestamp_str == NULL ? "Invalid Timestamp" : timestamp_str));
00370 INFO_MAIN("Logger Event Data: %s\n\n", logger_event->data);
00371 }
00372 #endif
00373
00381 int tx_file(sangoma_interface *sang_if)
00382 {
00383 FILE *pFile;
00384 unsigned int tx_counter=0, bytes_read_from_file, total_bytes_read_from_file=0;
00385 wp_api_hdr_t hdr;
00386 unsigned char local_tx_data[MAX_NO_DATA_BYTES_IN_FRAME];
00387
00388 pFile = fopen( program_settings.szTxFileName, "rb" );
00389 if( pFile == NULL){
00390 ERR_MAIN( "Can't open file: [%s]\n", program_settings.szTxFileName );
00391 return 1;
00392 }
00393
00394 do
00395 {
00396
00397 bytes_read_from_file = fread( local_tx_data, 1, program_settings.txlength , pFile );
00398 total_bytes_read_from_file += bytes_read_from_file;
00399
00400 hdr.data_length = program_settings.txlength;
00401 hdr.operation_status = SANG_STATUS_TX_TIMEOUT;
00402
00403 if(SANG_STATUS_SUCCESS != sang_if->transmit(&hdr, local_tx_data)){
00404
00405 break;
00406 }
00407
00408 tx_counter++;
00409
00410
00411
00412 }while(bytes_read_from_file == program_settings.txlength);
00413
00414 INFO_MAIN("%s: Finished transmitting file \"%s\" (tx_counter: %u, total_bytes_read_from_file: %d)\n",
00415 sang_if->device_name, program_settings.szTxFileName, tx_counter, total_bytes_read_from_file);
00416
00417 fclose( pFile );
00418 return 0;
00419 }
00420
00426 static int get_user_decimal_number()
00427 {
00428 int result = 1;
00429 int retry_counter = 0;
00430
00431 while(scanf("%d", &result) == 0){
00432 fflush( stdin );
00433 INFO_MAIN("\nError: Not a numerical input!!\n");
00434 if(retry_counter++ > 10){
00435 INFO_MAIN("giving up...\n");
00436 result = 1;
00437 break;
00438 }
00439 }
00440
00441 INFO_MAIN("User input: %d\n", result);
00442 return result;
00443 }
00444
00450 static int get_user_hex_number()
00451 {
00452 int result = 1;
00453 int retry_counter = 0;
00454
00455 while(scanf("%x", &result) == 0){
00456 fflush( stdin );
00457 INFO_MAIN("\nError: Not a HEX input!!\n");
00458 if(retry_counter++ > 10){
00459 INFO_MAIN("giving up...\n");
00460 result = 1;
00461 break;
00462 }
00463 }
00464
00465 INFO_MAIN("User input: 0x%X\n", result);
00466 return result;
00467 }
00468
00476 static int parse_command_line_args(int argc, char* argv[])
00477 {
00478 int i;
00479 const char *USAGE_STR =
00480 "\n"
00481 "Usage: sample [-c] [-i] [options]\n"
00482 "\n"
00483 "\t-c number Wanpipe (Port/Span) number: 1,2,3...\n"
00484 "\t-i number Interface number 1,2,3,....\n"
00485 "options:\n"
00486 "\t-silent Disable display of Rx data\n"
00487 "\t-driver_config \tStop/Set Configuration/Start a Port....\n"
00488 "\t-rx2tx All received data automatically transmitted on\n"
00489 "\t the SAME interface\n"
00490 "\t-txlength\tnumber\tLength of data frames to be transmitted when 't'\n"
00491 "\t \t \tkey is pressed\n"
00492 "\t-txcount\tnumber Number of test data frames to be transmitted when 't'\n"
00493 "\t \t \tkey is pressed\n"
00494 "\t-tx_file_name\tstring\tFile to be transmitted when 't' key is pressed\n"
00495 #if USE_STELEPHONY_API
00496 "\t-decode_fsk_cid\t\tDecode FSK Caller ID on an Analog line.\n"
00497 "\t \t\tFor Voice data only.\n"
00498 "\t-encode_fsk_cid\t\tEncode FSK Caller ID on an Analog line.\n"
00499 "\t \t\tFor 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 "\t-rm_txgain\t Set txgain for FXS/FXO modules.\n"
00505 "\t \t\tFXO range from -150 to 120, FXS 35 or -35\n"
00506 "\t-rm_rxgain\t Set txgain for FXS/FXO modules.\n"
00507 "\t \t\tFXO range from -150 to 120, FXS 35 or -35\n"
00508 #endif
00509 #if 0
00510 "\t-use_ctrl_dev \tUse the global 'wptdm_ctrl' device to Get events from\n"
00511 "\t \tall API devices.\n"
00512 #endif
00513 "\t-use_logger_dev \tUse the global Logger device to Get Log Messages\n"
00514 "\t \tfrom API driver.\n"
00515 #ifdef WP_API_FEATURE_LIBSNG_HWEC
00516 "\t-use_hwec \tInitialize/Configure/Use the Hardware Echo Canceller\n"
00517 "\t-hwec_chan \tA 1-based channel number to be used by per-channel (vs. global)\n"
00518 "\t \tHWEC functions. Valid values: 1-31\n"
00519 #endif
00520 "\t-real_time \tRun the Program at real-time priority. This maybe\n"
00521 "\t \t\timportant when Audio stream is used for timing.\n"
00522 "\n"
00523 "Example: sample -c 1 -i 1\n";
00524
00525 memset(&program_settings, 0, sizeof(wp_program_settings_t));
00526 program_settings.wanpipe_number = 1;
00527 program_settings.interface_number = 1;
00528 program_settings.txlength = 80;
00529 program_settings.txcount = 1;
00530 program_settings.rxgain = 0xFFFF;
00531 program_settings.txgain = 0xFFFF;
00532 program_settings.hwec_channel = 1;
00533
00534 for(i = 1; i < argc;){
00535
00536 if(_stricmp(argv[i], "-silent") == 0){
00537 INFO_MAIN("disabling Rx data display...\n");
00538 program_settings.silent = 1;
00539 }else if(_stricmp(argv[i], "help") == 0 || _stricmp(argv[i], "?") == 0 || _stricmp(argv[i], "/?") == 0){
00540 INFO_MAIN(USAGE_STR);
00541 return 1;
00542 }else if(_stricmp(argv[i], "-c") == 0){
00543 if (i+1 > argc-1){
00544 INFO_MAIN("No Wanpipe number was provided!\n");
00545 return 1;
00546 }
00547 program_settings.wanpipe_number = (uint16_t)atoi(argv[i+1]);
00548 INFO_MAIN("Using wanpipe number %d\n", program_settings.wanpipe_number);
00549 i++;
00550 }else if(_stricmp(argv[i], "-i") == 0){
00551 if (i+1 > argc-1){
00552 INFO_MAIN("No Interface number was provided!\n");
00553 return 1;
00554 }
00555 program_settings.interface_number = (uint16_t)atoi(argv[i+1]);
00556 INFO_MAIN("Using interface number %d\n", program_settings.interface_number);
00557 if(program_settings.interface_number < 1){
00558 ERR_MAIN("Invalid interface number %d!!\n", program_settings.interface_number);
00559 return 1;
00560 }
00561 i++;
00562 }else if(strcmp(argv[i], "-rx2tx") == 0){
00563 INFO_MAIN("enabling Rx to Tx loopback...\n");
00564 program_settings.Rx_to_Tx_loopback = 1;
00565 }else if(strcmp(argv[i], "-driver_config") == 0){
00566 INFO_MAIN("enabling driver config start/stop\n");
00567 program_settings.driver_config = 1;
00568
00569 }else if(_stricmp(argv[i], "-txlength") == 0){
00570 if (i+1 > argc-1){
00571 INFO_MAIN("No txlength provided!\n");
00572 return 1;
00573 }
00574 program_settings.txlength = (uint16_t)atoi(argv[i+1]);
00575 INFO_MAIN("Setting txlength to %d bytes.\n", program_settings.txlength);
00576 i++;
00577 }else if(_stricmp(argv[i], "-txcount") == 0){
00578 if (i+1 > argc-1){
00579 INFO_MAIN("No txcount provided!\n");
00580 return 1;
00581 }
00582 program_settings.txcount = atoi(argv[i+1]);
00583 i++;
00584 INFO_MAIN("Setting txcount to %d.\n", program_settings.txcount);
00585 #if USE_STELEPHONY_API
00586 }else if(_stricmp(argv[i], "-decode_fsk_cid") == 0){
00587 INFO_MAIN("enabling FSK Caller ID decoder...\n");
00588 program_settings.decode_fsk_cid = 1;
00589 callback_functions.FSKCallerIDEvent = FSKCallerIDEvent;
00590 }else if(_stricmp(argv[i], "-sw_dtmf") == 0){
00591 INFO_MAIN("enabling Software DTMF decoder...\n");
00592 program_settings.sw_dtmf = 1;
00593 callback_functions.DTMFEvent = DTMFEvent;
00594 }else if(_stricmp(argv[i], "-decode_q931") == 0){
00595 INFO_MAIN("enabling Q931 decoder...\n");
00596 program_settings.decode_q931 = 1;
00597 callback_functions.Q931Event = Q931Event;
00598 }else if(_stricmp(argv[i], "-encode_fsk_cid") == 0){
00599 INFO_MAIN("enabling FSK Caller ID encoder...\n");
00600 program_settings.encode_fsk_cid = 1;
00601 callback_functions.FSKCallerIDTransmit = FSKCallerIDTransmit;
00602 }else if(_stricmp(argv[i], "-encode_sw_dtmf") == 0){
00603 INFO_MAIN("enabling Software DTMF encoder...\n");
00604 program_settings.encode_sw_dtmf = 1;
00605 callback_functions.SwDtmfTransmit = SwDtmfTransmit;
00606 }else if(_stricmp(argv[i], "-alaw") == 0){
00607 INFO_MAIN("enabling ALaw codec...\n");
00608 program_settings.voice_codec_alaw = 1;
00609 #endif//USE_STELEPHONY_API
00610 }else if(_stricmp(argv[i], "-tx_file_name") == 0){
00611 if (i+1 > argc-1){
00612 INFO_MAIN("No TxFileName provided!\n");
00613 return 1;
00614 }
00615 strcpy(program_settings.szTxFileName, argv[i+1]);
00616 i++;
00617 INFO_MAIN("Setting szTxFileName to '%s'.\n", program_settings.szTxFileName);
00618 }else if(_stricmp(argv[i], "-use_ctrl_dev") == 0){
00619 INFO_MAIN("Using ctrl_dev...\n");
00620 program_settings.use_ctrl_dev = 1;
00621 }else if(_stricmp(argv[i], "-use_logger_dev") == 0){
00622 INFO_MAIN("Using logger_dev...\n");
00623 program_settings.use_logger_dev = 1;
00624 }else if(_stricmp(argv[i], "-rm_txgain") == 0){
00625 if (i+1 > argc-1){
00626 INFO_MAIN("No Tx gain provided!\n");
00627 return 1;
00628 }
00629 program_settings.txgain = atoi(argv[i+1]);
00630 i++;
00631 INFO_MAIN("Setting Tx gain to %d.\n", program_settings.txgain);
00632 }else if(_stricmp(argv[i], "-rm_rxgain") == 0){
00633 if (i+1 > argc-1){
00634 INFO_MAIN("No Rx gain provided!\n");
00635 return 1;
00636 }
00637 program_settings.rxgain = atoi(argv[i+1]);
00638 i++;
00639 INFO_MAIN("Setting Rx gain to %d.\n", program_settings.txgain);
00640 }else if(_stricmp(argv[i], "-use_hwec") == 0){
00641 INFO_MAIN("Using hardware echo canceller...\n");
00642 program_settings.use_hardware_echo_canceller = 1;
00643 }else if(_stricmp(argv[i], "-hwec_chan") == 0){
00644 if (i+1 > argc-1){
00645 INFO_MAIN("No hwec_chan provided!\n");
00646 return 1;
00647 }
00648 program_settings.hwec_channel = atoi(argv[i+1]);
00649 i++;
00650 INFO_MAIN("Setting hwec_chan to %d.\n", program_settings.hwec_channel);
00651 }else if(_stricmp(argv[i], "-real_time") == 0){
00652 INFO_MAIN("Will be running at real-time priority...\n");
00653 program_settings.real_time = 1;
00654 }else{
00655 INFO_MAIN("Error: Invalid Argument %s\n",argv[i]);
00656 return 1;
00657 }
00658 i++;
00659 }
00660 return 0;
00661 }
00662
00663
00679 int __cdecl main(int argc, char* argv[])
00680 {
00681 int rc, user_selection,err;
00682 sangoma_interface *sang_if = NULL;
00683 wp_api_hdr_t hdr;
00684 unsigned char local_tx_data[MAX_NO_DATA_BYTES_IN_FRAME];
00685 UCHAR tx_test_byte = 0;
00686
00688 memset(&callback_functions, 0x00, sizeof(callback_functions));
00689 callback_functions.got_rx_data = got_rx_data;
00690 callback_functions.got_tdm_api_event = got_tdm_api_event;
00691 #if USE_WP_LOGGER
00692 callback_functions.got_logger_event = got_logger_event;
00693 #endif
00695 if(parse_command_line_args(argc, argv)){
00696 return 1;
00697 }
00698
00700
00701
00702
00703
00704 if (program_settings.driver_config) {
00705 err=set_port_configuration();
00706 if (err) {
00707 return err;
00708 }
00709 }
00710
00712
00713 InitializeCriticalSection(&PrintCriticalSection);
00714 InitializeCriticalSection(&TdmEventCriticalSection);
00715
00716 if (program_settings.real_time) {
00717 sng_set_process_priority_to_real_time();
00718 }
00719
00721
00722 INFO_MAIN("Using wanpipe_number: %d, interface_number: %d\n", program_settings.wanpipe_number, program_settings.interface_number);
00723
00724 sang_if = init(program_settings.wanpipe_number, program_settings.interface_number);
00725
00726 if(sang_if == NULL){
00727 return 1;
00728 }
00729
00730 rc = start(sang_if);
00731 if(rc){
00732 cleanup(sang_if);
00733 return rc;
00734 }
00735 if(program_settings.txgain != 0xFFFF) {
00736 INFO_MAIN("Applying txgain...\n");
00737 if (sang_if->tdm_control_rm_txgain(program_settings.txgain)){
00738 INFO_MAIN("Failed to apply txgain!\n");
00739 }
00740 }
00741
00742
00743
00744 if(sang_if->get_adapter_type() == WAN_MEDIA_FXOFXS && sang_if->get_sub_media() == MOD_TYPE_FXS) {
00745 INFO_MAIN("Setting Proper hookstates on FXS\n");
00746 sang_if->tdm_txsig_offhook();
00747 sang_if->tdm_txsig_onhook();
00748 }
00749
00750 if(program_settings.rxgain != 0xFFFF) {
00751 INFO_MAIN("Applying rxgain...\n");
00752 if (sang_if->tdm_control_rm_rxgain(program_settings.rxgain)){
00753 INFO_MAIN("Failed to apply rxgain!\n");
00754 }
00755 }
00756 do{
00757 EnterCriticalSection(&PrintCriticalSection);
00758
00759 INFO_MAIN("Press 'q' to quit the program.\n");
00760 INFO_MAIN("Press 's' to get Operational Statistics.\n");
00761 INFO_MAIN("Press 'f' to reset (flush) Operational Statistics.\n");
00762
00763 if(program_settings.use_logger_dev != 1){
00764
00765 INFO_MAIN("Press 't' to transmit data.\n");
00766 INFO_MAIN("Press 'v' to get API driver version.\n");
00767
00768 if(sang_if->get_adapter_type() == WAN_MEDIA_T1 || sang_if->get_adapter_type() == WAN_MEDIA_E1){
00769 INFO_MAIN("Press 'a' to get T1/E1 alarms.\n");
00770
00771 INFO_MAIN("Press 'g' to get RBS bits.\n");
00772 INFO_MAIN("Press 'r' to set RBS bits.\n");
00773 INFO_MAIN("Press '1' to read FE register. Warning: used by Sangoma Techsupport only!\n");
00774 INFO_MAIN("Press '2' to write FE register. Warning: used by Sangoma Techsupport only!\n");
00775 }
00776 INFO_MAIN("Press 'i' to set Tx idle data buffer (BitStream only).\n");
00777 switch(sang_if->get_adapter_type())
00778 {
00779 case WAN_MEDIA_T1:
00780
00781 INFO_MAIN("Press 'l' to send 'activate remote loop back' signal.\n");
00782 INFO_MAIN("Press 'd' to send 'deactivate remote loop back' signal.\n");
00783 break;
00784 case WAN_MEDIA_FXOFXS:
00785 switch(sang_if->get_sub_media())
00786 {
00787 case MOD_TYPE_FXS:
00788 INFO_MAIN("Press 'e' to listen to test tones on a phone connected to the A200-FXS\n");
00789 INFO_MAIN("Press 'c' to ring/stop ring phone connected to the A200-FXS\n");
00790 INFO_MAIN("Press 'n' to enable/disable reception of ON/OFF Hook events on A200-FXS\n");
00791 INFO_MAIN("Press 'm' to enable DTMF events (on SLIC chip) on A200-FXS\n");
00792 INFO_MAIN("Press 'j 'to enable/disable reception of Ring Trip events on A200-FXS\n");
00793 INFO_MAIN("Press 'k' to transmit kewl - drop line voltage on the line connected to the A200-FXS\n");
00794 INFO_MAIN("Press 'h' to set polarity on the line connected to the A200-fXS\n");
00795 INFO_MAIN("Press 'u' to transmit onhooktransfer on the line connected to the A200-FXS\n");
00796 break;
00797
00798 case MOD_TYPE_FXO:
00799 INFO_MAIN("Press 'u' to enable/disable reception of Ring Detect events on A200-FXO\n");
00800 INFO_MAIN("Press 'h' to transmit ON/OFF hook signals on A200-FXO\n");
00801 INFO_MAIN("Press 'a' to get Line Status (Connected/Disconnected)\n");
00802 break;
00803 }
00804 break;
00805 case WAN_MEDIA_BRI:
00806 INFO_MAIN("Press 'k' to Activate/Deactivate ISDN BRI line\n");
00807 INFO_MAIN("Press 'l' to enable bri bchan loopback\n");
00808 INFO_MAIN("Press 'd' to disable bri bchan loopback\n");
00809 break;
00810 }
00811 INFO_MAIN("Press 'o' to control DTMF events on DSP (Octasic)\n");
00812 if (program_settings.encode_sw_dtmf) {
00813 INFO_MAIN("Press 'x' to send software DTMF\n");
00814 }
00815 if (program_settings.encode_fsk_cid) {
00816 INFO_MAIN("Press 'z' to send software FSK Caller ID\n");
00817 }
00818 }
00819
00820 LeaveCriticalSection(&PrintCriticalSection);
00821 user_selection = tolower(_getch());
00822 switch(user_selection)
00823 {
00824 case 'q':
00825 break;
00826 case 't':
00827 for(u_int32_t cnt = 0; cnt < program_settings.txcount; cnt++){
00828 if(program_settings.szTxFileName[0]){
00829 tx_file(sang_if);
00830 }else{
00831 hdr.data_length = program_settings.txlength;
00832 hdr.operation_status = SANG_STATUS_TX_TIMEOUT;
00833
00834 memset(local_tx_data, tx_test_byte, program_settings.txlength);
00835 sang_if->transmit(&hdr, local_tx_data);
00836 tx_test_byte++;
00837 }
00838 }
00839 break;
00840 case 's':
00841 if(program_settings.use_logger_dev == 1){
00842 wp_logger_stats_t stats;
00843
00844
00845 ((sangoma_api_logger_dev*)sang_if)->get_logger_dev_operational_stats(&stats);
00846 }else{
00847 wanpipe_chan_stats_t stats;
00848 sang_if->get_operational_stats(&stats);
00849 }
00850 break;
00851 case 'f':
00852 sang_if->flush_operational_stats();
00853 break;
00854 case 'v':
00855 {
00856 DRIVER_VERSION version;
00857
00858 sang_if->get_api_driver_version(&version);
00859 INFO_MAIN("\nAPI version\t: %d,%d,%d,%d\n",
00860 version.major, version.minor, version.minor1, version.minor2);
00861
00862 u_int8_t customer_id = 0;
00863 sang_if->get_card_customer_id(&customer_id);
00864 INFO_MAIN("\ncustomer_id\t: 0x%02X\n", customer_id);
00865 }
00866 break;
00867 case 'a':
00868 unsigned char cFeStatus;
00869
00870 switch(sang_if->get_adapter_type())
00871 {
00872 case WAN_MEDIA_T1:
00873 case WAN_MEDIA_E1:
00874
00875 sang_if->get_te1_56k_stat();
00876 break;
00877
00878 case WAN_MEDIA_FXOFXS:
00879 switch(sang_if->get_sub_media())
00880 {
00881 case MOD_TYPE_FXO:
00882 cFeStatus = 0;
00883 sang_if->tdm_get_front_end_status(&cFeStatus);
00884 INFO_MAIN("cFeStatus: %s (%d)\n", FE_STATUS_DECODE(cFeStatus), cFeStatus);
00885 break;
00886 }
00887 }
00888 break;
00889 case 'l':
00890 switch(sang_if->get_adapter_type())
00891 {
00892 case WAN_MEDIA_T1:
00893 case WAN_MEDIA_E1:
00894
00895 sang_if->set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE);
00896
00897
00898
00899 break;
00900 case WAN_MEDIA_BRI:
00901 sang_if->tdm_enable_bri_bchan_loopback(WAN_BRI_BCHAN1);
00902 break;
00903 }
00904 break;
00905 case 'd':
00906 switch(sang_if->get_adapter_type())
00907 {
00908 case WAN_MEDIA_T1:
00909 case WAN_MEDIA_E1:
00910
00911 sang_if->set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE);
00912
00913
00914
00915 break;
00916 case WAN_MEDIA_BRI:
00917 sang_if->tdm_disable_bri_bchan_loopback(WAN_BRI_BCHAN1);
00918 break;
00919 }
00920 break;
00921 case 'g':
00922 switch(sang_if->get_adapter_type())
00923 {
00924 case WAN_MEDIA_T1:
00925 case WAN_MEDIA_E1:
00926 {
00927 rbs_management_t rbs_management_struct = {0,0};
00928
00929 sang_if->enable_rbs_monitoring();
00930
00931 INFO_MAIN("Type Channel number and press <Enter>:\n");
00932 rbs_management_struct.channel = get_user_decimal_number();
00933
00934 if(WAN_MEDIA_T1 == sang_if->get_adapter_type()){
00935 if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 24){
00936 INFO_MAIN("Invalid T1 RBS Channel number!\n");
00937 break;
00938 }
00939 }
00940
00941 if(WAN_MEDIA_E1 == sang_if->get_adapter_type()){
00942 if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 31){
00943 INFO_MAIN("Invalid E1 CAS Channel number!\n");
00944 break;
00945 }
00946 }
00947
00948 sang_if->get_rbs(&rbs_management_struct);
00949 }
00950 break;
00951 default:
00952 INFO_MAIN("Command invalid for card type\n");
00953 break;
00954 }
00955 break;
00956 case 'r':
00957 switch(sang_if->get_adapter_type())
00958 {
00959 case WAN_MEDIA_T1:
00960 case WAN_MEDIA_E1:
00961 {
00962 static rbs_management_t rbs_management_struct = {0,0};
00963 int chan_no;
00964
00965 sang_if->enable_rbs_monitoring();
00966
00967 INFO_MAIN("Type Channel number and press <Enter>:\n");
00968 rbs_management_struct.channel = chan_no = get_user_decimal_number();
00969
00970 if(WAN_MEDIA_T1 == sang_if->get_adapter_type()){
00971 if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 24){
00972 INFO_MAIN("Invalid T1 RBS Channel number!\n");
00973 break;
00974 }
00975 }
00976
00977 if(WAN_MEDIA_E1 == sang_if->get_adapter_type()){
00978 if(rbs_management_struct.channel < 1 || rbs_management_struct.channel > 31){
00979 INFO_MAIN("Invalid E1 CAS Channel number!\n");
00980 break;
00981 }
00982 }
00983
00984
00985
00986
00987
00988
00989 if(rbs_management_struct.ABCD_bits == WAN_RBS_SIG_A){
00990 rbs_management_struct.ABCD_bits = WAN_RBS_SIG_B;
00991 }else{
00992 rbs_management_struct.ABCD_bits = WAN_RBS_SIG_A;
00993 }
00994 sang_if->set_rbs(&rbs_management_struct);
00995
00996 #if 0
00997 #define RBS_CAS_TX_AND_WAIT(chan, abcd) \
00998 { \
00999 rbs_management_struct.channel = chan; \
01000 rbs_management_struct.ABCD_bits = abcd; \
01001 INFO_MAIN("Press any key to transmit bits:"); \
01002 wp_print_rbs_cas_bits(abcd); \
01003 _getch(); \
01004 sang_if->set_rbs(&rbs_management_struct); \
01005 }
01006
01007
01008 RBS_CAS_TX_AND_WAIT(chan_no, 0x00);
01009
01010 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A);
01011
01012 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_B);
01013
01014 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_B);
01015
01016 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_C);
01017
01018 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_C);
01019
01020 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_B | WAN_RBS_SIG_C);
01021
01022 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_B | WAN_RBS_SIG_C);
01023
01024 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_D);
01025
01026 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_D);
01027
01028 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_B | WAN_RBS_SIG_D);
01029
01030 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_B | WAN_RBS_SIG_D);
01031
01032 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_C | WAN_RBS_SIG_D);
01033
01034 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_C | WAN_RBS_SIG_D);
01035
01036 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_B | WAN_RBS_SIG_C | WAN_RBS_SIG_D);
01037
01038 RBS_CAS_TX_AND_WAIT(chan_no, WAN_RBS_SIG_A | WAN_RBS_SIG_B | WAN_RBS_SIG_C | WAN_RBS_SIG_D);
01039 #endif
01040 }
01041 default:
01042 INFO_MAIN("Command invalid for card type\n");
01043 break;
01044 }
01045 break;
01046 case 'i':
01047 {
01048 INFO_MAIN("Type Idle Flag (HEX, for example: FE) and press <Enter>:\n");
01049 unsigned char new_idle_flag = (unsigned char)get_user_hex_number();
01050 sang_if->set_tx_idle_flag(new_idle_flag);
01051 }
01052 break;
01053 case 'c':
01054 user_retry_ring_e_d:
01055 INFO_MAIN("Press 'e' to START ring, 'd' to STOP ring, 't' to Toggle\n");
01056 INFO_MAIN("\n");
01057 user_selection = tolower(_getch());
01058 switch(user_selection)
01059 {
01060 case 'e':
01061 INFO_MAIN("Starting Ring ...%c\n",user_selection);
01062 sang_if->start_ringing_phone();
01063 break;
01064 case 'd':
01065 INFO_MAIN("Stopping Ring ... %c\n",user_selection);
01066 sang_if->stop_ringing_phone();
01067 break;
01068 case 't':
01069 {
01070 int x;
01071 for (x=0;x<500;x++) {
01072 sang_if->start_ringing_phone();
01073 sang_if->start_ringing_phone();
01074
01075 sang_if->stop_ringing_phone();
01076 sang_if->stop_ringing_phone();
01077
01078 sang_if->start_busy_tone();
01079 sangoma_msleep(50);
01080 sang_if->stop_all_tones();
01081 sangoma_msleep(50);
01082 }
01083 }
01084 break;
01085 default:
01086 goto user_retry_ring_e_d;
01087 break;
01088 }
01089 break;
01090 case 'e':
01091 INFO_MAIN("Press 'e' to START a Tone, 'd' to STOP a Tone.\n");
01092 INFO_MAIN("\n");
01093
01094 switch(tolower(_getch()))
01095 {
01096 case 'e':
01097 INFO_MAIN("Press 'r' for Ring Tone, 'd' for Dial Tone, 'b' for Busy Tone, 'c' for Congestion Tone.\n");
01098 INFO_MAIN("\n");
01099 switch(tolower(_getch()))
01100 {
01101 case 'r':
01102 sang_if->start_ring_tone();
01103 break;
01104 case 'd':
01105 sang_if->start_dial_tone();
01106 break;
01107 case 'b':
01108 sang_if->start_busy_tone();
01109 break;
01110 case 'c':
01111 default:
01112 sang_if->start_congestion_tone();
01113 break;
01114 }
01115 break;
01116
01117 case 'd':
01118 default:
01119 sang_if->stop_all_tones();
01120 }
01121 break;
01122 case 'n':
01123 INFO_MAIN("Press 'e' to ENABLE Rx Hook Events, 'd' to DISABLE Rx Hook Events.\n");
01124 INFO_MAIN("\n");
01125 switch(tolower(_getch()))
01126 {
01127 case 'e':
01128 sang_if->tdm_enable_rxhook_events();
01129 break;
01130 case 'd':
01131 default:
01132 sang_if->tdm_disable_rxhook_events();
01133 }
01134 break;
01135 case 'm':
01136
01137
01138 INFO_MAIN("Press 'e' to ENABLE Remora DTMF Events, 'd' to DISABLE Remora DTMF Events.\n");
01139 INFO_MAIN("\n");
01140 switch(tolower(_getch()))
01141 {
01142 case 'e':
01143 sang_if->tdm_enable_rm_dtmf_events();
01144 break;
01145 case 'd':
01146 default:
01147 sang_if->tdm_disable_rm_dtmf_events();
01148 }
01149 break;
01150 case 'o':
01151 {
01152
01153
01154 INFO_MAIN("Press 'e' to ENABLE Octasic DTMF Events, 'd' to DISABLE Octasic DTMF Events.\n");
01155 uint8_t channel;
01156
01157 INFO_MAIN("\n");
01158 switch(tolower(_getch()))
01159 {
01160 case 'e':
01161 INFO_MAIN("Type Channel number and press <Enter>:\n");
01162 channel = (uint8_t)get_user_decimal_number();
01163
01164 sang_if->tdm_enable_dtmf_events(channel);
01165 break;
01166 case 'd':
01167 default:
01168 INFO_MAIN("Type Channel number and press <Enter>:\n");
01169 channel = (uint8_t)get_user_decimal_number();
01170
01171 sang_if->tdm_disable_dtmf_events(channel);
01172 }
01173 }
01174 break;
01175 case 'u':
01176
01177 if(sang_if->get_sub_media()==MOD_TYPE_FXO){
01178 INFO_MAIN("Press 'e' to ENABLE Rx Ring Detect Events, 'd' to DISABLE Rx Ring Detect Events.\n");
01179 INFO_MAIN("\n");
01180 switch(tolower(_getch()))
01181 {
01182 case 'e':
01183 sang_if->tdm_enable_ring_detect_events();
01184 break;
01185 case 'd':
01186 default:
01187 sang_if->tdm_disable_ring_detect_events();
01188 }
01189 }else if(sang_if->get_sub_media()==MOD_TYPE_FXS){
01190 sang_if->tdm_txsig_onhooktransfer();
01191 }
01192 break;
01193 case 'j':
01194
01195 INFO_MAIN("Press 'e' to ENABLE Rx Ring Trip Events, 'd' to DISABLE Rx Ring Trip Events.\n");
01196 INFO_MAIN("\n");
01197 switch(tolower(_getch()))
01198 {
01199 case 'e':
01200 sang_if->tdm_enable_ring_trip_detect_events();
01201 break;
01202 case 'd':
01203 default:
01204 sang_if->tdm_disable_ring_trip_detect_events();
01205 }
01206 break;
01207 case 'h':
01208 if(sang_if->get_sub_media()==MOD_TYPE_FXO) {
01209 INFO_MAIN("Press 'e' to transmit OFF hook signal, 'd' to transmit ON hook signal.\n");
01210 INFO_MAIN("\n");
01211 switch(tolower(_getch()))
01212 {
01213 case 'e':
01214 sang_if->fxo_go_off_hook();
01215 break;
01216 case 'd':
01217 default:
01218 sang_if->fxo_go_on_hook();
01219 }
01220 }else if(sang_if->get_sub_media() == MOD_TYPE_FXS) {
01221 INFO_MAIN("Press 'f' for forward, 'r' to for reverse.\n");
01222 INFO_MAIN("\n");
01223 switch(tolower(_getch()))
01224 {
01225 case 'f':
01226 sang_if->tdm_set_rm_polarity(0);
01227 break;
01228 case 'r':
01229 sang_if->tdm_set_rm_polarity(1);
01230 break;
01231 default:
01232
01233 int polarity_wait, two_second_ring_repetion_counter;
01234
01235 INFO_MAIN("Type Polarity Reverse/Forward delay and press <Enter>:\n");
01236 polarity_wait = get_user_decimal_number();
01237 if (!polarity_wait) {
01238 ERR_MAIN("Invalid User-specified Polarity Reverse/Forward delay: %d!\n", polarity_wait);
01239 polarity_wait = 400;
01240 }
01241
01242
01243 INFO_MAIN("User specified Polarity Reverse/Forward delay: %d. Press <Enter> to continue.\n", polarity_wait);
01244 _getch();
01245
01246
01247 two_second_ring_repetion_counter = 2000 / (polarity_wait * 2);
01248 INFO_MAIN("two_second_ring_repetion_counter: %d. Press <Enter> to continue.\n", two_second_ring_repetion_counter);
01249 _getch();
01250
01251 for (int ii = 0; ii < two_second_ring_repetion_counter; ii++) {
01252 INFO_MAIN("Reversing polarity %d...\n", ii);
01253 sang_if->tdm_set_rm_polarity(1);
01254 sangoma_msleep(polarity_wait);
01255 INFO_MAIN("Forwarding polarity %d...\n", ii);
01256 sang_if->tdm_set_rm_polarity(0);
01257 sangoma_msleep(polarity_wait);
01258 }
01259
01260
01261 INFO_MAIN("4 seconds between the rings...\n");
01262 sangoma_msleep(4000);
01263
01264 for (int ii = 0; ii < two_second_ring_repetion_counter; ii++) {
01265 INFO_MAIN("Reversing polarity %d...\n", ii);
01266 sang_if->tdm_set_rm_polarity(1);
01267 sangoma_msleep(polarity_wait);
01268 INFO_MAIN("Forwarding polarity %d...\n", ii);
01269 sang_if->tdm_set_rm_polarity(0);
01270 sangoma_msleep(polarity_wait);
01271 }
01272 }
01273 }
01274 break;
01275 case 'k':
01276 if( sang_if->get_adapter_type() == WAN_MEDIA_BRI ) {
01277 INFO_MAIN("Press 'e' to Activate, 'd' to De-Activate line.\n");
01278 INFO_MAIN("\n");
01279 switch(tolower(_getch()))
01280 {
01281 case 'e':
01282 sang_if->tdm_front_end_activate();
01283 break;
01284 case 'd':
01285 default:
01286 sang_if->tdm_front_end_deactivate();
01287 }
01288 }else if(sang_if->get_adapter_type()== WAN_MEDIA_FXOFXS) {
01289 if(sang_if->get_sub_media()==MOD_TYPE_FXS) {
01290 printf("calling tdm_txsig_kewl()...\n");
01291 sang_if->tdm_txsig_kewl();
01292 sangoma_msleep(5000);
01293
01294 printf("restoring line current after txsig kewl...\n");
01295 sang_if->tdm_txsig_offhook();
01296 }
01297 }
01298 break;
01299 case 'p':
01300 {
01301 int user_period;
01302 INFO_MAIN("Type User Period and press <Enter>. Valid values are: 10, 20, 40.\n");
01303 user_period = get_user_decimal_number();
01304 switch(user_period)
01305 {
01306 case 10:
01307 case 20:
01308 case 40:
01309 sang_if->tdm_set_user_period(user_period);
01310 break;
01311 default:
01312 INFO_MAIN("Invalid User Period value! Valid values are: 10, 20, 40.\n");
01313 break;
01314 }
01315 }
01316 break;
01317 #if USE_STELEPHONY_API
01318 case 'x':
01319 {
01320 INFO_MAIN("Press a key. Valid values are 0-9, A-C\n");
01321 int user_char = _getch();
01322 switch(tolower(user_char)) {
01323 case '1': case '2': case '3':
01324 case '4': case '5': case '6':
01325 case '7': case '8': case '9':
01326 case '0': case 'a': case 'b':
01327 case 'c':
01328 INFO_MAIN("Sending DTMF (%c).\n", user_char);
01329 sang_if->sendSwDTMF((char)user_char);
01330 break;
01331 default:
01332 INFO_MAIN("Invalid DTMF Char! Valid values are: 0-9, A-C\n");
01333 break;
01334 }
01335 }
01336 break;
01337 case 'z':
01338 {
01339 if(WAN_MEDIA_FXOFXS == sang_if->get_adapter_type() && MOD_TYPE_FXS == sang_if->get_sub_media() ){
01340
01341 sang_if->start_ringing_phone();
01342 sangoma_msleep(2000);
01343
01344 sang_if->fxs_txsig_offhook();
01345 INFO_MAIN("Sending CallerID.\n");
01346 sang_if->sendCallerID("Sangoma Rocks", "9054741990");
01347 }else{
01348 INFO_MAIN("Sending CallerID.\n");
01349 sang_if->sendCallerID("Sangoma Rocks", "9054741990");
01350 }
01351 }
01352 break;
01353 #endif
01354 case '1':
01355 {
01356 int value;
01357 sdla_fe_debug_t fe_debug;
01358
01359 fe_debug.type = WAN_FE_DEBUG_REG;
01360
01361 printf("Type Register number (hex) i.g. F8 and press Enter:");
01362 value = get_user_hex_number();
01363
01364 fe_debug.fe_debug_reg.reg = value;
01365 fe_debug.fe_debug_reg.read = 1;
01366
01367 sang_if->set_fe_debug_mode(&fe_debug);
01368 }
01369 break;
01370
01371 case '2':
01372 {
01373 int value;
01374 sdla_fe_debug_t fe_debug;
01375 fe_debug.type = WAN_FE_DEBUG_REG;
01376
01377 printf("WRITE: Type Register number (hex) i.g. F8 and press Enter:");
01378 value = get_user_hex_number();
01379
01380 fe_debug.fe_debug_reg.reg = value;
01381 fe_debug.fe_debug_reg.read = 1;
01382
01383 printf("WRITE: Type value (hex) i.g. 1A and press Enter:");
01384 value = get_user_hex_number();
01385
01386 fe_debug.fe_debug_reg.read = 0;
01387 fe_debug.fe_debug_reg.value = (unsigned char)value;
01388
01389 sang_if->set_fe_debug_mode(&fe_debug);
01390 }
01391 break;
01392
01393 default:
01394 INFO_MAIN("Invalid command.\n");
01395 }
01396 }while(user_selection != 'q');
01397
01398 stop(sang_if);
01399 cleanup(sang_if);
01400
01401 return 0;
01402 }
01403
01404 static int set_port_configuration()
01405 {
01406 int rc = 0, user_selection;
01407
01408
01409
01410
01411 int is_te1_port = 0, is_analog_port = 0, is_bri_port = 0, is_serial_port = 0;
01412 hardware_info_t hardware_info;
01413 port_cfg_t port_cfg;
01414
01415 sangoma_port_configurator *sng_port_cfg_obj;
01416
01417 sng_port_cfg_obj = new sangoma_port_configurator();
01418 if(sng_port_cfg_obj == NULL || sng_port_cfg_obj->init((unsigned short)program_settings.wanpipe_number)){
01419 ERR_MAIN("Failed to initialize 'sangoma_port_configurator'\n");
01420 return 2;
01421 }
01422
01423 rc = sng_port_cfg_obj->get_hardware_info(&hardware_info);
01424
01425 if(rc == SANG_STATUS_SUCCESS){
01426
01427 INFO_MAIN("card_model : %s (%d)\n",
01428 SDLA_ADPTR_NAME(hardware_info.card_model), hardware_info.card_model);
01429 INFO_MAIN("firmware_version\t: 0x%02X\n", hardware_info.firmware_version);
01430 INFO_MAIN("pci_bus_number\t\t: %d\n", hardware_info.pci_bus_number);
01431 INFO_MAIN("pci_slot_number\t\t: %d\n", hardware_info.pci_slot_number);
01432 INFO_MAIN("max_hw_ec_chans\t\t: %d\n", hardware_info.max_hw_ec_chans);
01433 INFO_MAIN("port_number\t\t: %d\n", hardware_info.port_number);
01434
01435 }else{
01436 ERR_MAIN("Failed to get hardware information\n");
01437 delete sng_port_cfg_obj;
01438 return 3;
01439 }
01440
01441
01442 memset(&port_cfg, 0x00, sizeof(port_cfg_t));
01443
01444 switch(hardware_info.card_model)
01445 {
01446 case A101_ADPTR_1TE1:
01447 case A101_ADPTR_2TE1:
01448 case A104_ADPTR_4TE1:
01449 case A108_ADPTR_8TE1:
01450 is_te1_port = 1;
01451 INFO_MAIN("T1/E1 Port on non-Hybrid Card (A10[1/2/4/8]).\n");
01452 break;
01453 case A200_ADPTR_ANALOG:
01454 case A400_ADPTR_ANALOG:
01455 case AFT_ADPTR_A600:
01456 is_analog_port = 1;
01457 INFO_MAIN("Analog Port on non-Hybrid Card (A200/A400).\n");
01458 break;
01459 case AFT_ADPTR_ISDN:
01460 is_bri_port = 1;
01461 INFO_MAIN("BRI Port on non-Hybrid Card (A500).\n");
01462 break;
01463 case AFT_ADPTR_FLEXBRI:
01464
01465 if (hardware_info.bri_modtype == MOD_TYPE_NT ||
01466 hardware_info.bri_modtype == MOD_TYPE_TE) {
01467 is_bri_port = 1;
01468 INFO_MAIN("BRI Port on Hybrid Card.\n");
01469 } else {
01470 is_analog_port = 1;
01471 INFO_MAIN("Analog Port on Hybrid Card.\n");
01472 }
01473 break;
01474 case AFT_ADPTR_2SERIAL_V35X21:
01475 case AFT_ADPTR_4SERIAL_V35X21:
01476 case AFT_ADPTR_2SERIAL_RS232:
01477 case AFT_ADPTR_4SERIAL_RS232:
01478 is_serial_port = 1;
01479 INFO_MAIN("Serial Port on non-Hybrid Card (A14[2/4]).\n");
01480 break;
01481 default:
01482 INFO_MAIN("Warning: configuration of card model 0x%08X can not be changed!\n",
01483 hardware_info.card_model);
01484 break;
01485 }
01486
01487
01488 if (is_te1_port) {
01489 INFO_MAIN("\n");
01490 INFO_MAIN("Press 't' to set T1 configration.\n");
01491 INFO_MAIN("Press 'e' to set E1 configration.\n");
01492 try_again:
01493 user_selection = tolower(_getch());
01494 switch(user_selection)
01495 {
01496 case 't':
01497 rc=sng_port_cfg_obj->initialize_t1_tdm_span_voice_api_configration_structure(&port_cfg,&hardware_info,program_settings.wanpipe_number);
01498 break;
01499
01500 case 'e':
01501 rc=sng_port_cfg_obj->initialize_e1_tdm_span_voice_api_configration_structure(&port_cfg,&hardware_info,program_settings.wanpipe_number);
01502 break;
01503
01504 case 'q':
01505 rc = 1;
01506 break;
01507
01508 default:
01509 INFO_MAIN("Invalid command %c.\n",user_selection);
01510 goto try_again;
01511
01512 }
01513 }
01514
01515 if (is_analog_port) {
01516
01517 if(sng_port_cfg_obj->get_configration(&port_cfg)){
01518 rc = 1;
01519 }else{
01520
01521 sng_port_cfg_obj->print_port_cfg_structure(&port_cfg);
01522 #if 0
01523 sng_port_cfg_obj->initialize_interface_mtu_mru(&port_cfg, 16, 16);
01524 #endif
01525 #if 0
01526
01527 rc=sng_port_cfg_obj->control_analog_rm_lcm(&port_cfg, 1);
01528 #endif
01529 #if 0
01530
01531 rc=sng_port_cfg_obj->set_analog_opermode(&port_cfg, "TBR21");
01532 #endif
01533 }
01534 }
01535
01536 if (is_bri_port) {
01537 rc=sng_port_cfg_obj->initialize_bri_tdm_span_voice_api_configration_structure(&port_cfg,&hardware_info,program_settings.wanpipe_number);
01538 }
01539
01540 if (is_serial_port) {
01541 rc=sng_port_cfg_obj->initialize_serial_api_configration_structure(&port_cfg,&hardware_info,program_settings.wanpipe_number);
01542 }
01543
01544 if(!is_te1_port && !is_analog_port && !is_bri_port && !is_serial_port){
01545 INFO_MAIN("Unsupported Card %d\n", hardware_info.card_model);
01546 rc = 1;
01547 }
01548
01549 do{
01550 if (rc) {
01551 ERR_MAIN("Failed to Initialize Port Configuratoin structure!\n");
01552 break;
01553 }
01554 #if 1
01555 INFO_MAIN("Stopping PORT for re-configuration!\n");
01556 if ((rc = sng_port_cfg_obj->stop_port())) {
01557 ERR_MAIN("Failed to Stop Port! rc: %d\n", rc);
01558 break;
01559 }
01560
01561 INFO_MAIN("Configuring PORT!\n");
01562 if ((rc = sng_port_cfg_obj->set_volatile_configration(&port_cfg))) {
01563 ERR_MAIN("Failed to Configure Port! rc: %d\n", rc);
01564 break;
01565 }
01566
01567 INFO_MAIN("Starting PORT!\n");
01568 if ((rc = sng_port_cfg_obj->start_port())) {
01569 ERR_MAIN("Failed to Start Port! rc: %d\n", rc);
01570 break;
01571 }
01572 #endif
01573 #if 0
01574
01575 if (rc = sng_port_cfg_obj->write_configration_on_persistent_storage(
01576 &port_cfg, &hardware_info, program_settings.wanpipe_number)) {
01577 ERR_MAIN("Failed to write configuration on persistant storage! rc: %d\n", rc);
01578 break;
01579 }
01580 #endif
01581 }while(0);
01582
01583 if(sng_port_cfg_obj != NULL){
01584 delete sng_port_cfg_obj;
01585 }
01586
01587 sangoma_msleep(2000);
01588
01589 return rc;
01590 }
01591
01592
01593 #if USE_STELEPHONY_API
01594 static void FSKCallerIDEvent(void *callback_context,
01595 char * Name, char * CallerNumber,
01596 char * CalledNumber, char * DateTime)
01597 {
01598
01599 sangoma_interface *sang_if = (sangoma_interface*)callback_context;
01600
01601 INFO_MAIN("\n%s: %s() - Start\n", sang_if->device_name, __FUNCTION__);
01602
01603 if(Name){
01604 INFO_MAIN("Name: %s\n", Name);
01605 #if 0
01606 printf("caller name in SINGLE byte hex:\n");
01607 for(unsigned int ind = 0; ind < strlen(Name); ind++){
01608 printf("Name[%02d]: 0x%02X\n", ind, Name[ind]);
01609 }
01610 printf("\n");
01611
01612 printf("caller name in DOUBLE byte (unicode) hex:\n");
01613 for(unsigned int ind = 0; ind < strlen(Name); ind += 2){
01614 printf("Name[%02d]: 0x%04X\n", ind, *(unsigned short*)&Name[ind]);
01615 }
01616 #endif
01617 printf("\n");
01618 }
01619
01620
01621 if(CallerNumber){
01622 INFO_MAIN("CallerNumber: %s\n", CallerNumber);
01623 }
01624 if(CalledNumber){
01625 INFO_MAIN("CalledNumber: %s\n", CalledNumber);
01626 }
01627 if(DateTime){
01628 INFO_MAIN("DateTime: %s\n", DateTime);
01629 }
01630
01631 INFO_MAIN("Resetting FSK Caller ID\n");
01632 sang_if->resetFSKCID();
01633
01634 INFO_MAIN("%s() - End\n\n", __FUNCTION__);
01635 }
01636
01637 static void DTMFEvent(void *callback_context, long Key)
01638 {
01639
01640 sangoma_interface *sang_if = (sangoma_interface*)callback_context;
01641
01642 INFO_MAIN("\n%s: %s() - Start\n", sang_if->device_name, __FUNCTION__);
01643
01644 INFO_MAIN("Key: %c\n", (char) Key);
01645
01646 INFO_MAIN("%s() - End\n\n", __FUNCTION__);
01647 }
01648
01649 static void Q931Event(void *callback_context, stelephony_q931_event *pQ931Event)
01650 {
01651
01652 sangoma_interface *sang_if = (sangoma_interface*)callback_context;
01653
01654 INFO_MAIN("\n%s: %s() - Start\n", sang_if->device_name, __FUNCTION__);
01655 #if 0
01656 INFO_MAIN("\nFound %d bytes of data: ", pQ931Event->dataLength);
01657 for (int i=0; i < pQ931Event->dataLength;i++){
01658 INFO_MAIN("%02X ",pQ931Event->data[i]);
01659 }
01660 INFO_MAIN("\n");
01661 #endif
01662
01663
01664 INFO_MAIN("Message Received on: %02d/%02d/%02d @ %02d:%02d:%02d\n",pQ931Event->tv.wMonth,pQ931Event->tv.wDay,pQ931Event->tv.wYear,
01665 pQ931Event->tv.wHour,pQ931Event->tv.wMinute,pQ931Event->tv.wSecond);
01666
01667 INFO_MAIN("Message Type is: %s\n",pQ931Event->msg_type);
01668 INFO_MAIN("Length of Call Reference Field is: %d\n", pQ931Event->len_callRef);
01669 INFO_MAIN("Message Call Reference is : 0X%s\n",pQ931Event->callRef);
01670
01671 if (pQ931Event->cause_code > 0){
01672 INFO_MAIN("Cause code found = %d \n", pQ931Event->cause_code);
01673 }
01674
01675 if (pQ931Event->chan > 0){
01676 INFO_MAIN("B-channel used = %d \n", pQ931Event->chan);
01677 }
01678
01679 if (pQ931Event->calling_num_digits_count > 0 ){
01680 INFO_MAIN("Found %d digits for calling number \n", pQ931Event->calling_num_digits_count);
01681 INFO_MAIN("Presentation indicator is = %d \n",pQ931Event->calling_num_presentation);
01682 INFO_MAIN("Screening indicator is = %d \n",pQ931Event->calling_num_screening_ind);
01683 INFO_MAIN("Calling number is = %s\n",pQ931Event->calling_num_digits);
01684 }
01685
01686 if (pQ931Event->called_num_digits_count > 0 ){
01687 INFO_MAIN("Found %d digits for called number \n", pQ931Event->called_num_digits_count);
01688 INFO_MAIN("Called number is = %s\n",pQ931Event->called_num_digits);
01689 }
01690
01691 if (pQ931Event->rdnis_digits_count > 0 ){
01692 INFO_MAIN("Found %d digits for RDNIS\n", pQ931Event->rdnis_digits_count);
01693 INFO_MAIN("RDNIS is = %s\n",pQ931Event->rdnis_string);
01694 }
01695
01696 }
01697
01698
01699
01700 static void SwDtmfTransmit (void *callback_context, void *DtmfBuffer)
01701 {
01702 sangoma_interface *sang_if = (sangoma_interface*)callback_context;
01703 DBG_MAIN("%s(): %s:\n", __FUNCTION__, sang_if->device_name);
01704
01705
01706
01707 sang_if->CreateSwDtmfTxThread(DtmfBuffer);
01708 }
01709
01710
01711 static void FSKCallerIDTransmit (void *callback_context, void *FskCidBuffer)
01712 {
01713 sangoma_interface *sang_if = (sangoma_interface*)callback_context;
01714 DBG_MAIN("%s(): %s:\n", __FUNCTION__, sang_if->device_name);
01715
01716
01717
01718 sang_if->CreateFskCidTxThread(FskCidBuffer);
01719 }
01720
01721 #if 0
01722 #warning "REMOVE LATER"
01723 int slin2ulaw(void* data, size_t max, size_t *datalen)
01724 {
01725 int16_t sln_buf[512] = {0}, *sln = sln_buf;
01726 uint8_t *lp = (uint8_t*)data;
01727 uint32_t i;
01728 size_t len = *datalen;
01729
01730 if (max > len) {
01731 max = len;
01732 }
01733
01734 memcpy(sln, data, max);
01735
01736 for(i = 0; i < max; i++) {
01737 *lp++ = linear_to_ulaw(*sln++);
01738 }
01739
01740 *datalen = max / 2;
01741
01742 return 0;
01743 }
01744 #endif
01745
01746 #endif
01747
01748 #if 0
01749 LONG Win32FaultHandler(struct _EXCEPTION_POINTERS * ExInfo)
01750
01751 {
01752 char *FaultTx = "";
01753 switch(ExInfo->ExceptionRecord->ExceptionCode)
01754 {
01755 case EXCEPTION_ACCESS_VIOLATION:
01756 FaultTx = "ACCESS VIOLATION";
01757 break;
01758 case EXCEPTION_DATATYPE_MISALIGNMENT:
01759 FaultTx = "DATATYPE MISALIGNMENT";
01760 break;
01761 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
01762 FaultTx = "FLT DIVIDE BY ZERO";
01763 break;
01764 default: FaultTx = "(unknown)";
01765 break;
01766 }
01767
01768 FILE *sgLogFile = fopen("Win32Fault.log", "w");
01769 int wsFault = ExInfo->ExceptionRecord->ExceptionCode;
01770 PVOID CodeAddress = ExInfo->ExceptionRecord->ExceptionAddress;
01771
01772 sgLogFile = fopen("Win32Fault.log", "w");
01773 if(sgLogFile != NULL)
01774 {
01775 fprintf(sgLogFile, "****************************************************\n");
01776 fprintf(sgLogFile, "*** A Program Fault occurred:\n");
01777 fprintf(sgLogFile, "*** Error code %08X: %s\n", wsFault, FaultTx);
01778 fprintf(sgLogFile, "****************************************************\n");
01779 fprintf(sgLogFile, "*** Address: %08X\n", (int)CodeAdress);
01780 fprintf(sgLogFile, "*** Flags: %08X\n",
01781 ExInfo->ExceptionRecord->ExceptionFlags);
01782 LogStackFrames(CodeAddress, (char *)ExInfo->ContextRecord->Ebp);
01783 fclose(sgLogFile);
01784 }
01785
01786
01787
01788
01789
01790
01791 return EXCEPTION_EXECUTE_HANDLER;
01792 }
01793 #endif