870 lines
30 KiB
C
870 lines
30 KiB
C
/*******************************************************************************//**
|
|
* \file libsangoma_hwec.c
|
|
* \brief Hardware Echo Canceller API Code Library for
|
|
* Sangoma AFT T1/E1/Analog/BRI hardware.
|
|
*
|
|
* Author(s): David Rokhvarg <davidr@sangoma.com>
|
|
*
|
|
* Copyright: (c) 2005-2011 Sangoma Technologies Corporation
|
|
*
|
|
* * Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the Sangoma Technologies nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY Sangoma Technologies ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL Sangoma Technologies BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#include "libsangoma.h"
|
|
#include "libsangoma-pvt.h"
|
|
#include "wanpipe_includes.h"
|
|
|
|
#ifdef WP_API_FEATURE_LIBSNG_HWEC
|
|
|
|
#include "wanpipe_events.h"
|
|
#include "wanec_api.h"
|
|
#include "wanec_iface_api.h"
|
|
|
|
#if defined (__WINDOWS__)
|
|
# include "wanpipe_time.h" /* wp_sleep() */
|
|
# pragma comment( lib, "waneclib" ) /* import functions from waneclib.dll */
|
|
#endif/* __WINDOWS__) */
|
|
|
|
static int libsng_hwec_verbosity_level = 0x00;
|
|
|
|
/************************************************************//**
|
|
* Private Functions. (Not exported)
|
|
***************************************************************/
|
|
|
|
static sangoma_status_t sangoma_hwec_bypass(char *device_name, int enable, unsigned int fe_chan_map)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_hwec_t hwec;
|
|
|
|
memset(&hwec, 0, sizeof(wanec_api_hwec_t));
|
|
|
|
hwec.enable = enable;
|
|
hwec.fe_chan_map = fe_chan_map;
|
|
|
|
/* WAN_EC_API_CMD_HWEC_ENABLE/WAN_EC_API_CMD_HWEC_DISABLE - Controls the "bypass" mode.)*/
|
|
rc = wanec_api_hwec(device_name, libsng_hwec_verbosity_level, &hwec);
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int sangoma_hwec_is_numeric_parameter(char *parameter)
|
|
{
|
|
int i;
|
|
static char *WANEC_numeric_params[] = {
|
|
"WANEC_TailDisplacement",
|
|
"WANEC_MaxPlayoutBuffers",
|
|
"WANEC_MaxConfBridges",
|
|
"WANEC_EchoOperationMode",
|
|
"WANEC_ComfortNoiseMode",
|
|
"WANEC_NonLinearityBehaviorA",
|
|
"WANEC_NonLinearityBehaviorB",
|
|
"WANEC_DoubleTalkBehavior",
|
|
"WANEC_RinLevelControlGainDb",
|
|
"WANEC_SoutLevelControlGainDb",
|
|
"WANEC_RinAutomaticLevelControlTargetDb",
|
|
"WANEC_SoutAutomaticLevelControlTargetDb",
|
|
"WANEC_RinHighLevelCompensationThresholdDb",
|
|
"WANEC_AnrSnrEnhancementDb",
|
|
"WANEC_AecTailLength",
|
|
NULL
|
|
};
|
|
|
|
i = 0;
|
|
while(WANEC_numeric_params[i]){
|
|
if (!wp_strncasecmp(parameter, WANEC_numeric_params[i], strlen(parameter))) {
|
|
return 1;/* this IS a numeric parameter */
|
|
}
|
|
i++;
|
|
};
|
|
|
|
return 0;/* NOT a numeric parameter */
|
|
}
|
|
|
|
static sangoma_status_t sangoma_hwec_ioctl(sng_fd_t fd, wan_ec_api_t *ec_api)
|
|
{
|
|
wanpipe_api_t tdm_api;
|
|
sangoma_status_t err;
|
|
|
|
/* it is very important to zero out 'tdm_api' */
|
|
memset(&tdm_api, 0x00, sizeof(tdm_api));
|
|
|
|
WANPIPE_API_INIT_CHAN((&tdm_api), ec_api->fe_chan);
|
|
SANGOMA_INIT_TDM_API_CMD_RESULT(tdm_api);
|
|
|
|
tdm_api.wp_cmd.cmd = WP_API_CMD_EC_IOCTL;
|
|
|
|
tdm_api.wp_cmd.iovec_list.iovec_list[0].iov_base = ec_api;
|
|
tdm_api.wp_cmd.iovec_list.iovec_list[0].iov_len = sizeof(*ec_api);
|
|
|
|
err = sangoma_cmd_exec(fd, &tdm_api);
|
|
if (err) {
|
|
DBG_HWEC("sangoma_cmd_exec() Failed: err %d !\n", err);
|
|
return err;
|
|
}
|
|
|
|
#if 0
|
|
if (WAN_EC_API_RC_OK != ec_api->err) {
|
|
|
|
/* IOCTL ok, but error in cmd - caller must check 'ec_api->err' */
|
|
switch(ec_api->err){
|
|
case WAN_EC_API_RC_INVALID_STATE:
|
|
DBG_HWEC("WP_API_CMD_EC_IOCTL Failed: Invalid State: %s !\n",
|
|
WAN_EC_STATE_DECODE(ec_api->state));
|
|
break;
|
|
case WAN_EC_API_RC_FAILED:
|
|
case WAN_EC_API_RC_INVALID_CMD:
|
|
case WAN_EC_API_RC_INVALID_DEV:
|
|
case WAN_EC_API_RC_BUSY:
|
|
case WAN_EC_API_RC_INVALID_CHANNELS:
|
|
case WAN_EC_API_RC_INVALID_PORT:
|
|
default:
|
|
DBG_HWEC("WP_API_CMD_EC_IOCTL Failed: %s !\n",
|
|
WAN_EC_API_RC_DECODE(ec_api->err));
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return SANG_STATUS_SUCCESS;
|
|
}
|
|
|
|
/***************************************************************
|
|
* Public Functions. (Exported)
|
|
***************************************************************/
|
|
|
|
/*!
|
|
\fn void _LIBSNG_CALL sangoma_hwec_initialize_custom_parameter_structure(wan_custom_param_t *custom_param, char *parameter_name, char *parameter_value)
|
|
|
|
\brief Initialize Custom Paramter structure.
|
|
|
|
\param parameter_name Parameter Name
|
|
|
|
\param parameter_value Parameter Value
|
|
|
|
\return None
|
|
*/
|
|
void _LIBSNG_CALL sangoma_hwec_initialize_custom_parameter_structure(wan_custom_param_t *custom_param, char *parameter_name, char *parameter_value)
|
|
{
|
|
memset(custom_param, 0x00, sizeof(*custom_param));
|
|
|
|
strncpy( custom_param->name, parameter_name, sizeof(custom_param->name) );
|
|
|
|
if (sangoma_hwec_is_numeric_parameter(parameter_name)) {
|
|
custom_param->dValue = atoi(parameter_value);
|
|
} else {
|
|
strncpy(custom_param->sValue, parameter_value, sizeof(custom_param->sValue));
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_init(char *device_name, wan_custom_param_t custom_params[], unsigned int number_of_custom_params)
|
|
|
|
\brief Load Firmware image onto EC chip and allocated per-port resources in HWEC API.
|
|
All chip-wide configuration paramters, if any, must be specified at the time of chip initialization.
|
|
Note that Analog card is considered a "single-port" card by HWEC API. That means for Analog cards and
|
|
for single-port digital cards only a single sangoma_hwec_config_init() call is required, all subsequent
|
|
calls will have no effect.
|
|
For multi-port cards, such as A102/A104/A108/A500, the sangoma_hwec_config_init() must be called
|
|
for each port, at least one time. Only the first call will actually load the Firmware image onto
|
|
EC chip, all subsequent calls (for other ports) will only add the Port to list of ports which use
|
|
the HWEC API.
|
|
Actions of sangoma_hwec_config_init() can be reversed by calling sangoma_hwec_config_release().
|
|
When Port is stopped, the HWEC API automatically releases per-port resources and removes the Port
|
|
from list ports which use HWEC API.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1... Note that wanpipe1_if1 and wanpipe1_if2 will access the same Port - wanpipe1.
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param custom_params[] - (optional) array of custom paramter structures.
|
|
|
|
This is list of Echo Cancellation chip parameters:
|
|
|
|
Chip parameter Chip parameter value
|
|
================= =======================
|
|
WANEC_TailDisplacement 0-896
|
|
WANEC_MaxPlayoutBuffers 0-4678
|
|
WANEC_EnableExtToneDetection TRUE | FALSE
|
|
WANEC_EnableAcousticEcho TRUE | FALSE
|
|
|
|
\param number_of_custom_params - (optional) number of structures in custom_params[]. Minimum value is 1, maximum is 4,
|
|
if any other value the custom_params[] will be ignored.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_init(char *device_name, wan_custom_param_t custom_params[], unsigned int number_of_custom_params)
|
|
{
|
|
sangoma_status_t rc = SANG_STATUS_SUCCESS;
|
|
wanec_api_config_t config;
|
|
|
|
memset(&config, 0x00, sizeof(config));
|
|
|
|
if (number_of_custom_params >= 1 && number_of_custom_params <= 4) {
|
|
|
|
wan_custom_param_t *custom_parms_ptr;
|
|
unsigned int i, custom_params_memory_size;
|
|
|
|
custom_params_memory_size = sizeof(wan_custom_param_t) * number_of_custom_params;
|
|
|
|
/* Do NOT change memory at custom_params[] (it belongs to the caller).
|
|
* Instead allocate temporary buffer, and use information in custom_params[]
|
|
* for proper initialization the temproary buffer and
|
|
* and send if down to API driver. */
|
|
custom_parms_ptr = malloc(custom_params_memory_size);
|
|
if (!custom_parms_ptr) {
|
|
return SANG_STATUS_FAILED_ALLOCATE_MEMORY;
|
|
}
|
|
|
|
memset(custom_parms_ptr, 0x00, custom_params_memory_size);
|
|
|
|
for (i = 0; i < number_of_custom_params; i++) {
|
|
|
|
strcpy( custom_parms_ptr[i].name, custom_params[i].name );
|
|
|
|
if (sangoma_hwec_is_numeric_parameter(custom_params[i].name)) {
|
|
custom_parms_ptr[i].dValue = atoi(custom_params[i].sValue);
|
|
} else {
|
|
strcpy(custom_parms_ptr[i].sValue, custom_params[i].sValue);
|
|
}
|
|
} /* for() */
|
|
|
|
config.conf.param_no = number_of_custom_params;
|
|
config.conf.params = custom_parms_ptr;
|
|
|
|
}/* if() */
|
|
|
|
/* Load firmware on EC chip AND apply configuration, if any. */
|
|
rc = wanec_api_config( device_name, libsng_hwec_verbosity_level, &config );
|
|
|
|
if (config.conf.params) {
|
|
free(config.conf.params);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_release(char *device_name)
|
|
|
|
\brief Release resources allocated by sangoma_hwec_config_init().
|
|
For single-port cards, such as A101 and A200 (A200 is an Analog card and considered
|
|
sinle-port by HWEC API), a single call to sangoma_hwec_config_release() will free the per-chip resources.
|
|
For multi-port cards, such as A102/A104/A108/A500, sangoma_hwec_config_release() can be called
|
|
for each port to remove it from list Ports which are using HWEC API. When sangoma_hwec_config_release()
|
|
is called for the last Port which was "configured/initialized by HWEC API", the per-chip resources will be freed.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1... Note that wanpipe1_if1 and wanpipe1_if2 will access the same Port - wanpipe1.
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_release(char *device_name)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_release_t release;
|
|
|
|
memset(&release, 0, sizeof(wanec_api_release_t));
|
|
|
|
rc = wanec_api_release( device_name, libsng_hwec_verbosity_level, &release );
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
Modify channel operation mode.
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_operation_mode(char *device_name, int mode, unsigned int fe_chan_map)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_opmode_t opmode;
|
|
|
|
memset(&opmode, 0, sizeof(wanec_api_opmode_t));
|
|
|
|
opmode.mode = mode;
|
|
opmode.fe_chan_map = fe_chan_map;
|
|
|
|
/* modes are:
|
|
WANEC_API_OPMODE_NORMAL,
|
|
WANEC_API_OPMODE_HT_FREEZE,
|
|
WANEC_API_OPMODE_HT_RESET,
|
|
WANEC_API_OPMODE_POWER_DOWN,
|
|
WANEC_API_OPMODE_NO_ECHO,
|
|
WANEC_API_OPMODE_SPEECH_RECOGNITION.
|
|
*/
|
|
rc = wanec_api_opmode(device_name, libsng_hwec_verbosity_level, &opmode);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_power_on (char *device_name, unsigned int fe_chan_map)
|
|
|
|
\brief Set the channel state in the echo canceller to NORMAL/POWER ON.
|
|
This enables echo cancelation logic inside the chip.
|
|
The action is internal to EC chip itself, not related to AFT FPGA.
|
|
This call is slow and should be used only on startup.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital,
|
|
lines for Analog) where the call will take effect.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_power_on(char *device_name, unsigned int fe_chan_map)
|
|
{
|
|
return sangoma_hwec_config_operation_mode(device_name, WANEC_API_OPMODE_NORMAL, fe_chan_map);
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_power_off (char *device_name, unsigned int fe_chan_map)
|
|
|
|
\brief Set the channel state in the echo canceller to POWER OFF.
|
|
This disables echo cancellatio logic inside the chip and
|
|
data passes unmodified through the ec chip.
|
|
The action is internal to EC chip itself, not related
|
|
to AFT FPGA. This call is slow and should be used only on startup.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital,
|
|
lines for Analog) where the call will take effect.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_power_off(char *device_name, unsigned int fe_chan_map)
|
|
{
|
|
return sangoma_hwec_config_operation_mode(device_name, WANEC_API_OPMODE_POWER_DOWN, fe_chan_map);
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_enable(char *device_name, unsigned int fe_chan_map)
|
|
|
|
\brief Redirect audio stream from AFT FPGA to EC chip.
|
|
This command effectively enables echo cancellation since
|
|
data is now forced through the EC chip by the FPGA.
|
|
Data will be modified by the echo canceller.
|
|
This command is recommened for fast enabling of Echo Cancellation.
|
|
Note 1: Chip must be configured and in POWER ON state for echo
|
|
Chancellation to take place.
|
|
Note 2: sangoma_tdm_enable_hwec() function can be used to achive
|
|
the same funcitnality based on file descriptor versus
|
|
channel map.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital, lines for Analog) where
|
|
the call will take effect.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_enable(char *device_name, unsigned int fe_chan_map)
|
|
{
|
|
return sangoma_hwec_bypass(device_name, 1 /* enable */, fe_chan_map);
|
|
}
|
|
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_disable(char *device_name, unsigned int fe_chan_map)
|
|
|
|
\brief Force AFT FPGA to bypass the echo canceller.
|
|
This command effectively disables echo cancellation since
|
|
data will not flowing through the ec chip.
|
|
Data will not be modified by the echo canceller.
|
|
This command is recommened for fast disabling of Echo Cancelation.
|
|
Note: sangoma_tdm_disable_hwec() function can be use to achive
|
|
the same functionality based on file descriptor versus
|
|
channel map.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital, lines for Analog) where
|
|
the call will take effect.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_disable(char *device_name, unsigned int fe_chan_map)
|
|
{
|
|
return sangoma_hwec_bypass(device_name, 0 /* disable */, fe_chan_map);;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_channel_parameter(char *device_name, char *parameter, char *parameter_value, unsigned int channel_map)
|
|
|
|
\brief Modify channel configuration parameters.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param parameter Echo Cancellation channel parameter
|
|
|
|
This channel parameters are listed under "Channel parameter":
|
|
|
|
Channel parameter Channel parameter value
|
|
================= =======================
|
|
WANEC_EnableNlp TRUE | FALSE
|
|
WANEC_EnableTailDisplacement TRUE | FALSE
|
|
WANEC_TailDisplacement 0-896
|
|
WANEC_SoutLevelControl TRUE | FALSE
|
|
WANEC_RinAutomaticLevelControl TRUE | FALSE
|
|
WANEC_SoutAutomaticLevelControl TRUE | FALSE
|
|
WANEC_SoutAdaptiveNoiseReduction TRUE | FALSE
|
|
WANEC_RoutNoiseReduction TRUE | FALSE
|
|
WANEC_ComfortNoiseMode COMFORT_NOISE_NORMAL
|
|
COMFORT_NOISE_FAST_LATCH
|
|
COMFORT_NOISE_EXTENDED
|
|
COMFORT_NOISE_OFF
|
|
WANEC_DtmfToneRemoval TRUE | FALSE
|
|
WANEC_AcousticEcho TRUE | FALSE
|
|
WANEC_NonLinearityBehaviorA 0-13
|
|
WANEC_NonLinearityBehaviorB 0-8
|
|
WANEC_DoubleTalkBehavior DT_BEH_NORMAL
|
|
DT_BEH_LESS_AGGRESSIVE
|
|
WANEC_AecTailLength 128 (default), 256, 512 or 1024
|
|
WANEC_EnableToneDisabler TRUE | FALSE
|
|
|
|
\param parameter_value channel parameter value, listed under "Channel parameter value"
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital, lines for Analog) where
|
|
the call will take effect.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_channel_parameter(char *device_name, char *parameter, char *parameter_value, unsigned int channel_map)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_modify_t channelModify;
|
|
wan_custom_param_t custom_param;
|
|
|
|
memset(&channelModify, 0x00, sizeof(channelModify));
|
|
|
|
sangoma_hwec_initialize_custom_parameter_structure(&custom_param, parameter, parameter_value);
|
|
|
|
channelModify.fe_chan_map = channel_map;
|
|
channelModify.conf.param_no = 1;
|
|
channelModify.conf.params = &custom_param;
|
|
|
|
rc = wanec_api_modify( device_name, libsng_hwec_verbosity_level, &channelModify );
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
\fn 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)
|
|
|
|
\brief Enable/Disable tone detection (such as DTMF) of channels from channel map.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param tone_id See wanpipe_api_iface.h for list of valid tones
|
|
|
|
\param enable A flag, if 1 - the specified tone will be detected,
|
|
if 0 - specified tone will not be detected.
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital, lines for Analog) where
|
|
the call will take effect.
|
|
|
|
\param port_map Port\Direction of tone detection - Rx, Tx. See wanpipe_events.h for
|
|
list of valid ports (WAN_EC_CHANNEL_PORT_SOUT...).
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
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)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_tone_t tone;
|
|
|
|
memset(&tone, 0, sizeof(wanec_api_tone_t));
|
|
|
|
tone.id = tone_id;
|
|
tone.enable = enable;
|
|
tone.fe_chan_map = fe_chan_map;
|
|
tone.port_map = port_map;
|
|
tone.type_map = WAN_EC_TONE_PRESENT | WAN_EC_TONE_STOP;
|
|
|
|
rc = wanec_api_tone( device_name, libsng_hwec_verbosity_level, &tone );
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_print_statistics(char *device_name, int full, unsigned int fe_chan)
|
|
|
|
\brief Read and print Chip/Channel statistics from EC chip.
|
|
|
|
\param device_name Sangoma API device name.
|
|
Windows: wanpipe1_if1, wanpipe2_if1...
|
|
Linux: wanpipe1, wanpipe2...
|
|
|
|
\param full Flag to read full statistics, if set to 1.
|
|
|
|
\param fe_chan Channel number (a timeslot for Digital, a line for Analog) where
|
|
the call will read statistics. Values from 1 to 31 will indicate the
|
|
channel nuber. A value of zero will indicate request to print global chip statistics,
|
|
not per-channel statistics.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_print_statistics(char *device_name, int full, unsigned int fe_chan)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_stats_t stats;
|
|
|
|
memset(&stats, 0, sizeof(wanec_api_stats_t));
|
|
|
|
stats.full = full;
|
|
stats.fe_chan = fe_chan;
|
|
stats.reset = 0; /* do not reset */
|
|
|
|
rc = wanec_api_stats( device_name, libsng_hwec_verbosity_level, &stats );
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_load(char *device_name, char *filename, char pcmlaw, int *out_buffer_id)
|
|
|
|
\brief Load audio buffer to EC chip. The buffer can be played out using the sangoma_hwec_audio_buffer_playout() function.
|
|
|
|
\param filename name of the audio file (without the extension).
|
|
Actual file must have .pcm extension.
|
|
Location:
|
|
Windows: %SystemRoot%\sang_ec_files (ex: c:\WINDOWS\sang_ec_files)
|
|
Linux: /etc/wanpipe/buffers
|
|
|
|
\param out_buffer_id when the buffer is loaded on the chip, it is assigned an ID. This ID should
|
|
be used when requesting to play out the buffer.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_load(char *device_name, char *filename, char pcmlaw, int *out_buffer_id)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_bufferload_t bufferload;
|
|
|
|
memset(&bufferload, 0, sizeof(wanec_api_bufferload_t));
|
|
*out_buffer_id = -1;
|
|
|
|
bufferload.buffer = filename;
|
|
bufferload.pcmlaw = pcmlaw;
|
|
|
|
rc = wanec_api_buffer_load( device_name, libsng_hwec_verbosity_level, &bufferload );
|
|
if( rc ) {
|
|
return rc;
|
|
}
|
|
|
|
*out_buffer_id = bufferload.buffer_id;
|
|
|
|
return SANG_STATUS_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_mem_buffer_load(char *device_name, char *filename, char pcmlaw, int *out_buffer_id)
|
|
|
|
\brief Load audio buffer to EC chip. The buffer can be played out using the sangoma_hwec_audio_buffer_playout() function.
|
|
|
|
\param out_buffer_id when the buffer is loaded on the chip, it is assigned an ID. This ID should
|
|
be used when requesting to play out the buffer.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
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)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_membufferload_t bufferload;
|
|
|
|
memset(&bufferload, 0, sizeof(bufferload));
|
|
*out_buffer_id = -1;
|
|
|
|
bufferload.buffer = buffer;
|
|
bufferload.size = in_size;
|
|
bufferload.pcmlaw = pcmlaw;
|
|
|
|
rc = wanec_api_mem_buffer_load( device_name, libsng_hwec_verbosity_level, &bufferload );
|
|
if( rc ) {
|
|
return rc;
|
|
}
|
|
|
|
*out_buffer_id = bufferload.buffer_id;
|
|
|
|
return SANG_STATUS_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_bufferunload(char *device_name, int in_buffer_id)
|
|
|
|
\brief Unload/remove an audio buffer from the HWEC chip.
|
|
|
|
\param device_name Sangoma wanpipe device name. (ex: wanpipe1 - Linux; wanpipe1_if1 - Windows).
|
|
|
|
\param in_buffer_id ID of the buffer which will be unloaded. The ID must be initialized by sangoma_hwec_audio_bufferload().
|
|
|
|
\return SANG_STATUS_SUCCESS - buffer was successfully unloaded/removed, SANG_STATUS_GENERAL_ERROR - error occured
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_unload(char *device_name, int in_buffer_id)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_bufferunload_t bufferunload;
|
|
|
|
memset(&bufferunload, 0, sizeof(wanec_api_bufferunload_t));
|
|
|
|
bufferunload.buffer_id = (unsigned int)in_buffer_id;
|
|
|
|
rc = wanec_api_buffer_unload( device_name, libsng_hwec_verbosity_level, &bufferunload);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_playout(char *device_name, unsigned int fe_chan_map,
|
|
unsigned char port_map, int buffer_id, int start, int repeat_cnt, int duration)
|
|
|
|
\brief Start\Stop playing out an audio buffer previously loaded by sangoma_hwec_audio_buffer_load().
|
|
|
|
\param fe_chan_map Bitmap of channels (timeslots for Digital,
|
|
lines for Analog) where the call will take effect.
|
|
|
|
\param port_map Port\Direction where the buffer will be played out.
|
|
This is the channel port on which the buffer will be
|
|
played (WAN_EC_CHANNEL_PORT_SOUT or WAN_EC_CHANNEL_PORT_ROUT)
|
|
|
|
\param in_buffer_id ID of the buffer which will be unloaded. The ID must be initialized by sangoma_hwec_audio_bufferload().
|
|
|
|
\param start If 1 - start the play out, 0 - stop the play out
|
|
|
|
\param repeat_cnt Number of times to play out the same buffer
|
|
|
|
\param duration Maximum duration of the playout, in milliseconds. If it takes less then 'duration' to
|
|
play out the whole buffer, it will be repeated to fill 'duration' amount of time.
|
|
If 'duration' is set to non-zero, this parameter overrides the repeat_cnt flag.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_audio_buffer_playout(char *device_name, unsigned int fe_chan_map,
|
|
unsigned char port, int in_buffer_id, int start,
|
|
int repeat_cnt, int duration)
|
|
{
|
|
sangoma_status_t rc;
|
|
wanec_api_playout_t playout;
|
|
|
|
memset(&playout, 0, sizeof(wanec_api_playout_t));
|
|
|
|
playout.start = start;
|
|
playout.fe_chan = fe_chan_map;
|
|
playout.buffer_id = in_buffer_id;
|
|
playout.port = port;
|
|
playout.notifyonstop = 1;
|
|
playout.user_event_id = 0xA5; /* dummy value */
|
|
playout.repeat_cnt = repeat_cnt;
|
|
playout.duration = (duration) ? duration : cOCT6100_INVALID_VALUE; /* default is no duration */
|
|
|
|
rc = wanec_api_playout( device_name, libsng_hwec_verbosity_level, &playout);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*!
|
|
\fn void _LIBSNG_CALL sangoma_hwec_config_verbosity(int verbosity_level)
|
|
|
|
\brief Set Verbosity level of EC API Driver and Library.
|
|
The level controls amount of data
|
|
printed to stdout and to wanpipelog.txt (Windows) or
|
|
/var/log/messages (Linux) for diagnostic purposes.
|
|
|
|
\param verbosity_level Valid values are from 0 to 3.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_config_verbosity(int verbosity_level)
|
|
{
|
|
if (verbosity_level >= 0 || verbosity_level <= 3) {
|
|
libsng_hwec_verbosity_level = verbosity_level;
|
|
wanec_api_set_lib_verbosity(verbosity_level);
|
|
return SANG_STATUS_SUCCESS;
|
|
}
|
|
return SANG_STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_channel_statistics(sng_fd_t fd, unsigned int fe_chan,
|
|
int *hwec_api_return_code, wanec_chan_stats_t *wanec_chan_stats, int reset)
|
|
|
|
\brief Get Channel statistics from EC chip.
|
|
|
|
\param fd device file descriptor
|
|
|
|
\param fe_chan Channel number (a timeslot for Digital, a line for Analog) where
|
|
the call will read statistics. Valid values are from 1 to 31.
|
|
|
|
\param hwec_api_return_code will contain one of WAN_EC_API_RC_x codes which are defined in wanec_iface_api.h
|
|
|
|
\param wanec_chip_stats structure will be filled with HWEC channel statistics.
|
|
|
|
\param verbose Flag indicating to the Driver to print additional information about the command into Wanpipe Log file.
|
|
|
|
\param reset Flag to reset (flush) channel statistics to zero, if set to 1.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status of IOCTL
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_channel_statistics(sng_fd_t fd, unsigned int fe_chan,
|
|
int *hwec_api_return_code, wanec_chan_stats_t *wanec_chan_stats, int verbose, int reset)
|
|
{
|
|
sangoma_status_t err;
|
|
wan_ec_api_t ec_api;
|
|
|
|
memset(&ec_api, 0x00, sizeof(ec_api));
|
|
|
|
ec_api.cmd = WAN_EC_API_CMD_STATS_FULL;
|
|
|
|
ec_api.verbose = verbose;
|
|
|
|
/* translate channel number into "single bit" bitmap */
|
|
ec_api.fe_chan_map = (1 << fe_chan);
|
|
|
|
/* user may want to reset (clear) Channel statistics */
|
|
ec_api.u_chan_stats.reset = reset;
|
|
|
|
err = sangoma_hwec_ioctl(fd, &ec_api);
|
|
if (err) {
|
|
/* error in IOCTL */
|
|
return err;
|
|
}
|
|
|
|
/* copy stats from driver buffer to user buffer */
|
|
memcpy(wanec_chan_stats, &ec_api.u_chan_stats, sizeof(*wanec_chan_stats));
|
|
|
|
*hwec_api_return_code = ec_api.err;
|
|
|
|
return SANG_STATUS_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_global_chip_statistics(sng_fd_t fd,
|
|
int *hwec_api_return_code, wanec_chip_stats_t *wanec_chip_stats, int verbose, int reset)
|
|
|
|
\brief Get Global statistics from EC chip.
|
|
|
|
\param fd device file descriptor
|
|
|
|
\param hwec_api_return_code will contain one of WAN_EC_API_RC_x codes which are defined in wanec_iface_api.h
|
|
|
|
\param wanec_chip_stats structure will be filled with HWEC channel statistics.
|
|
|
|
\param verbose Flag indicating to the Driver to print additional information about the command into Wanpipe Log file.
|
|
|
|
\param reset Flag to reset (flush) global statistics to zero, if set to 1.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status of IOCTL
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_global_chip_statistics(sng_fd_t fd,
|
|
int *hwec_api_return_code, wanec_chip_stats_t *wanec_chip_stats, int verbose, int reset)
|
|
{
|
|
|
|
sangoma_status_t err;
|
|
wan_ec_api_t ec_api;
|
|
|
|
memset(&ec_api, 0x00, sizeof(ec_api));
|
|
|
|
ec_api.cmd = WAN_EC_API_CMD_STATS_FULL;
|
|
|
|
ec_api.verbose = verbose;
|
|
|
|
/* indicate to Driver to get chip stats, not channel stats, by setting fe_chan_map to zero */
|
|
ec_api.fe_chan_map = 0;
|
|
|
|
/* user may want to reset (clear) Chip statistics */
|
|
ec_api.u_chip_stats.reset = reset;
|
|
|
|
err = sangoma_hwec_ioctl(fd, &ec_api);
|
|
if (err) {
|
|
/* error in IOCTL */
|
|
return err;
|
|
}
|
|
|
|
/* copy stats from driver buffer to user buffer */
|
|
memcpy(wanec_chip_stats, &ec_api.u_chip_stats, sizeof(*wanec_chip_stats));
|
|
|
|
*hwec_api_return_code = ec_api.err;
|
|
|
|
return SANG_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
/*!
|
|
\fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_chip_image_info(sng_fd_t fd,
|
|
int *hwec_api_return_code, wanec_chip_image_t *wanec_chip_image, int verbose)
|
|
|
|
\brief Get information about Firmware Image of EC chip.
|
|
|
|
\param fd device file descriptor
|
|
|
|
\param hwec_api_return_code will contain one of WAN_EC_API_RC_x codes which are defined in wanec_iface_api.h
|
|
|
|
\param wanec_chip_image_t structure will be filled with HWEC channel statistics.
|
|
|
|
\param verbose Flag indicating to the Driver to print additional information about the command into Wanpipe Log file.
|
|
|
|
\return SANG_STATUS_SUCCESS: success, or error status of IOCTL
|
|
*/
|
|
sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_chip_image_info(sng_fd_t fd,
|
|
int *hwec_api_return_code, wanec_chip_image_t *wanec_chip_image, int verbose)
|
|
{
|
|
sangoma_status_t err;
|
|
wan_ec_api_t ec_api;
|
|
|
|
memset(&ec_api, 0x00, sizeof(ec_api));
|
|
|
|
ec_api.cmd = WAN_EC_API_CMD_STATS_IMAGE;
|
|
|
|
ec_api.verbose = verbose;
|
|
|
|
/* driver will copy image information into wanec_chip_image->f_ChipImageInfo */
|
|
ec_api.u_chip_image.f_ChipImageInfo = wanec_chip_image->f_ChipImageInfo;
|
|
|
|
err = sangoma_hwec_ioctl(fd, &ec_api);
|
|
if (err) {
|
|
/* error in IOCTL */
|
|
return err;
|
|
}
|
|
|
|
*hwec_api_return_code = ec_api.err;
|
|
|
|
return SANG_STATUS_SUCCESS;
|
|
}
|
|
|
|
#endif /* WP_API_FEATURE_LIBSNG_HWEC */
|