Support for huntgroups
git-svn-id: http://svn.openzap.org/svn/openzap/branches/sangoma_boost@944 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
b433175950
commit
29436b8cd6
|
@ -1033,7 +1033,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
|
||||
const char *dest = NULL;
|
||||
char *data = NULL;
|
||||
int span_id = -1, chan_id = 0;
|
||||
int span_id = -1, group_id = -1,chan_id = 0;
|
||||
zap_channel_t *zchan = NULL;
|
||||
switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
char name[128];
|
||||
|
@ -1085,7 +1085,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
|
||||
if (span_id == 0 && chan_id != 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Span 0 is used to pick the first available span, selecting a channel is not supported (and doesn't make sense)\n");
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
if (span_id == -1 && !zstr(span_name)) {
|
||||
|
@ -1097,11 +1097,18 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
}
|
||||
|
||||
if (span_id == -1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing span\n");
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
//Look for a group
|
||||
zap_group_t *group;
|
||||
zap_status_t zstatus = zap_group_find_by_name(span_name, &group);
|
||||
if (zstatus == ZAP_SUCCESS && group) {
|
||||
group_id = group->group_id;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing span\n");
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan_id < 0) {
|
||||
if (group_id < 0 && chan_id < 0) {
|
||||
direction = ZAP_BOTTOM_UP;
|
||||
chan_id = 0;
|
||||
}
|
||||
|
@ -1143,11 +1150,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
|
||||
zap_set_string(caller_data.cid_name, outbound_profile->caller_id_name);
|
||||
zap_set_string(caller_data.cid_num.digits, outbound_profile->caller_id_number);
|
||||
|
||||
if (chan_id) {
|
||||
|
||||
if (group_id >= 0) {
|
||||
status = zap_channel_open_by_group(group_id, direction, &caller_data, &zchan);
|
||||
} else if (chan_id) {
|
||||
status = zap_channel_open(span_id, chan_id, &zchan);
|
||||
} else {
|
||||
status = zap_channel_open_any(span_id, direction, &caller_data, &zchan);
|
||||
status = zap_channel_open_by_span(span_id, direction, &caller_data, &zchan);
|
||||
}
|
||||
|
||||
if (status != ZAP_SUCCESS) {
|
||||
|
@ -1753,7 +1762,7 @@ static ZIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ZAP_SIGEVENT_PROGRESS:
|
||||
case ZAP_SIGEVENT_PROGRESS:
|
||||
{
|
||||
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
@ -1766,8 +1775,6 @@ static ZIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
sigmsg->channel->span_id, sigmsg->channel->chan_id, (uuid) ? uuid : "N/A");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
|
||||
|
|
|
@ -195,6 +195,9 @@ extern "C" {
|
|||
#define ZAP_MAX_CHANNELS_SPAN ZAP_MAX_CHANNELS_PHYSICAL_SPAN * ZAP_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN
|
||||
#define ZAP_MAX_SPANS_INTERFACE 128
|
||||
|
||||
#define ZAP_MAX_CHANNELS_GROUP 1024
|
||||
#define ZAP_MAX_GROUPS_INTERFACE ZAP_MAX_SPANS_INTERFACE
|
||||
|
||||
#define GOTO_STATUS(label,st) status = st; goto label ;
|
||||
|
||||
#define zap_copy_string(x,y,z) strncpy(x, y, z - 1)
|
||||
|
@ -578,6 +581,16 @@ struct zap_span {
|
|||
struct zap_span *next;
|
||||
};
|
||||
|
||||
struct zap_group {
|
||||
char *name;
|
||||
uint32_t group_id;
|
||||
uint32_t chan_count;
|
||||
zap_channel_t *channels[ZAP_MAX_CHANNELS_GROUP];
|
||||
uint32_t last_used_index;
|
||||
zap_mutex_t *mutex;
|
||||
struct zap_group *next;
|
||||
};
|
||||
|
||||
OZ_DECLARE_DATA extern zap_logger_t zap_log;
|
||||
|
||||
typedef enum {
|
||||
|
@ -706,11 +719,19 @@ OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **s
|
|||
OZ_DECLARE(zap_status_t) zap_span_close_all(void);
|
||||
OZ_DECLARE(zap_status_t) zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_chan_type_t type, zap_channel_t **chan);
|
||||
OZ_DECLARE(zap_status_t) zap_span_set_event_callback(zap_span_t *span, zio_event_cb_t event_callback);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_add_to_group(const char* name, zap_channel_t* zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_group_add_channels(const char* name, zap_span_t* span, const char* val);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_remove_from_group(zap_group_t* group, zap_channel_t* zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_group_find(uint32_t id, zap_group_t **group);
|
||||
OZ_DECLARE(zap_status_t) zap_group_find_by_name(const char *name, zap_group_t **group);
|
||||
OZ_DECLARE(zap_status_t) zap_group_create(zap_group_t **group, const char *name);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_set_event_callback(zap_channel_t *zchan, zio_event_cb_t event_callback);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_chan(zap_channel_t *zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_span_channel_use_count(zap_span_t *span, uint32_t *count);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_group_channel_use_count(zap_group_t *group, uint32_t *count);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_by_span(uint32_t span_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_by_group(uint32_t group_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_close(zap_channel_t **zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_done(zap_channel_t *zchan);
|
||||
OZ_DECLARE(zap_status_t) zap_channel_use(zap_channel_t *zchan);
|
||||
|
|
|
@ -458,6 +458,7 @@ typedef struct zap_channel zap_channel_t;
|
|||
typedef struct zap_event zap_event_t;
|
||||
typedef struct zap_sigmsg zap_sigmsg_t;
|
||||
typedef struct zap_span zap_span_t;
|
||||
typedef struct zap_group zap_group_t;
|
||||
typedef struct zap_caller_data zap_caller_data_t;
|
||||
typedef struct zap_io_interface zap_io_interface_t;
|
||||
|
||||
|
|
|
@ -55,8 +55,11 @@ zap_mutex_t *g_boost_modules_mutex = NULL;
|
|||
zap_hash_t *g_boost_modules_hash = NULL;
|
||||
|
||||
#define MAX_TRUNK_GROUPS 64
|
||||
//DAVIDY need to merge congestion_timeouts with zap_sangoma_boost_trunkgroups
|
||||
static time_t congestion_timeouts[MAX_TRUNK_GROUPS];
|
||||
|
||||
static zap_sangoma_boost_trunkgroup_t *g_trunkgroups[MAX_TRUNK_GROUPS];
|
||||
|
||||
#define BOOST_QUEUE_SIZE 500
|
||||
|
||||
/* get openzap span and chan depending on the span mode */
|
||||
|
@ -303,76 +306,80 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
|
||||
zap_set_string(ani, caller_data->ani.digits);
|
||||
|
||||
if ((gr = strchr(ani, '@'))) {
|
||||
*gr++ = '\0';
|
||||
}
|
||||
|
||||
if (gr && *(gr+1)) {
|
||||
tg = atoi(gr+1);
|
||||
if (tg > 0) {
|
||||
tg--;
|
||||
}
|
||||
}
|
||||
event.trunk_group = tg;
|
||||
|
||||
if (check_congestion(tg)) {
|
||||
zap_log(ZAP_LOG_CRIT, "All circuits are busy. Trunk Group=%i (BOOST REQUESTED BACK OFF)\n",tg+1);
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
zap_span_channel_use_count(span, &count);
|
||||
|
||||
if (count >= span->chan_count) {
|
||||
zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n");
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
r = next_request_id();
|
||||
if (r == 0) {
|
||||
zap_log(ZAP_LOG_CRIT, "All tanks ids are busy.\n");
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
sangomabc_call_init(&event, caller_data->cid_num.digits, ani, r);
|
||||
//sangoma_bc_call_init will clear the trunk_group val so we need to set it again
|
||||
event.trunk_group=tg;
|
||||
|
||||
if (gr && *(gr+1)) {
|
||||
|
||||
switch(*gr) {
|
||||
case 'g':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC;
|
||||
break;
|
||||
case 'G':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_SEQ_DESC;
|
||||
break;
|
||||
case 'r':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_RR_ASC;
|
||||
break;
|
||||
case 'R':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_RR_DESC;
|
||||
break;
|
||||
default:
|
||||
zap_log(ZAP_LOG_WARNING, "Failed to determine huntgroup (%s)\n", gr);
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC;
|
||||
if (sangoma_boost_data->sigmod) {
|
||||
*zchan = span->channels[chan_id];
|
||||
|
||||
event.span = (uint8_t) (*zchan)->physical_span_id;
|
||||
event.chan = (uint8_t) (*zchan)->physical_chan_id;
|
||||
|
||||
zap_set_flag((*zchan), ZAP_CHANNEL_OUTBOUND);
|
||||
zap_set_flag_locked((*zchan), ZAP_CHANNEL_INUSE);
|
||||
|
||||
OUTBOUND_REQUESTS[r].zchan = *zchan;
|
||||
} else {
|
||||
if ((gr = strchr(ani, '@'))) {
|
||||
*gr++ = '\0';
|
||||
}
|
||||
|
||||
if (gr && *(gr+1)) {
|
||||
tg = atoi(gr+1);
|
||||
if (tg > 0) {
|
||||
tg--;
|
||||
}
|
||||
}
|
||||
event.trunk_group = tg;
|
||||
|
||||
if (check_congestion(tg)) {
|
||||
zap_log(ZAP_LOG_CRIT, "All circuits are busy. Trunk Group=%i (BOOST REQUESTED BACK OFF)\n",tg+1);
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
zap_span_channel_use_count(span, &count);
|
||||
|
||||
if (count >= span->chan_count) {
|
||||
zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n");
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
if (gr && *(gr+1)) {
|
||||
switch(*gr) {
|
||||
case 'g':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC;
|
||||
break;
|
||||
case 'G':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_SEQ_DESC;
|
||||
break;
|
||||
case 'r':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_RR_ASC;
|
||||
break;
|
||||
case 'R':
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_RR_DESC;
|
||||
break;
|
||||
default:
|
||||
zap_log(ZAP_LOG_WARNING, "Failed to determine huntgroup (%s)\n", gr);
|
||||
event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zap_set_string(event.calling_name, caller_data->cid_name);
|
||||
zap_set_string(event.isup_in_rdnis, caller_data->rdnis.digits);
|
||||
if (strlen(caller_data->rdnis.digits)) {
|
||||
event.isup_in_rdnis_size = (uint16_t)strlen(caller_data->rdnis.digits)+1;
|
||||
}
|
||||
if (strlen(caller_data->rdnis.digits)) {
|
||||
event.isup_in_rdnis_size = (uint16_t)strlen(caller_data->rdnis.digits)+1;
|
||||
}
|
||||
|
||||
event.calling_number_screening_ind = caller_data->screen;
|
||||
event.calling_number_presentation = caller_data->pres;
|
||||
if (sangoma_boost_data->sigmod) {
|
||||
/* boost sigmods only know about physical spans, give them that and let them hunt there */
|
||||
event.span = (uint8_t)span->channels[1]->physical_span_id;
|
||||
}
|
||||
|
||||
OUTBOUND_REQUESTS[r].status = BST_WAITING;
|
||||
OUTBOUND_REQUESTS[r].span = span;
|
||||
|
@ -380,7 +387,9 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) {
|
||||
zap_log(ZAP_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno));
|
||||
status = ZAP_FAIL;
|
||||
*zchan = NULL;
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
*zchan = NULL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -388,8 +397,11 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
zap_sleep(1);
|
||||
if (--boost_request_timeout <= 0) {
|
||||
status = ZAP_FAIL;
|
||||
*zchan = NULL;
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
*zchan = NULL;
|
||||
}
|
||||
zap_log(ZAP_LOG_CRIT, "Timed out waiting for boost channel request response, current status: BST_WAITING\n");
|
||||
zap_log(ZAP_LOG_CRIT, "DYDBG s%dc%d: Csid:%d Timed out waiting for boost channel request response, current status: BST_WAITING\n", (*zchan)->physical_span_id, (*zchan)->physical_chan_id, r);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +418,9 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
zap_sleep(1);
|
||||
if (--boost_request_timeout <= 0) {
|
||||
status = ZAP_FAIL;
|
||||
*zchan = NULL;
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
*zchan = NULL;
|
||||
}
|
||||
zap_log(ZAP_LOG_CRIT, "Timed out waiting for boost channel request response, current status: BST_ACK\n");
|
||||
goto done;
|
||||
}
|
||||
|
@ -420,7 +434,9 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
zap_log(ZAP_LOG_DEBUG, "Channel state changed to PROGRESS_MEDIA [Csid:%d]\n", r);
|
||||
} else {
|
||||
status = ZAP_FAIL;
|
||||
*zchan = NULL;
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
*zchan = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -433,12 +449,21 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
} else if (st != BST_READY) {
|
||||
assert(r <= MAX_REQ_ID);
|
||||
nack_map[r] = 1;
|
||||
sangomabc_exec_command(&sangoma_boost_data->mcon,
|
||||
0,
|
||||
0,
|
||||
r,
|
||||
SIGBOOST_EVENT_CALL_START_NACK,
|
||||
0);
|
||||
if (sangoma_boost_data->sigmod) {
|
||||
sangomabc_exec_command(&sangoma_boost_data->mcon,
|
||||
(*zchan)->physical_span_id,
|
||||
(*zchan)->physical_chan_id,
|
||||
r,
|
||||
SIGBOOST_EVENT_CALL_START_NACK,
|
||||
0);
|
||||
} else {
|
||||
sangomabc_exec_command(&sangoma_boost_data->mcon,
|
||||
0,
|
||||
0,
|
||||
r,
|
||||
SIGBOOST_EVENT_CALL_START_NACK,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -526,9 +551,11 @@ static void handle_call_progress(sangomabc_connection_t *mcon, sangomabc_short_e
|
|||
*/
|
||||
static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
|
||||
{
|
||||
|
||||
zap_channel_t *zchan;
|
||||
uint32_t event_span = event->span+1;
|
||||
uint32_t event_chan = event->chan+1;
|
||||
|
||||
if (nack_map[event->call_setup_id]) {
|
||||
return;
|
||||
}
|
||||
|
@ -541,12 +568,19 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_
|
|||
OUTBOUND_REQUESTS[event->call_setup_id].event = *event;
|
||||
SETUP_GRID[event->span][event->chan] = event->call_setup_id;
|
||||
|
||||
if ((zchan = find_zchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 0))) {
|
||||
if (mcon->sigmod) {
|
||||
zchan = OUTBOUND_REQUESTS[event->call_setup_id].zchan;
|
||||
zap_set_flag(zchan, ZAP_CHANNEL_OUTBOUND);
|
||||
zap_set_flag_locked(zchan, ZAP_CHANNEL_INUSE);
|
||||
} else {
|
||||
zchan = find_zchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 0);
|
||||
}
|
||||
|
||||
|
||||
if (zchan) {
|
||||
if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) {
|
||||
zap_log(ZAP_LOG_ERROR, "OPEN ERROR [%s]\n", zchan->last_error);
|
||||
} else {
|
||||
zap_set_flag(zchan, ZAP_CHANNEL_OUTBOUND);
|
||||
zap_set_flag_locked(zchan, ZAP_CHANNEL_INUSE);
|
||||
zchan->extra_id = event->call_setup_id;
|
||||
zap_log(ZAP_LOG_DEBUG, "Assign chan %d:%d (%d:%d) CSid=%d\n", zchan->span_id, zchan->chan_id, event_span, event_chan, event->call_setup_id);
|
||||
zchan->sflags = 0;
|
||||
|
@ -620,6 +654,7 @@ static void handle_call_done(zap_span_t *span, sangomabc_connection_t *mcon, san
|
|||
static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
|
||||
{
|
||||
zap_channel_t *zchan;
|
||||
zap_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
|
||||
|
||||
if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) {
|
||||
uint32_t count = 0;
|
||||
|
@ -648,8 +683,10 @@ static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mco
|
|||
event->release_cause = 17;
|
||||
}
|
||||
|
||||
if (event->call_setup_id) {
|
||||
|
||||
zap_log(ZAP_LOG_CRIT, "DYDBG setting event->call_setup_id:%d to BST_FAIL\n", event->call_setup_id);
|
||||
OUTBOUND_REQUESTS[event->call_setup_id].event = *event;
|
||||
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL;
|
||||
if (!sangoma_boost_data->sigmod) {
|
||||
sangomabc_exec_command(mcon,
|
||||
0,
|
||||
0,
|
||||
|
@ -657,8 +694,6 @@ static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mco
|
|||
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
||||
0);
|
||||
|
||||
OUTBOUND_REQUESTS[event->call_setup_id].event = *event;
|
||||
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL;
|
||||
return;
|
||||
} else {
|
||||
if ((zchan = find_zchan(span, event, 1))) {
|
||||
|
@ -677,6 +712,7 @@ static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mco
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (zchan) {
|
||||
zap_set_sflag_locked(zchan, SFLAG_SENT_FINAL_MSG);
|
||||
}
|
||||
|
@ -688,6 +724,7 @@ static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mco
|
|||
0,
|
||||
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
||||
0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1528,6 +1565,7 @@ end:
|
|||
*/
|
||||
static ZIO_SIG_LOAD_FUNCTION(zap_sangoma_boost_init)
|
||||
{
|
||||
int i;
|
||||
g_boost_modules_hash = create_hashtable(10, zap_hash_hashfromstring, zap_hash_equalkeys);
|
||||
if (!g_boost_modules_hash) {
|
||||
return ZAP_FAIL;
|
||||
|
@ -1535,6 +1573,10 @@ static ZIO_SIG_LOAD_FUNCTION(zap_sangoma_boost_init)
|
|||
zap_mutex_create(&request_mutex);
|
||||
zap_mutex_create(&signal_mutex);
|
||||
zap_mutex_create(&g_boost_modules_mutex);
|
||||
|
||||
for(i=0;i< MAX_TRUNK_GROUPS;i++) {
|
||||
g_trunkgroups[i]=NULL;
|
||||
}
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1806,7 +1848,6 @@ static ZIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(zap_sangoma_boost_configure_span)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!sigmod) {
|
||||
if (!local_ip && local_port && remote_ip && remote_port && sig_cb) {
|
||||
zap_set_string(span->last_error, "missing Sangoma boost IP parameters");
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "sangoma_boost_client.h"
|
||||
#include "openzap.h"
|
||||
|
||||
#define MAX_CHANS_PER_TRUNKGROUP 1024
|
||||
|
||||
typedef enum {
|
||||
ZAP_SANGOMA_BOOST_RUNNING = (1 << 0),
|
||||
ZAP_SANGOMA_BOOST_RESTARTING = (1 << 1)
|
||||
|
@ -50,9 +52,16 @@ typedef struct zap_sangoma_boost_data {
|
|||
zio_signal_cb_t signal_cb;
|
||||
uint32_t flags;
|
||||
boost_sigmod_interface_t *sigmod;
|
||||
zap_queue_t *boost_queue;
|
||||
zap_queue_t *boost_queue;
|
||||
} zap_sangoma_boost_data_t;
|
||||
|
||||
typedef struct zap_sangoma_boost_trunkgroup {
|
||||
zap_mutex_t *mutex;
|
||||
zap_size_t size; /* Number of b-channels in group */
|
||||
unsigned int last_used_index; /* index of last b-channel used */
|
||||
zap_channel_t* zchans[MAX_CHANS_PER_TRUNKGROUP];
|
||||
//DAVIDY need to merge congestion timeouts to this struct
|
||||
} zap_sangoma_boost_trunkgroup_t;
|
||||
#endif
|
||||
|
||||
/* For Emacs:
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
* Contributors:
|
||||
*
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -81,11 +82,15 @@ static struct {
|
|||
zap_hash_t *interface_hash;
|
||||
zap_hash_t *module_hash;
|
||||
zap_hash_t *span_hash;
|
||||
zap_hash_t *group_hash;
|
||||
zap_mutex_t *mutex;
|
||||
zap_mutex_t *span_mutex;
|
||||
zap_mutex_t *group_mutex;
|
||||
uint32_t span_index;
|
||||
uint32_t group_index;
|
||||
uint32_t running;
|
||||
zap_span_t *spans;
|
||||
zap_group_t *groups;
|
||||
} globals;
|
||||
|
||||
|
||||
|
@ -1008,6 +1013,113 @@ OZ_DECLARE(zap_status_t) zap_channel_set_state(zap_channel_t *zchan, zap_channel
|
|||
return ok ? ZAP_SUCCESS : ZAP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_group_channel_use_count(zap_group_t *group, uint32_t *count)
|
||||
{
|
||||
uint32_t j;
|
||||
|
||||
*count = 0;
|
||||
|
||||
if (!group) {
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
for(j = 0; j < group->chan_count && group->channels[j]; j++) {
|
||||
if (group->channels[j]) {
|
||||
if (zap_test_flag(group->channels[j], ZAP_CHANNEL_INUSE)) {
|
||||
(*count)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_by_group(uint32_t group_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan)
|
||||
{
|
||||
zap_status_t status = ZAP_FAIL;
|
||||
zap_channel_t *check;
|
||||
uint32_t i, count;
|
||||
zap_group_t *group = NULL;
|
||||
|
||||
if (group_id) {
|
||||
zap_group_find(group_id, &group);
|
||||
}
|
||||
|
||||
if (!group ) {
|
||||
zap_log(ZAP_LOG_CRIT, "GROUP NOT DEFINED!\n");
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
zap_group_channel_use_count(group, &count);
|
||||
|
||||
if (count >= group->chan_count) {
|
||||
zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n");
|
||||
*zchan = NULL;
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
if (direction == ZAP_TOP_DOWN) {
|
||||
i = 0;
|
||||
} else {
|
||||
i = group->chan_count-1;
|
||||
}
|
||||
|
||||
zap_mutex_lock(group->mutex);
|
||||
for (;;) {
|
||||
if (direction == ZAP_TOP_DOWN) {
|
||||
if (i >= group->chan_count) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (i < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(check = group->channels[i])) {
|
||||
status = ZAP_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (zap_test_flag(check, ZAP_CHANNEL_READY) &&
|
||||
!zap_test_flag(check, ZAP_CHANNEL_INUSE) &&
|
||||
!zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) &&
|
||||
check->state == ZAP_CHANNEL_STATE_DOWN &&
|
||||
check->type != ZAP_CHAN_TYPE_DQ921 &&
|
||||
check->type != ZAP_CHAN_TYPE_DQ931
|
||||
|
||||
) {
|
||||
zap_span_t* span = NULL;
|
||||
zap_span_find(check->span_id, &span);
|
||||
if (span && span->channel_request) {
|
||||
status = span->channel_request(span, check->physical_chan_id, direction, caller_data, zchan);
|
||||
break;
|
||||
}
|
||||
|
||||
status = check->zio->open(check);
|
||||
|
||||
if (status == ZAP_SUCCESS) {
|
||||
zap_set_flag(check, ZAP_CHANNEL_INUSE);
|
||||
zap_channel_open_chan(check);
|
||||
*zchan = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (direction == ZAP_TOP_DOWN) {
|
||||
i++;
|
||||
} else {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
zap_mutex_unlock(group->mutex);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_span_channel_use_count(zap_span_t *span, uint32_t *count)
|
||||
{
|
||||
uint32_t j;
|
||||
|
@ -1029,7 +1141,7 @@ OZ_DECLARE(zap_status_t) zap_span_channel_use_count(zap_span_t *span, uint32_t *
|
|||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan)
|
||||
OZ_DECLARE(zap_status_t) zap_channel_open_by_span(uint32_t span_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan)
|
||||
{
|
||||
zap_status_t status = ZAP_FAIL;
|
||||
zap_channel_t *check;
|
||||
|
@ -1172,7 +1284,6 @@ static zap_status_t zap_channel_reset(zap_channel_t *zchan)
|
|||
|
||||
OZ_DECLARE(zap_status_t) zap_channel_init(zap_channel_t *zchan)
|
||||
{
|
||||
|
||||
if (zchan->init_state != ZAP_CHANNEL_STATE_DOWN) {
|
||||
zap_set_state_locked(zchan, zchan->init_state);
|
||||
zchan->init_state = ZAP_CHANNEL_STATE_DOWN;
|
||||
|
@ -2438,6 +2549,7 @@ static zap_status_t load_config(void)
|
|||
unsigned configured = 0, d = 0;
|
||||
char name[80] = "";
|
||||
char number[25] = "";
|
||||
char group_name[80] = "default";
|
||||
zap_io_interface_t *zio = NULL;
|
||||
zap_analog_start_type_t tmp;
|
||||
|
||||
|
@ -2572,6 +2684,9 @@ static zap_status_t load_config(void)
|
|||
}
|
||||
} else if (!strcasecmp(var, "b-channel")) {
|
||||
configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_B, name, number);
|
||||
if (zap_group_add_channels(group_name, span, val) != ZAP_SUCCESS) {
|
||||
zap_log(ZAP_LOG_ERROR, "Failed to add channels (%d:%s) to group\n", number, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "d-channel")) {
|
||||
if (d) {
|
||||
zap_log(ZAP_LOG_WARNING, "ignoring extra d-channel\n");
|
||||
|
@ -2591,6 +2706,9 @@ static zap_status_t load_config(void)
|
|||
} else if (!strcasecmp(var, "dtmf_hangup")) {
|
||||
span->dtmf_hangup = zap_strdup(val);
|
||||
span->dtmf_hangup_len = strlen(val);
|
||||
} else if (!strcasecmp(var, "group")) {
|
||||
memset(group_name, 0, sizeof(group_name));
|
||||
memcpy(group_name, val, sizeof(group_name));
|
||||
} else {
|
||||
zap_log(ZAP_LOG_ERROR, "unknown span variable '%s'\n", var);
|
||||
}
|
||||
|
@ -2880,6 +2998,190 @@ OZ_DECLARE(zap_status_t) zap_span_start(zap_span_t *span)
|
|||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_channel_add_to_group(const char* name, zap_channel_t* zchan)
|
||||
{
|
||||
int i;
|
||||
zap_group_t* group = NULL;
|
||||
|
||||
zap_mutex_lock(globals.group_mutex);
|
||||
|
||||
if (zap_group_find_by_name(name, &group) != ZAP_SUCCESS) {
|
||||
zap_log(ZAP_LOG_DEBUG, "Creating new group:%s\n", name);
|
||||
zap_group_create(&group, name);
|
||||
}
|
||||
|
||||
/*verify that group does not already include this channel first */
|
||||
for(i=0; i < group->chan_count; i++) {
|
||||
if (group->channels[i]->physical_span_id == zchan->physical_span_id &&
|
||||
group->channels[i]->physical_chan_id == zchan->physical_chan_id) {
|
||||
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (group->chan_count >= ZAP_MAX_CHANNELS_GROUP) {
|
||||
zap_log(ZAP_LOG_CRIT, "Max number of channels exceeded (max:%d)\n", ZAP_MAX_CHANNELS_GROUP);
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
group->channels[group->chan_count++] = zchan;
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_channel_remove_from_group(zap_group_t* group, zap_channel_t* zchan)
|
||||
{
|
||||
//Need to test this function
|
||||
zap_mutex_lock(globals.group_mutex);
|
||||
int i, j;
|
||||
|
||||
for (i=0; i < group->chan_count; i++) {
|
||||
if (group->channels[i]->physical_span_id == zchan->physical_span_id &&
|
||||
group->channels[i]->physical_chan_id == zchan->physical_chan_id) {
|
||||
|
||||
j=i;
|
||||
while(j < group->chan_count-1) {
|
||||
group->channels[j] = group->channels[j+1];
|
||||
j++;
|
||||
}
|
||||
group->channels[group->chan_count--] = NULL;
|
||||
if (group->chan_count <=0) {
|
||||
/* Delete group if it is empty */
|
||||
hashtable_remove(globals.group_hash, (void *)group->name);
|
||||
}
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
//Group does not contain this channel
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_group_add_channels(const char* name, zap_span_t* span, const char* val)
|
||||
{
|
||||
char *p, *mydata, *item_list[10];
|
||||
int items, i;
|
||||
|
||||
assert(strlen(name) > 0);
|
||||
|
||||
p = strchr(val, ':');
|
||||
mydata = zap_strdup(++p);
|
||||
|
||||
assert(mydata != NULL);
|
||||
|
||||
items = zap_separate_string(mydata, ',', item_list, (sizeof(item_list) / sizeof(item_list[0])));
|
||||
|
||||
for(i=0; i < items; i++) {
|
||||
if (!strchr(item_list[i], '-')) {
|
||||
int chan_no;
|
||||
|
||||
chan_no = atoi (item_list[i]);
|
||||
assert(chan_no > 0);
|
||||
|
||||
if (zap_channel_add_to_group(name, span->channels[chan_no]) != ZAP_SUCCESS) {
|
||||
zap_log(ZAP_LOG_CRIT, "Failed to add chan:%d to group:%s\n", chan_no, name);
|
||||
}
|
||||
} else {
|
||||
int chan_no_start, chan_no_end;
|
||||
|
||||
if (sscanf(item_list[i], "%d-%d", &chan_no_start, &chan_no_end) == 2) {
|
||||
while (chan_no_start <= chan_no_end) {
|
||||
if (zap_channel_add_to_group(name, span->channels[chan_no_start++])) {
|
||||
zap_log(ZAP_LOG_CRIT, "Failed to add chan:%d to group:%s\n", chan_no_start-1, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_group_find(uint32_t id, zap_group_t **group)
|
||||
{
|
||||
zap_group_t *fgroup = NULL, *grp;
|
||||
|
||||
if (id > ZAP_MAX_GROUPS_INTERFACE) {
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
zap_mutex_lock(globals.group_mutex);
|
||||
for (grp = globals.groups; grp; grp = grp->next) {
|
||||
if (grp->group_id == id) {
|
||||
fgroup = grp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
|
||||
if (!fgroup) {
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
*group = fgroup;
|
||||
|
||||
return ZAP_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_group_find_by_name(const char *name, zap_group_t **group)
|
||||
{
|
||||
zap_status_t status = ZAP_FAIL;
|
||||
|
||||
zap_mutex_lock(globals.group_mutex);
|
||||
if (!zap_strlen_zero(name)) {
|
||||
if ((*group = hashtable_search(globals.group_hash, (void *) name))) {
|
||||
status = ZAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void zap_group_add(zap_group_t *group)
|
||||
{
|
||||
zap_group_t *grp;
|
||||
zap_mutex_lock(globals.group_mutex);
|
||||
|
||||
for (grp = globals.groups; grp && grp->next; grp = grp->next);
|
||||
|
||||
if (grp) {
|
||||
grp->next = group;
|
||||
} else {
|
||||
globals.groups = group;
|
||||
}
|
||||
hashtable_insert(globals.group_hash, (void *)group->name, group, HASHTABLE_FLAG_NONE);
|
||||
|
||||
zap_mutex_unlock(globals.group_mutex);
|
||||
}
|
||||
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_group_create(zap_group_t **group, const char *name)
|
||||
{
|
||||
zap_group_t *new_group = NULL;
|
||||
zap_status_t status = ZAP_FAIL;
|
||||
|
||||
zap_mutex_lock(globals.mutex);
|
||||
if (globals.group_index < ZAP_MAX_GROUPS_INTERFACE) {
|
||||
new_group = zap_malloc(sizeof(*new_group));
|
||||
assert(new_group);
|
||||
memset(new_group, 0, sizeof(*new_group));
|
||||
status = zap_mutex_create(&new_group->mutex);
|
||||
assert(status == ZAP_SUCCESS);
|
||||
|
||||
new_group->group_id = ++globals.group_index;
|
||||
new_group->name = zap_strdup(name);
|
||||
zap_group_add(new_group);
|
||||
*group = new_group;
|
||||
status = ZAP_SUCCESS;
|
||||
}
|
||||
zap_mutex_unlock(globals.mutex);
|
||||
return status;
|
||||
}
|
||||
|
||||
OZ_DECLARE(zap_status_t) zap_global_init(void)
|
||||
{
|
||||
|
@ -2893,8 +3195,10 @@ OZ_DECLARE(zap_status_t) zap_global_init(void)
|
|||
globals.interface_hash = create_hashtable(16, zap_hash_hashfromstring, zap_hash_equalkeys);
|
||||
globals.module_hash = create_hashtable(16, zap_hash_hashfromstring, zap_hash_equalkeys);
|
||||
globals.span_hash = create_hashtable(16, zap_hash_hashfromstring, zap_hash_equalkeys);
|
||||
globals.group_hash = create_hashtable(16, zap_hash_hashfromstring, zap_hash_equalkeys);
|
||||
zap_mutex_create(&globals.mutex);
|
||||
zap_mutex_create(&globals.span_mutex);
|
||||
zap_mutex_create(&globals.group_mutex);
|
||||
globals.running = 1;
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue