mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-15 22:08:33 +00:00
Merge root@192.168.1.163:/freeswitch
Conflicts: libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
This commit is contained in:
commit
c4f821f822
26 files changed
+1002
-153
No files matched your search
@@ -91,6 +91,7 @@ static struct {
|
||||
char hold_music[256];
|
||||
switch_mutex_t *mutex;
|
||||
analog_option_t analog_options;
|
||||
switch_hash_t *ss7_configs;
|
||||
} globals;
|
||||
|
||||
struct private_object {
|
||||
@@ -1961,6 +1962,15 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
||||
}
|
||||
|
||||
|
||||
static FIO_SIGNAL_CB_FUNCTION(on_ss7_signal)
|
||||
{
|
||||
if (on_common_signal(sigmsg) == FTDM_BREAK) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "got ss7 sig %d:%d [%s]\n", sigmsg->channel->span_id, sigmsg->channel->chan_id, ftdm_signal_event2str(sigmsg->event_id));
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_SIGNAL_CB_FUNCTION(on_analog_signal)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
@@ -2022,10 +2032,140 @@ static uint32_t enable_analog_option(const char *str, uint32_t current_options)
|
||||
|
||||
}
|
||||
|
||||
/* create ftdm_conf_node_t tree based on a fixed pattern XML configuration list
|
||||
* last 2 args are for limited aka dumb recursivity
|
||||
* */
|
||||
static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode,
|
||||
const char *list_name, const char *list_element_name,
|
||||
const char *sub_list_name, const char *sub_list_element_name)
|
||||
{
|
||||
char *var, *val;
|
||||
switch_xml_t list;
|
||||
switch_xml_t element;
|
||||
switch_xml_t param;
|
||||
|
||||
ftdm_conf_node_t *n_list;
|
||||
ftdm_conf_node_t *n_element;
|
||||
|
||||
list = switch_xml_child(swnode, list_name);
|
||||
if (!list) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no list %s found\n", list_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS != ftdm_conf_node_create(list_name, &n_list, rootnode))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node\n", list_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (element = switch_xml_child(list, list_element_name); element; element = element->next) {
|
||||
char *element_name = (char *) switch_xml_attr(element, "name");
|
||||
|
||||
if (!element_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS != ftdm_conf_node_create(list_element_name, &n_element, n_list))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", list_element_name, element_name);
|
||||
return -1;
|
||||
}
|
||||
ftdm_conf_node_add_param(n_element, "name", element_name);
|
||||
|
||||
for (param = switch_xml_child(element, "param"); param; param = param->next) {
|
||||
var = (char *) switch_xml_attr_soft(param, "name");
|
||||
val = (char *) switch_xml_attr_soft(param, "value");
|
||||
ftdm_conf_node_add_param(n_element, var, val);
|
||||
}
|
||||
|
||||
if (sub_list_name && sub_list_element_name) {
|
||||
if (add_config_list_nodes(element, n_element, sub_list_name, sub_list_element_name, NULL, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confname)
|
||||
{
|
||||
switch_xml_t signode, ss7configs, isup;
|
||||
ftdm_conf_node_t *rootnode;
|
||||
|
||||
/* try to find the conf in the hash first */
|
||||
rootnode = switch_core_hash_find(globals.ss7_configs, confname);
|
||||
if (rootnode) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ss7 config %s was found in the hash already\n", confname);
|
||||
return rootnode;
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not found %s config in hash, searching in xml ...\n", confname);
|
||||
|
||||
signode = switch_xml_child(cfg, "signaling_configs");
|
||||
if (!signode) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'signaling_configs' XML config section\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ss7configs = switch_xml_child(signode, "sngss7_configs");
|
||||
if (!ss7configs) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'sngss7_configs' XML config section\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* search the isup config */
|
||||
for (isup = switch_xml_child(ss7configs, "sng_isup"); isup; isup = isup->next) {
|
||||
char *name = (char *) switch_xml_attr(isup, "name");
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(name, confname)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isup) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found '%s' sng_isup XML config section\n", confname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* found our XML chunk, create the root node */
|
||||
if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_isup", &rootnode, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create root node for sng_isup config %s\n", confname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add mtp linksets */
|
||||
if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", "mtp_links", "mtp_link")) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_linksets for sng_isup config %s\n", confname);
|
||||
ftdm_conf_node_destroy(rootnode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add mtp routes */
|
||||
if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", NULL, NULL)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_routes for sng_isup config %s\n", confname);
|
||||
ftdm_conf_node_destroy(rootnode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add isup interfaces */
|
||||
if (add_config_list_nodes(isup, rootnode, "isup_interfaces", "isup_interface", NULL, NULL)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process isup_interfaces for sng_isup config %s\n", confname);
|
||||
ftdm_conf_node_destroy(rootnode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch_core_hash_insert(globals.ss7_configs, confname, rootnode);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added SS7 node configuration %s\n", confname);
|
||||
return rootnode;
|
||||
}
|
||||
|
||||
static switch_status_t load_config(void)
|
||||
{
|
||||
const char *cf = "freetdm.conf";
|
||||
switch_xml_t cfg, xml, settings, param, spans, myspan;
|
||||
ftdm_conf_node_t *ss7confnode = NULL;
|
||||
ftdm_span_t *boost_spans[FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN];
|
||||
ftdm_span_t *boost_span = NULL;
|
||||
unsigned boosti = 0;
|
||||
@@ -2054,6 +2194,91 @@ static switch_status_t load_config(void)
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_hash_init(&globals.ss7_configs, module_pool);
|
||||
if ((spans = switch_xml_child(cfg, "ss7_spans"))) {
|
||||
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
|
||||
ftdm_status_t zstatus = FTDM_FAIL;
|
||||
const char *context = "default";
|
||||
const char *dialplan = "XML";
|
||||
ftdm_conf_parameter_t spanparameters[30];
|
||||
char *id = (char *) switch_xml_attr(myspan, "id");
|
||||
char *name = (char *) switch_xml_attr(myspan, "name");
|
||||
char *configname = (char *) switch_xml_attr(myspan, "config");
|
||||
ftdm_span_t *span = NULL;
|
||||
uint32_t span_id = 0;
|
||||
unsigned paramindex = 0;
|
||||
if (!name && !id) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ss7 span missing required attribute 'id' or 'name', skipping ...\n");
|
||||
continue;
|
||||
}
|
||||
if (!configname) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ss7 span missing required attribute, skipping ...\n");
|
||||
continue;
|
||||
}
|
||||
if (name) {
|
||||
zstatus = ftdm_span_find_by_name(name, &span);
|
||||
} else {
|
||||
if (switch_is_number(id)) {
|
||||
span_id = atoi(id);
|
||||
zstatus = ftdm_span_find(span_id, &span);
|
||||
}
|
||||
|
||||
if (zstatus != FTDM_SUCCESS) {
|
||||
zstatus = ftdm_span_find_by_name(id, &span);
|
||||
}
|
||||
}
|
||||
|
||||
if (zstatus != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!span_id) {
|
||||
span_id = span->span_id;
|
||||
}
|
||||
|
||||
ss7confnode = get_ss7_config_node(cfg, configname);
|
||||
if (!ss7confnode) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error finding ss7config '%s' for FreeTDM span id: %s\n", configname, switch_str_nil(id));
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(spanparameters, 0, sizeof(spanparameters));
|
||||
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
|
||||
if (sizeof(spanparameters)/sizeof(spanparameters[0]) == paramindex) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strcasecmp(var, "context")) {
|
||||
context = val;
|
||||
} else if (!strcasecmp(var, "dialplan")) {
|
||||
dialplan = val;
|
||||
} else {
|
||||
spanparameters[paramindex].var = var;
|
||||
spanparameters[paramindex].val = val;
|
||||
paramindex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_configure_span("ss7", span, on_ss7_signal,
|
||||
"confnode", ss7confnode,
|
||||
"parameters", spanparameters,
|
||||
TAG_END) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error configuring ss7 FreeTDM span %d\n", span_id);
|
||||
continue;
|
||||
}
|
||||
SPAN_CONFIG[span->span_id].span = span;
|
||||
switch_copy_string(SPAN_CONFIG[span->span_id].context, context, sizeof(SPAN_CONFIG[span->span_id].context));
|
||||
switch_copy_string(SPAN_CONFIG[span->span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span->span_id].dialplan));
|
||||
switch_copy_string(SPAN_CONFIG[span->span_id].type, "Sangoma (SS7)", sizeof(SPAN_CONFIG[span->span_id].type));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Configured ss7 FreeTDM span %d with config node %s\n", span_id, configname);
|
||||
}
|
||||
}
|
||||
|
||||
if ((spans = switch_xml_child(cfg, "analog_spans"))) {
|
||||
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
|
||||
char *id = (char *) switch_xml_attr(myspan, "id");
|
||||
@@ -2504,7 +2729,6 @@ static switch_status_t load_config(void)
|
||||
const char *dialplan = "XML";
|
||||
uint32_t span_id = 0;
|
||||
ftdm_span_t *span = NULL;
|
||||
const char *tonegroup = NULL;
|
||||
ftdm_conf_parameter_t spanparameters[30];
|
||||
unsigned paramindex = 0;
|
||||
|
||||
@@ -2526,9 +2750,8 @@ static switch_status_t load_config(void)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for boost span, ignoring any parameter after %s\n", var);
|
||||
break;
|
||||
}
|
||||
if (!strcasecmp(var, "tonegroup")) {
|
||||
tonegroup = val;
|
||||
} else if (!strcasecmp(var, "context")) {
|
||||
|
||||
if (!strcasecmp(var, "context")) {
|
||||
context = val;
|
||||
} else if (!strcasecmp(var, "dialplan")) {
|
||||
dialplan = val;
|
||||
@@ -2539,10 +2762,6 @@ static switch_status_t load_config(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!tonegroup) {
|
||||
tonegroup = "us";
|
||||
}
|
||||
|
||||
if (name) {
|
||||
zstatus = ftdm_span_find_by_name(name, &span);
|
||||
} else {
|
||||
@@ -3194,6 +3413,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
|
||||
const void *var;
|
||||
void *val;
|
||||
|
||||
/* destroy ss7 configs */
|
||||
for (hi = switch_hash_first(NULL, globals.ss7_configs); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
ftdm_conf_node_destroy(val);
|
||||
}
|
||||
|
||||
ftdm_global_destroy();
|
||||
|
||||
// this breaks pika but they are MIA so *shrug*
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
*/
|
||||
|
||||
#include "freetdm.h"
|
||||
@@ -239,6 +243,82 @@ FT_DECLARE (int) ftdm_config_get_cas_bits(char *strvalue, unsigned char *outbits
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PARAMETERS_CHUNK_SIZE 20
|
||||
FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent)
|
||||
{
|
||||
ftdm_conf_node_t *newnode;
|
||||
ftdm_conf_node_t *sibling = NULL;
|
||||
|
||||
ftdm_assert_return(name != NULL, FTDM_FAIL, "null node name");
|
||||
|
||||
newnode = ftdm_calloc(1, sizeof(**node));
|
||||
if (!newnode) {
|
||||
return FTDM_MEMERR;
|
||||
}
|
||||
|
||||
strncpy(newnode->name, name, sizeof(newnode->name)-1);
|
||||
newnode->name[sizeof(newnode->name)-1] = 0;
|
||||
|
||||
newnode->parameters = ftdm_calloc(PARAMETERS_CHUNK_SIZE, sizeof(*newnode->parameters));
|
||||
if (!newnode->parameters) {
|
||||
ftdm_safe_free(newnode);
|
||||
return FTDM_MEMERR;
|
||||
}
|
||||
newnode->t_parameters = PARAMETERS_CHUNK_SIZE;
|
||||
|
||||
if (parent) {
|
||||
/* store who my parent is */
|
||||
newnode->parent = parent;
|
||||
/* save any siblings */
|
||||
sibling = parent->child;
|
||||
/* as a newborn I am first */
|
||||
parent->child = newnode;
|
||||
if (sibling) {
|
||||
/* store a pointer to my next sibling */
|
||||
newnode->next = sibling;
|
||||
}
|
||||
}
|
||||
|
||||
*node = newnode;
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val)
|
||||
{
|
||||
void *newparameters;
|
||||
|
||||
ftdm_assert_return(param != NULL, FTDM_FAIL, "param is null");
|
||||
ftdm_assert_return(val != NULL, FTDM_FAIL, "val is null");
|
||||
|
||||
if (node->n_parameters == node->t_parameters) {
|
||||
newparameters = ftdm_realloc(node->parameters, (node->t_parameters + PARAMETERS_CHUNK_SIZE) * sizeof(*node->parameters));
|
||||
if (!newparameters) {
|
||||
return FTDM_MEMERR;
|
||||
}
|
||||
node->parameters = newparameters;
|
||||
node->t_parameters = node->n_parameters + PARAMETERS_CHUNK_SIZE;
|
||||
}
|
||||
node->parameters[node->n_parameters].var = param;
|
||||
node->parameters[node->n_parameters].val = val;
|
||||
node->n_parameters++;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node)
|
||||
{
|
||||
ftdm_conf_node_t *curr = NULL;
|
||||
ftdm_conf_node_t *child = node->child;
|
||||
while (child) {
|
||||
curr = child;
|
||||
child = curr->next;
|
||||
ftdm_conf_node_destroy(curr);
|
||||
}
|
||||
ftdm_free(node->parameters);
|
||||
ftdm_free(node);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
||||
@@ -1087,16 +1087,20 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(ftdm_channel_t *ftdmchan, ftdm_
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Ignored state change request from %s to %s, the previous state change has not been processed yet\n",
|
||||
ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (lock) {
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Ignored state change request from %s to %s, the previous state change has not been processed yet\n",
|
||||
ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
if (lock) {
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
||||
if (ftdmchan->span->state_map) {
|
||||
ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
|
||||
goto end;
|
||||
@@ -1353,7 +1357,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
|
||||
ftdm_span_channel_use_count(span, &count);
|
||||
|
||||
if (count >= span->chan_count) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "All circuits are busy.\n");
|
||||
ftdm_log(FTDM_LOG_CRIT, "All circuits are busy: active=%i max=%i.\n",
|
||||
count, span->chan_count);
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
@@ -1623,8 +1628,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_sig_status(ftdm_channel_t *ftdmchan,
|
||||
if (ftdmchan->span->get_channel_sig_status) {
|
||||
return ftdmchan->span->get_channel_sig_status(ftdmchan, sigstatus);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "get_channel_sig_status method not implemented!\n");
|
||||
return FTDM_FAIL;
|
||||
/* don't log error here, it can be called just to test if its supported */
|
||||
return FTDM_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -414,7 +414,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
||||
for (i = 0; i < size; i++) {
|
||||
ints[i] = interrupts[i]->event;
|
||||
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
|
||||
ints[i+numdevices] = interrupts[i]->device;
|
||||
ints[size+numdevices] = interrupts[i]->device;
|
||||
numdevices++;
|
||||
}
|
||||
}
|
||||
@@ -446,9 +446,9 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
||||
ints[i].revents = 0;
|
||||
ints[i].fd = interrupts[i]->readfd;
|
||||
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
|
||||
ints[i+numdevices].events = POLLIN;
|
||||
ints[i+numdevices].revents = 0;
|
||||
ints[i+numdevices].fd = interrupts[i]->device;
|
||||
ints[size+numdevices].events = POLLIN;
|
||||
ints[size+numdevices].revents = 0;
|
||||
ints[size+numdevices].fd = interrupts[i]->device;
|
||||
numdevices++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@ typedef uint16_t sangoma_boost_request_id_t;
|
||||
typedef enum {
|
||||
BST_FREE,
|
||||
BST_WAITING,
|
||||
BST_ACK,
|
||||
BST_READY,
|
||||
BST_FAIL
|
||||
} sangoma_boost_request_status_t;
|
||||
@@ -109,6 +108,13 @@ typedef struct {
|
||||
int flags;
|
||||
} sangoma_boost_request_t;
|
||||
|
||||
typedef struct {
|
||||
int call_setup_id;
|
||||
int last_event_id;
|
||||
} sangoma_boost_call_t;
|
||||
|
||||
#define CALL_DATA(ftdmchan) ((sangoma_boost_call_t*)((ftdmchan)->call_data))
|
||||
|
||||
//#define MAX_REQ_ID FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN * FTDM_MAX_CHANNELS_PHYSICAL_SPAN
|
||||
#define MAX_REQ_ID 6000
|
||||
|
||||
@@ -179,7 +185,7 @@ static sangoma_boost_request_id_t __next_request_id(const char *func, int line)
|
||||
r = ++last_req;
|
||||
|
||||
if (r >= MAX_REQ_ID) {
|
||||
r = i = last_req = 1;
|
||||
r = last_req = 1;
|
||||
}
|
||||
|
||||
if (req_map[r]) {
|
||||
@@ -204,6 +210,25 @@ static sangoma_boost_request_id_t __next_request_id(const char *func, int line)
|
||||
}
|
||||
#define next_request_id() __next_request_id(__FUNCTION__, __LINE__)
|
||||
|
||||
|
||||
static void print_request_ids(void)
|
||||
{
|
||||
sangoma_boost_request_id_t i = 0;
|
||||
|
||||
ftdm_mutex_lock(request_mutex);
|
||||
|
||||
for (i=1; i<= MAX_REQ_ID; i++){
|
||||
if (req_map[i]) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Used Request ID=%i\n",i);
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(request_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Finds the channel that triggered an event
|
||||
* \param span Span where to search the channel
|
||||
@@ -215,10 +240,26 @@ static ftdm_channel_t *find_ftdmchan(ftdm_span_t *span, sangomabc_short_event_t
|
||||
{
|
||||
uint32_t i;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
|
||||
ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
|
||||
uint32_t targetspan = BOOST_EVENT_SPAN(sangoma_boost_data->sigmod, event);
|
||||
uint32_t targetchan = BOOST_EVENT_CHAN(sangoma_boost_data->sigmod, event);
|
||||
|
||||
/* NC: Sanity check in case the call setup id does not relate
|
||||
to span. This can happen if RESTART is received on a
|
||||
full load. Where stray ACK messages can arrive after
|
||||
a RESTART has taken place.
|
||||
*/
|
||||
if (!span) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "No Span for Event=%s s%dc%d cid=%d\n",
|
||||
BOOST_DECODE_EVENT_ID(event->event_id),
|
||||
event->span,
|
||||
event->chan,
|
||||
event->call_setup_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for(i = 1; i <= span->chan_count; i++) {
|
||||
if (span->channels[i]->physical_span_id == targetspan && span->channels[i]->physical_chan_id == targetchan) {
|
||||
ftdmchan = span->channels[i];
|
||||
@@ -276,12 +317,20 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
||||
* and PRI stack will retransmit a second SETUP after the first timeout, so
|
||||
* we should allow for at least 8 seconds.
|
||||
*/
|
||||
|
||||
int boost_request_timeout = 10000;
|
||||
sangoma_boost_request_status_t st;
|
||||
char dnis[128] = "";
|
||||
char *gr = NULL;
|
||||
uint32_t count = 0;
|
||||
int tg=0;
|
||||
|
||||
/* NC: On large number of calls 10 seconds is not enough.
|
||||
Resetting to 30 seconds. Especially on ss7 when
|
||||
links are reset during large call volume */
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
boost_request_timeout = 30000;
|
||||
}
|
||||
|
||||
if (sangoma_boost_data->sigmod) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "This function should not be called when sigmod was configured in boost\n");
|
||||
@@ -290,12 +339,22 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_SUSPENDED)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "SPAN is not online.\n");
|
||||
ftdm_log(FTDM_LOG_CRIT, "SPAN is Suspended.\n");
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (check_congestion(tg)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "All circuits are busy. Trunk Group=%i (CONGESTION)\n",tg+1);
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (count >= span->chan_count) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "All circuits are busy.\n");
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_set_string(dnis, caller_data->dnis.digits);
|
||||
|
||||
r = next_request_id();
|
||||
if (r == 0) {
|
||||
@@ -303,7 +362,11 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
sangomabc_call_init(&event, caller_data->cid_num.digits, dnis, r);
|
||||
|
||||
/* After this point we must release request id before we leave the function
|
||||
in case of an error. */
|
||||
|
||||
ftdm_set_string(dnis, caller_data->dnis.digits);
|
||||
|
||||
if ((gr = strchr(dnis, '@'))) {
|
||||
*gr++ = '\0';
|
||||
@@ -315,22 +378,14 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
||||
tg--;
|
||||
}
|
||||
}
|
||||
|
||||
sangomabc_call_init(&event, caller_data->cid_num.digits, dnis, r);
|
||||
|
||||
event.trunk_group = tg;
|
||||
|
||||
if (check_congestion(tg)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "All circuits are busy. Trunk Group=%i (BOOST REQUESTED BACK OFF)\n",tg+1);
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_span_channel_use_count(span, &count);
|
||||
|
||||
if (count >= span->chan_count) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "All circuits are busy.\n");
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (gr && *(gr+1)) {
|
||||
switch(*gr) {
|
||||
case 'g':
|
||||
@@ -373,7 +428,7 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
||||
|
||||
if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno));
|
||||
status = FTDM_FAIL;
|
||||
status = OUTBOUND_REQUESTS[r].status = FTDM_FAIL;
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
*ftdmchan = NULL;
|
||||
}
|
||||
@@ -387,7 +442,7 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
*ftdmchan = NULL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_CRIT, "s%dc%d: Csid:%d Timed out waiting for boost channel request response, current status: BST_WAITING\n", (*ftdmchan)->physical_span_id, (*ftdmchan)->physical_chan_id, r);
|
||||
ftdm_log(FTDM_LOG_CRIT, "Csid:%d Timed out waiting for boost channel request response, current status: BST_WAITING\n", r);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -494,6 +549,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(sangoma_boost_outgoing_call)
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Dialing number %s over boost channel with request id %d\n", event.called_number_digits, r);
|
||||
if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) {
|
||||
release_request_id(r);
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
@@ -550,7 +606,12 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_
|
||||
uint32_t event_span = BOOST_EVENT_SPAN(mcon->sigmod, event);
|
||||
uint32_t event_chan = BOOST_EVENT_CHAN(mcon->sigmod, event);
|
||||
|
||||
|
||||
if (nack_map[event->call_setup_id]) {
|
||||
/* In this scenario outgoing call was alrady stopped
|
||||
via NACK and now we are expecting an NACK_ACK.
|
||||
If we receive an ACK its a race condition thus
|
||||
ignor it */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -607,15 +668,43 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_
|
||||
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
ftdm_assert(!mcon->sigmod, "CALL STOP ACK: Invalid Sigmod Path");
|
||||
|
||||
if ((ftdmchan = find_ftdmchan(OUTBOUND_REQUESTS[event->call_setup_id].span, (sangomabc_short_event_t*)event, 1))) {
|
||||
int r;
|
||||
/* NC: If we get CALL START ACK and channel is in active state
|
||||
then we are completely out of sync with the other end.
|
||||
Treat CALL START ACK as CALL STOP and hangup the current call.
|
||||
*/
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_UP ||
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA ||
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "FTDM_CHAN STATE UP/PROG/PROG_MEDIA -> Changed to HANGUP %d:%d\n", event->span+1,event->chan+1);
|
||||
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP, 0, r);
|
||||
|
||||
} else if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) {
|
||||
/* Do nothing because outgoing STOP will generaate a stop ack */
|
||||
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "FTDM_CHAN STATE INVALID %s on IN CALL ACK %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1);
|
||||
|
||||
}
|
||||
ftdmchan=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!ftdmchan) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "START ACK CANT FIND A CHAN %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
|
||||
} else {
|
||||
/* only reason to be here is failed to open channel when we we're in sigmod */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG);
|
||||
}
|
||||
ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG);
|
||||
|
||||
sangomabc_exec_command(mcon,
|
||||
event->span,
|
||||
event->chan,
|
||||
@@ -636,7 +725,7 @@ static void handle_call_done(ftdm_span_t *span, sangomabc_connection_t *mcon, sa
|
||||
{
|
||||
ftdm_channel_t *ftdmchan;
|
||||
int r = 0;
|
||||
|
||||
|
||||
if ((ftdmchan = find_ftdmchan(span, event, 1))) {
|
||||
ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data;
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
@@ -677,6 +766,7 @@ static void handle_call_done(ftdm_span_t *span, sangomabc_connection_t *mcon, sa
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Handler for call start nack event
|
||||
* \param span Span where event was fired
|
||||
@@ -718,7 +808,7 @@ static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mc
|
||||
if (event->call_setup_id) {
|
||||
if (sangoma_boost_data->sigmod) {
|
||||
ftdmchan = OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan;
|
||||
ftdmchan->call_data = (void*)(intptr_t)event->event_id;
|
||||
CALL_DATA(ftdmchan)->last_event_id = event->event_id;
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
} else {
|
||||
sangomabc_exec_command(mcon,
|
||||
@@ -740,7 +830,7 @@ static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mc
|
||||
/* if there is no call setup id this should not be an outbound channel for sure */
|
||||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), "Yay, outbound flag should not be set here!\n");
|
||||
|
||||
ftdmchan->call_data = (void*)(intptr_t)event->event_id;
|
||||
CALL_DATA(ftdmchan)->last_event_id = event->event_id;
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
|
||||
if (r == FTDM_STATE_CHANGE_SUCCESS) {
|
||||
@@ -793,7 +883,16 @@ static void handle_call_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sa
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) {
|
||||
if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP) ||
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_DOWN ||
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
|
||||
/* NC: Checking for state DOWN because ss7box can
|
||||
send CALL_STOP twice in a row. If we do not check for
|
||||
STATE_DOWN we will set the state back to termnating
|
||||
and block the channel forever
|
||||
*/
|
||||
|
||||
/* racing condition where both sides initiated a hangup
|
||||
* Do not change current state as channel is already clearing
|
||||
* itself through local initiated hangup */
|
||||
@@ -848,8 +947,18 @@ static void handle_call_answer(ftdm_span_t *span, sangomabc_connection_t *mcon,
|
||||
|
||||
if ((ftdmchan = find_ftdmchan(span, event, 1))) {
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) {
|
||||
|
||||
if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP) ||
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_DOWN ||
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
|
||||
/* NC: Do nothing here because we are in process
|
||||
of stopping the call. So ignore the ANSWER. */
|
||||
ftdm_log(FTDM_LOG_CRIT, "ANSWER BUT CALL IS HANGUP %d:%d\n", event->span+1,event->chan+1);
|
||||
|
||||
} else if (ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) {
|
||||
ftdmchan->init_state = FTDM_CHANNEL_STATE_UP;
|
||||
|
||||
} else {
|
||||
int r = 0;
|
||||
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_UP, 0, r);
|
||||
@@ -881,6 +990,12 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
|
||||
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) {
|
||||
if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) {
|
||||
int r;
|
||||
|
||||
/* NC: If we get CALL START and channel is in active state
|
||||
then we are completely out of sync with the other end.
|
||||
Treat CALL START as CALL STOP and hangup the current call.
|
||||
*/
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
|
||||
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
|
||||
@@ -1179,8 +1294,12 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
|
||||
handle_call_done(span, mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_CALL_START_NACK_ACK:
|
||||
handle_call_done(span, mcon, event);
|
||||
nack_map[event->call_setup_id] = 0;
|
||||
/* On NACK ack span chan are always invalid
|
||||
All there is to do is to clear the id */
|
||||
if (event->call_setup_id) {
|
||||
nack_map[event->call_setup_id] = 0;
|
||||
release_request_id(event->call_setup_id);
|
||||
}
|
||||
break;
|
||||
case SIGBOOST_EVENT_INSERT_CHECK_LOOP:
|
||||
handle_call_loop_start(span, mcon, event);
|
||||
@@ -1246,7 +1365,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG)) {
|
||||
ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG);
|
||||
|
||||
if (ftdmchan->call_data && ((uint32_t)(intptr_t)ftdmchan->call_data == SIGBOOST_EVENT_CALL_START_NACK)) {
|
||||
if (ftdmchan->call_data && CALL_DATA(ftdmchan)->last_event_id == SIGBOOST_EVENT_CALL_START_NACK) {
|
||||
sangomabc_exec_command(mcon,
|
||||
BOOST_SPAN(ftdmchan),
|
||||
BOOST_CHAN(ftdmchan),
|
||||
@@ -1266,7 +1385,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
}
|
||||
}
|
||||
ftdmchan->sflags = 0;
|
||||
ftdmchan->call_data = NULL;
|
||||
memset(ftdmchan->call_data,0,sizeof(sangoma_boost_call_t));
|
||||
|
||||
if (sangoma_boost_data->sigmod && call_stopped_ack_sent) {
|
||||
/* we dont want to call ftdm_channel_done just yet until call released is received */
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n",
|
||||
@@ -1457,13 +1577,17 @@ static __inline__ void check_state(ftdm_span_t *span)
|
||||
uint32_t j;
|
||||
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
|
||||
if (susp) {
|
||||
for (j = 0; j <= span->chan_count; j++) {
|
||||
ftdm_mutex_lock(span->channels[j]->mutex);
|
||||
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART, 0);
|
||||
state_advance(span->channels[j]);
|
||||
ftdm_channel_complete_state(span->channels[j]);
|
||||
ftdm_mutex_unlock(span->channels[j]->mutex);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE) || susp) {
|
||||
ftdm_mutex_lock(span->channels[j]->mutex);
|
||||
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
|
||||
if (susp && span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_channel_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART, 0);
|
||||
}
|
||||
state_advance(span->channels[j]);
|
||||
ftdm_channel_complete_state(span->channels[j]);
|
||||
ftdm_mutex_unlock(span->channels[j]->mutex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ((ftdmchan = ftdm_queue_dequeue(span->pendingchans))) {
|
||||
@@ -1642,8 +1766,8 @@ static int ftdm_boost_wait_event(ftdm_span_t *span)
|
||||
sangoma_boost_data->iteration = 0;
|
||||
}
|
||||
#endif
|
||||
res = ftdm_interrupt_multiple_wait(ints, numints, -1);
|
||||
if (FTDM_SUCCESS != res) {
|
||||
res = ftdm_interrupt_multiple_wait(ints, numints, 100);
|
||||
if (FTDM_SUCCESS != res && FTDM_TIMEOUT != res) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Unexpected return value from interrupt waiting: %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
@@ -1730,7 +1854,6 @@ static void *ftdm_sangoma_boost_run(ftdm_thread_t *me, void *obj)
|
||||
|
||||
if (ftdm_boost_wait_event(span) < 0) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "ftdm_boost_wait_event failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((event = ftdm_boost_read_event(span))) {
|
||||
@@ -1743,7 +1866,6 @@ static void *ftdm_sangoma_boost_run(ftdm_thread_t *me, void *obj)
|
||||
|
||||
goto end;
|
||||
|
||||
error:
|
||||
ftdm_log(FTDM_LOG_CRIT, "Boost event processing Error!\n");
|
||||
|
||||
end:
|
||||
@@ -1758,6 +1880,37 @@ end:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int sigmod_ss7box_isup_exec_cmd(ftdm_stream_handle_t *stream, char *cmd)
|
||||
{
|
||||
FILE *fp;
|
||||
int status=0;
|
||||
char path[1024];
|
||||
|
||||
fp = popen(cmd, "r");
|
||||
if (fp == NULL) {
|
||||
stream->write_function(stream, "%s: -ERR failed to execute cmd: %s\n",
|
||||
__FILE__,cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(path, sizeof(path)-1, fp) != NULL) {
|
||||
path[sizeof(path)-1]='\0';
|
||||
stream->write_function(stream,"%s", path);
|
||||
}
|
||||
|
||||
|
||||
status = pclose(fp);
|
||||
if (status == -1) {
|
||||
/* Error reported by pclose() */
|
||||
} else {
|
||||
/* Use macros described under wait() to inspect `status' in order
|
||||
to determine success/failure of command executed by popen() */
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define FTDM_BOOST_SYNTAX "list sigmods | <sigmod_name> <command>"
|
||||
/**
|
||||
@@ -1780,11 +1933,63 @@ static FIO_API_FUNCTION(ftdm_sangoma_boost_api)
|
||||
if (!strcasecmp(argv[0], "list")) {
|
||||
if (!strcasecmp(argv[1], "sigmods")) {
|
||||
if (ftdm_sangoma_boost_list_sigmods(stream) != FTDM_SUCCESS) {
|
||||
stream->write_function(stream, "%s: -ERR failed to execute cmd\n", __FILE__);
|
||||
stream->write_function(stream, "-ERR failed to list sigmods\n");
|
||||
goto done;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[1], "ids")) {
|
||||
print_request_ids();
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
#if 0
|
||||
/* NC: This code crashes the kernel due to fork on heavy fs load */
|
||||
} else if (!strcasecmp(argv[0], "ss7box_isupd_ckt")) {
|
||||
|
||||
if (!strcasecmp(argv[1], "used")) {
|
||||
stream->write_function(stream, "ss7box_isupd: in use\n", FTDM_BOOST_SYNTAX);
|
||||
sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh inuse");
|
||||
} else if (!strcasecmp(argv[1], "reset")) {
|
||||
stream->write_function(stream, "ss7box_isupd: in reset\n", FTDM_BOOST_SYNTAX);
|
||||
sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh reset");
|
||||
} else if (!strcasecmp(argv[1], "ready")) {
|
||||
stream->write_function(stream, "ss7box_isupd: ready \n", FTDM_BOOST_SYNTAX);
|
||||
sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh free");
|
||||
} else {
|
||||
stream->write_function(stream, "ss7box_isupd: list\n", FTDM_BOOST_SYNTAX);
|
||||
sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh");
|
||||
}
|
||||
|
||||
goto done;
|
||||
#endif
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[0], "restart")) {
|
||||
sangomabc_connection_t *pcon;
|
||||
ftdm_sangoma_boost_data_t *sangoma_boost_data;
|
||||
ftdm_span_t *span;
|
||||
int err = ftdm_span_find_by_name(argv[1], &span);
|
||||
if (FTDM_SUCCESS != err) {
|
||||
stream->write_function(stream, "-ERR failed to find span by name %s\n",argv[1]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
sangoma_boost_data = span->signal_data;
|
||||
pcon = &sangoma_boost_data->pcon;
|
||||
|
||||
/* No need to set any span flags because
|
||||
our RESTART will generate a RESTART from the sig daemon */
|
||||
sangomabc_exec_commandp(pcon,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
SIGBOOST_EVENT_SYSTEM_RESTART,
|
||||
0);
|
||||
|
||||
goto done;
|
||||
|
||||
} else {
|
||||
boost_sigmod_interface_t *sigmod_iface = NULL;
|
||||
sigmod_iface = hashtable_search(g_boost_modules_hash, argv[0]);
|
||||
@@ -1822,7 +2027,7 @@ done:
|
||||
*/
|
||||
static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_boost_io_init)
|
||||
{
|
||||
assert(fio != NULL);
|
||||
ftdm_assert(fio != NULL, "fio is NULL");
|
||||
memset(&ftdm_sangoma_boost_interface, 0, sizeof(ftdm_sangoma_boost_interface));
|
||||
|
||||
ftdm_sangoma_boost_interface.name = "boost";
|
||||
@@ -2205,6 +2410,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
|
||||
ftdm_dso_lib_t lib = NULL;
|
||||
char path[255] = "";
|
||||
char *err = NULL;
|
||||
int j = 0;
|
||||
unsigned paramindex = 0;
|
||||
ftdm_status_t rc = FTDM_SUCCESS;
|
||||
|
||||
@@ -2299,6 +2505,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
|
||||
ftdm_set_string(sangoma_boost_data->mcon.cfg.remote_ip, remote_ip);
|
||||
sangoma_boost_data->mcon.cfg.remote_port = remote_port;
|
||||
}
|
||||
|
||||
for (j = 1; j <= span->chan_count; j++) {
|
||||
span->channels[j]->call_data = ftdm_calloc(1,sizeof(sangoma_boost_call_t));
|
||||
if (!span->channels[j]->call_data) {
|
||||
FAIL_CONFIG_RETURN(FTDM_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
span->signal_cb = sig_cb;
|
||||
span->start = ftdm_sangoma_boost_start;
|
||||
span->stop = ftdm_sangoma_boost_stop;
|
||||
|
||||
@@ -77,7 +77,7 @@ static void sangomabc_print_event_call(sangomabc_connection_t *mcon, sangomabc_e
|
||||
if (event->event_id == SIGBOOST_EVENT_HEARTBEAT)
|
||||
return;
|
||||
|
||||
ftdm_log(file, func, line, FTDM_LOG_LEVEL_DEBUG, "%s EVENT (%s): %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s] Rdnis=[%s]\n",
|
||||
ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "%s EVENT (%s): %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s] Rdnis=[%s]\n",
|
||||
dir ? "TX":"RX",
|
||||
priority ? "P":"N",
|
||||
sangomabc_event_id_name(event->event_id),
|
||||
@@ -96,7 +96,7 @@ static void sangomabc_print_event_short(sangomabc_connection_t *mcon, sangomabc_
|
||||
{
|
||||
if (event->event_id == SIGBOOST_EVENT_HEARTBEAT)
|
||||
return;
|
||||
ftdm_log(file, func, line, FTDM_LOG_LEVEL_DEBUG, "%s EVENT (%s): %s:(%X) [s%dc%d] Rc=%i CSid=%i Seq=%i \n",
|
||||
ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "%s EVENT (%s): %s:(%X) [s%dc%d] Rc=%i CSid=%i Seq=%i \n",
|
||||
dir ? "TX":"RX",
|
||||
priority ? "P":"N",
|
||||
sangomabc_event_id_name(event->event_id),
|
||||
|
||||
@@ -51,6 +51,24 @@ enum e_sigboost_event_id_values
|
||||
SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE = 0x8c, /*140*/
|
||||
SIGBOOST_EVENT_DIGIT_IN = 0x8d, /*141*/
|
||||
};
|
||||
|
||||
#define BOOST_DECODE_EVENT_ID(id) \
|
||||
(id==SIGBOOST_EVENT_CALL_START)?"SIGBOOST_EVENT_CALL_START": \
|
||||
(id==SIGBOOST_EVENT_CALL_START_ACK)?"SIGBOOST_EVENT_CALL_START_ACK": \
|
||||
(id==SIGBOOST_EVENT_CALL_START_NACK)?"SIGBOOST_EVENT_CALL_START_NACK": \
|
||||
(id==SIGBOOST_EVENT_CALL_ANSWERED)?"SIGBOOST_EVENT_CALL_ANSWERED": \
|
||||
(id==SIGBOOST_EVENT_CALL_STOPPED)?"SIGBOOST_EVENT_CALL_STOPPED": \
|
||||
(id==SIGBOOST_EVENT_CALL_STOPPED_ACK)?"SIGBOOST_EVENT_CALL_STOPPED_ACK": \
|
||||
(id==SIGBOOST_EVENT_SYSTEM_RESTART)?"SIGBOOST_EVENT_SYSTEM_RESTART": \
|
||||
(id==SIGBOOST_EVENT_SYSTEM_RESTART_ACK)?"SIGBOOST_EVENT_SYSTEM_RESTART_ACK": \
|
||||
(id==SIGBOOST_EVENT_CALL_RELEASED)?"SIGBOOST_EVENT_CALL_RELEASED": \
|
||||
(id==SIGBOOST_EVENT_CALL_PROGRESS)?"SIGBOOST_EVENT_CALL_PROGRESS": \
|
||||
(id==SIGBOOST_EVENT_HEARTBEAT)?"SIGBOOST_EVENT_HEARTBEAT": \
|
||||
(id==SIGBOOST_EVENT_INSERT_CHECK_LOOP)?"SIGBOOST_EVENT_INSERT_CHECK_LOOP": \
|
||||
(id==SIGBOOST_EVENT_REMOVE_CHECK_LOOP)?"SIGBOOST_EVENT_REMOVE_CHECK_LOOP": \
|
||||
(id==SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE)?"SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE": \
|
||||
(id==SIGBOOST_EVENT_DIGIT_IN)?"SIGBOOST_EVENT_DIGIT_IN": "Unknown"
|
||||
|
||||
enum e_sigboost_release_cause_values
|
||||
{
|
||||
SIGBOOST_RELEASE_CAUSE_UNDEFINED = 0,
|
||||
|
||||
@@ -827,6 +827,9 @@ FT_DECLARE(char *) ftdm_api_execute(const char *type, const char *cmd);
|
||||
FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data);
|
||||
FT_DECLARE(void) ftdm_cpu_monitor_disable(void);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node);
|
||||
|
||||
FIO_CODEC_FUNCTION(fio_slin2ulaw);
|
||||
FIO_CODEC_FUNCTION(fio_ulaw2slin);
|
||||
|
||||
@@ -572,6 +572,30 @@ typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ;
|
||||
|
||||
#include "ftdm_dso.h"
|
||||
|
||||
#define FTDM_NODE_NAME_SIZE 50
|
||||
typedef struct ftdm_conf_node_s {
|
||||
/* node name */
|
||||
char name[FTDM_NODE_NAME_SIZE];
|
||||
|
||||
/* total slots for parameters */
|
||||
unsigned int t_parameters;
|
||||
|
||||
/* current number of parameters */
|
||||
unsigned int n_parameters;
|
||||
|
||||
/* array of parameters */
|
||||
ftdm_conf_parameter_t *parameters;
|
||||
|
||||
/* first node child */
|
||||
struct ftdm_conf_node_s *child;
|
||||
|
||||
/* next node sibling */
|
||||
struct ftdm_conf_node_s *next;
|
||||
|
||||
/* my parent if any */
|
||||
struct ftdm_conf_node_s *parent;
|
||||
} ftdm_conf_node_t;
|
||||
|
||||
typedef struct {
|
||||
char name[256];
|
||||
fio_io_load_t io_load;
|
||||
@@ -583,9 +607,9 @@ typedef struct {
|
||||
\brief configure a given span signaling
|
||||
\see sig_configure
|
||||
This is just like sig_configure but receives
|
||||
an array of paramters instead of va_list
|
||||
an an ftdm_conf_node_t instead
|
||||
I'd like to deprecate sig_configure and move
|
||||
all modules to use sigparam_configure
|
||||
all modules to use configure_span_signaling
|
||||
*/
|
||||
fio_configure_span_signaling_t configure_span_signaling;
|
||||
ftdm_dso_lib_t lib;
|
||||
|
||||
Reference in new issue
Block a user