00001
00033 #include "libsangoma.h"
00034 #include "libsangoma-pvt.h"
00035 #include "wanpipe_includes.h"
00036
00037 #ifdef WP_API_FEATURE_LIBSNG_HWEC
00038
00039 #include "wanpipe_events.h"
00040 #include "wanec_api.h"
00041 #include "wanec_iface_api.h"
00042
00043 #if defined (__WINDOWS__)
00044 # include "wanpipe_time.h"
00045 # pragma comment( lib, "waneclib" )
00046 #endif
00047
00048 static int libsng_hwec_verbosity_level = 0x00;
00049
00050
00054 static sangoma_status_t sangoma_hwec_bypass(char *device_name, int enable, unsigned int fe_chan_map)
00055 {
00056 sangoma_status_t rc;
00057 wanec_api_hwec_t hwec;
00058
00059 memset(&hwec, 0, sizeof(wanec_api_hwec_t));
00060
00061 hwec.enable = enable;
00062 hwec.fe_chan_map = fe_chan_map;
00063
00064
00065 rc = wanec_api_hwec(device_name, libsng_hwec_verbosity_level, &hwec);
00066
00067 return rc;
00068 }
00069
00070 static int sangoma_hwec_is_numeric_parameter(char *parameter)
00071 {
00072 int i;
00073 static char *WANEC_numeric_params[] = {
00074 "WANEC_TailDisplacement",
00075 "WANEC_MaxPlayoutBuffers",
00076 "WANEC_MaxConfBridges",
00077 "WANEC_EchoOperationMode",
00078 "WANEC_ComfortNoiseMode",
00079 "WANEC_NonLinearityBehaviorA",
00080 "WANEC_NonLinearityBehaviorB",
00081 "WANEC_DoubleTalkBehavior",
00082 "WANEC_RinLevelControlGainDb",
00083 "WANEC_SoutLevelControlGainDb",
00084 "WANEC_RinAutomaticLevelControlTargetDb",
00085 "WANEC_SoutAutomaticLevelControlTargetDb",
00086 "WANEC_RinHighLevelCompensationThresholdDb",
00087 "WANEC_AnrSnrEnhancementDb",
00088 "WANEC_AecTailLength",
00089 NULL
00090 };
00091
00092 i = 0;
00093 while(WANEC_numeric_params[i]){
00094 if (!wp_strncasecmp(parameter, WANEC_numeric_params[i], strlen(parameter))) {
00095 return 1;
00096 }
00097 i++;
00098 };
00099
00100 return 0;
00101 }
00102
00103 static sangoma_status_t sangoma_hwec_ioctl(sng_fd_t fd, wan_ec_api_t *ec_api)
00104 {
00105 wanpipe_api_t tdm_api;
00106 sangoma_status_t err;
00107
00108
00109 memset(&tdm_api, 0x00, sizeof(tdm_api));
00110
00111 WANPIPE_API_INIT_CHAN((&tdm_api), ec_api->fe_chan);
00112 SANGOMA_INIT_TDM_API_CMD_RESULT(tdm_api);
00113
00114 tdm_api.wp_cmd.cmd = WP_API_CMD_EC_IOCTL;
00115
00116 tdm_api.wp_cmd.iovec_list.iovec_list[0].iov_base = ec_api;
00117 tdm_api.wp_cmd.iovec_list.iovec_list[0].iov_len = sizeof(*ec_api);
00118
00119 err = sangoma_cmd_exec(fd, &tdm_api);
00120 if (err) {
00121 DBG_HWEC("sangoma_cmd_exec() Failed: err %d !\n", err);
00122 return err;
00123 }
00124
00125 #if 0
00126 if (WAN_EC_API_RC_OK != ec_api->err) {
00127
00128
00129 switch(ec_api->err){
00130 case WAN_EC_API_RC_INVALID_STATE:
00131 DBG_HWEC("WP_API_CMD_EC_IOCTL Failed: Invalid State: %s !\n",
00132 WAN_EC_STATE_DECODE(ec_api->state));
00133 break;
00134 case WAN_EC_API_RC_FAILED:
00135 case WAN_EC_API_RC_INVALID_CMD:
00136 case WAN_EC_API_RC_INVALID_DEV:
00137 case WAN_EC_API_RC_BUSY:
00138 case WAN_EC_API_RC_INVALID_CHANNELS:
00139 case WAN_EC_API_RC_INVALID_PORT:
00140 default:
00141 DBG_HWEC("WP_API_CMD_EC_IOCTL Failed: %s !\n",
00142 WAN_EC_API_RC_DECODE(ec_api->err));
00143 break;
00144 }
00145 }
00146 #endif
00147
00148 return SANG_STATUS_SUCCESS;
00149 }
00150
00151
00152
00153
00154
00166 void _LIBSNG_CALL sangoma_hwec_initialize_custom_parameter_structure(wan_custom_param_t *custom_param, char *parameter_name, char *parameter_value)
00167 {
00168 memset(custom_param, 0x00, sizeof(*custom_param));
00169
00170 strncpy( custom_param->name, parameter_name, sizeof(custom_param->name) );
00171
00172 if (sangoma_hwec_is_numeric_parameter(parameter_name)) {
00173 custom_param->dValue = atoi(parameter_value);
00174 } else {
00175 strncpy(custom_param->sValue, parameter_value, sizeof(custom_param->sValue));
00176 }
00177 }
00178
00215 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_init(char *device_name, wan_custom_param_t custom_params[], unsigned int number_of_custom_params)
00216 {
00217 sangoma_status_t rc = SANG_STATUS_SUCCESS;
00218 wanec_api_config_t config;
00219
00220 memset(&config, 0x00, sizeof(config));
00221
00222 if (number_of_custom_params >= 1 && number_of_custom_params <= 4) {
00223
00224 wan_custom_param_t *custom_parms_ptr;
00225 unsigned int i, custom_params_memory_size;
00226
00227 custom_params_memory_size = sizeof(wan_custom_param_t) * number_of_custom_params;
00228
00229
00230
00231
00232
00233 custom_parms_ptr = malloc(custom_params_memory_size);
00234 if (!custom_parms_ptr) {
00235 return SANG_STATUS_FAILED_ALLOCATE_MEMORY;
00236 }
00237
00238 memset(custom_parms_ptr, 0x00, custom_params_memory_size);
00239
00240 for (i = 0; i < number_of_custom_params; i++) {
00241
00242 strcpy( custom_parms_ptr[i].name, custom_params[i].name );
00243
00244 if (sangoma_hwec_is_numeric_parameter(custom_params[i].name)) {
00245 custom_parms_ptr[i].dValue = atoi(custom_params[i].sValue);
00246 } else {
00247 strcpy(custom_parms_ptr[i].sValue, custom_params[i].sValue);
00248 }
00249 }
00250
00251 config.conf.param_no = number_of_custom_params;
00252 config.conf.params = custom_parms_ptr;
00253
00254 }
00255
00256
00257 rc = wanec_api_config( device_name, libsng_hwec_verbosity_level, &config );
00258
00259 if (config.conf.params) {
00260 free(config.conf.params);
00261 }
00262
00263 return rc;
00264 }
00265
00266
00283 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_release(char *device_name)
00284 {
00285 sangoma_status_t rc;
00286 wanec_api_release_t release;
00287
00288 memset(&release, 0, sizeof(wanec_api_release_t));
00289
00290 rc = wanec_api_release( device_name, libsng_hwec_verbosity_level, &release );
00291
00292 return rc;
00293 }
00294
00298 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_operation_mode(char *device_name, int mode, unsigned int fe_chan_map)
00299 {
00300 sangoma_status_t rc;
00301 wanec_api_opmode_t opmode;
00302
00303 memset(&opmode, 0, sizeof(wanec_api_opmode_t));
00304
00305 opmode.mode = mode;
00306 opmode.fe_chan_map = fe_chan_map;
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 rc = wanec_api_opmode(device_name, libsng_hwec_verbosity_level, &opmode);
00317
00318 return rc;
00319 }
00320
00338 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_power_on(char *device_name, unsigned int fe_chan_map)
00339 {
00340 return sangoma_hwec_config_operation_mode(device_name, WANEC_API_OPMODE_NORMAL, fe_chan_map);
00341 }
00342
00361 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_power_off(char *device_name, unsigned int fe_chan_map)
00362 {
00363 return sangoma_hwec_config_operation_mode(device_name, WANEC_API_OPMODE_POWER_DOWN, fe_chan_map);
00364 }
00365
00389 sangoma_status_t _LIBSNG_CALL sangoma_hwec_enable(char *device_name, unsigned int fe_chan_map)
00390 {
00391 return sangoma_hwec_bypass(device_name, 1 , fe_chan_map);
00392 }
00393
00394
00416 sangoma_status_t _LIBSNG_CALL sangoma_hwec_disable(char *device_name, unsigned int fe_chan_map)
00417 {
00418 return sangoma_hwec_bypass(device_name, 0 , fe_chan_map);;
00419 }
00420
00464 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_channel_parameter(char *device_name, char *parameter, char *parameter_value, unsigned int channel_map)
00465 {
00466 sangoma_status_t rc;
00467 wanec_api_modify_t channelModify;
00468 wan_custom_param_t custom_param;
00469
00470 memset(&channelModify, 0x00, sizeof(channelModify));
00471
00472 sangoma_hwec_initialize_custom_parameter_structure(&custom_param, parameter, parameter_value);
00473
00474 channelModify.fe_chan_map = channel_map;
00475 channelModify.conf.param_no = 1;
00476 channelModify.conf.params = &custom_param;
00477
00478 rc = wanec_api_modify( device_name, libsng_hwec_verbosity_level, &channelModify );
00479
00480 return rc;
00481 }
00482
00505 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_tone_detection(char *device_name, int tone_id, int enable, unsigned int fe_chan_map, unsigned char port_map)
00506 {
00507 sangoma_status_t rc;
00508 wanec_api_tone_t tone;
00509
00510 memset(&tone, 0, sizeof(wanec_api_tone_t));
00511
00512 tone.id = tone_id;
00513 tone.enable = enable;
00514 tone.fe_chan_map = fe_chan_map;
00515 tone.port_map = port_map;
00516 tone.type_map = WAN_EC_TONE_PRESENT | WAN_EC_TONE_STOP;
00517
00518 rc = wanec_api_tone( device_name, libsng_hwec_verbosity_level, &tone );
00519
00520 return rc;
00521 }
00522
00541 sangoma_status_t _LIBSNG_CALL sangoma_hwec_print_statistics(char *device_name, int full, unsigned int fe_chan)
00542 {
00543 sangoma_status_t rc;
00544 wanec_api_stats_t stats;
00545
00546 memset(&stats, 0, sizeof(wanec_api_stats_t));
00547
00548 stats.full = full;
00549 stats.fe_chan = fe_chan;
00550 stats.reset = 0;
00551
00552 rc = wanec_api_stats( device_name, libsng_hwec_verbosity_level, &stats );
00553
00554 return rc;
00555 }
00556
00574 sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_load(char *device_name, char *filename, char pcmlaw, int *out_buffer_id)
00575 {
00576 sangoma_status_t rc;
00577 wanec_api_bufferload_t bufferload;
00578
00579 memset(&bufferload, 0, sizeof(wanec_api_bufferload_t));
00580 *out_buffer_id = -1;
00581
00582 bufferload.buffer = filename;
00583 bufferload.pcmlaw = pcmlaw;
00584
00585 rc = wanec_api_buffer_load( device_name, libsng_hwec_verbosity_level, &bufferload );
00586 if( rc ) {
00587 return rc;
00588 }
00589
00590 *out_buffer_id = bufferload.buffer_id;
00591
00592 return SANG_STATUS_SUCCESS;
00593 }
00594
00605 sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_mem_buffer_load(char *device_name, unsigned char *buffer, unsigned int in_size, char pcmlaw, int *out_buffer_id)
00606 {
00607 sangoma_status_t rc;
00608 wanec_api_membufferload_t bufferload;
00609
00610 memset(&bufferload, 0, sizeof(bufferload));
00611 *out_buffer_id = -1;
00612
00613 bufferload.buffer = buffer;
00614 bufferload.size = in_size;
00615 bufferload.pcmlaw = pcmlaw;
00616
00617 rc = wanec_api_mem_buffer_load( device_name, libsng_hwec_verbosity_level, &bufferload );
00618 if( rc ) {
00619 return rc;
00620 }
00621
00622 *out_buffer_id = bufferload.buffer_id;
00623
00624 return SANG_STATUS_SUCCESS;
00625 }
00626
00638 sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_unload(char *device_name, int in_buffer_id)
00639 {
00640 sangoma_status_t rc;
00641 wanec_api_bufferunload_t bufferunload;
00642
00643 memset(&bufferunload, 0, sizeof(wanec_api_bufferunload_t));
00644
00645 bufferunload.buffer_id = (unsigned int)in_buffer_id;
00646
00647 rc = wanec_api_buffer_unload( device_name, libsng_hwec_verbosity_level, &bufferunload);
00648
00649 return rc;
00650 }
00651
00677 sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_playout(char *device_name, unsigned int fe_chan_map,
00678 unsigned char port, int in_buffer_id, int start,
00679 int repeat_cnt, int duration)
00680 {
00681 sangoma_status_t rc;
00682 wanec_api_playout_t playout;
00683
00684 memset(&playout, 0, sizeof(wanec_api_playout_t));
00685
00686 playout.start = start;
00687 playout.fe_chan = fe_chan_map;
00688 playout.buffer_id = in_buffer_id;
00689 playout.port = port;
00690 playout.notifyonstop = 1;
00691 playout.user_event_id = 0xA5;
00692 playout.repeat_cnt = repeat_cnt;
00693 playout.duration = (duration) ? duration : cOCT6100_INVALID_VALUE;
00694
00695 rc = wanec_api_playout( device_name, libsng_hwec_verbosity_level, &playout);
00696
00697 return rc;
00698 }
00699
00712 sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_verbosity(int verbosity_level)
00713 {
00714 if (verbosity_level >= 0 || verbosity_level <= 3) {
00715 libsng_hwec_verbosity_level = verbosity_level;
00716 wanec_api_set_lib_verbosity(verbosity_level);
00717 return SANG_STATUS_SUCCESS;
00718 }
00719 return SANG_STATUS_INVALID_PARAMETER;
00720 }
00721
00743 sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_channel_statistics(sng_fd_t fd, unsigned int fe_chan,
00744 int *hwec_api_return_code, wanec_chan_stats_t *wanec_chan_stats, int verbose, int reset)
00745 {
00746 sangoma_status_t err;
00747 wan_ec_api_t ec_api;
00748
00749 memset(&ec_api, 0x00, sizeof(ec_api));
00750
00751 ec_api.cmd = WAN_EC_API_CMD_STATS_FULL;
00752
00753 ec_api.verbose = verbose;
00754
00755
00756 ec_api.fe_chan_map = (1 << fe_chan);
00757
00758
00759 ec_api.u_chan_stats.reset = reset;
00760
00761 err = sangoma_hwec_ioctl(fd, &ec_api);
00762 if (err) {
00763
00764 return err;
00765 }
00766
00767
00768 memcpy(wanec_chan_stats, &ec_api.u_chan_stats, sizeof(*wanec_chan_stats));
00769
00770 *hwec_api_return_code = ec_api.err;
00771
00772 return SANG_STATUS_SUCCESS;
00773 }
00774
00793 sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_global_chip_statistics(sng_fd_t fd,
00794 int *hwec_api_return_code, wanec_chip_stats_t *wanec_chip_stats, int verbose, int reset)
00795 {
00796
00797 sangoma_status_t err;
00798 wan_ec_api_t ec_api;
00799
00800 memset(&ec_api, 0x00, sizeof(ec_api));
00801
00802 ec_api.cmd = WAN_EC_API_CMD_STATS_FULL;
00803
00804 ec_api.verbose = verbose;
00805
00806
00807 ec_api.fe_chan_map = 0;
00808
00809
00810 ec_api.u_chip_stats.reset = reset;
00811
00812 err = sangoma_hwec_ioctl(fd, &ec_api);
00813 if (err) {
00814
00815 return err;
00816 }
00817
00818
00819 memcpy(wanec_chip_stats, &ec_api.u_chip_stats, sizeof(*wanec_chip_stats));
00820
00821 *hwec_api_return_code = ec_api.err;
00822
00823 return SANG_STATUS_SUCCESS;
00824
00825 }
00826
00843 sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_chip_image_info(sng_fd_t fd,
00844 int *hwec_api_return_code, wanec_chip_image_t *wanec_chip_image, int verbose)
00845 {
00846 sangoma_status_t err;
00847 wan_ec_api_t ec_api;
00848
00849 memset(&ec_api, 0x00, sizeof(ec_api));
00850
00851 ec_api.cmd = WAN_EC_API_CMD_STATS_IMAGE;
00852
00853 ec_api.verbose = verbose;
00854
00855
00856 ec_api.u_chip_image.f_ChipImageInfo = wanec_chip_image->f_ChipImageInfo;
00857
00858 err = sangoma_hwec_ioctl(fd, &ec_api);
00859 if (err) {
00860
00861 return err;
00862 }
00863
00864 *hwec_api_return_code = ec_api.err;
00865
00866 return SANG_STATUS_SUCCESS;
00867 }
00868
00869 #endif