git-svn-id: http://svn.openzap.org/svn/openzap/branches/sangoma_boost@1040 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Moises Silva 2010-02-25 23:36:18 +00:00
parent 165bb80072
commit 5df64c1d38
6 changed files with 151 additions and 36 deletions

View File

@ -675,7 +675,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
tech_pvt->read_frame.samples /= 2;
}
if (ftdm_channel_dequeue_dtmf(tech_pvt->ftdmchan, dtmf, sizeof(dtmf))) {
while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdmchan, dtmf, sizeof(dtmf))) {
switch_dtmf_t _dtmf = { 0, SWITCH_DEFAULT_DTMF_DURATION };
char *p;
for (p = dtmf; p && *p; p++) {
@ -737,10 +737,11 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
wflags = FTDM_WRITE;
status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, tech_pvt->ftdmchan->effective_interval * 4);
status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, tech_pvt->ftdmchan->effective_interval * 10);
if (!(wflags & FTDM_WRITE)) {
goto fail;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready)\n");
return SWITCH_STATUS_SUCCESS;
}
len = frame->datalen;

View File

@ -1322,9 +1322,7 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
ftdmchan->token_count = 0;
if (ftdmchan->dtmf_buffer) {
ftdm_buffer_zero(ftdmchan->dtmf_buffer);
}
ftdm_channel_flush_dtmf(ftdmchan);
if (ftdmchan->gen_dtmf_buffer) {
ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);

View File

@ -239,7 +239,6 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
{
ftdm_sigmsg_t sigev;
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
ftdm_log(FTDM_LOG_NOTICE, "Call offered on chan %d, ANI = %s, DNIS = %s, Category = %s\n", openr2_chan_get_number(r2chan),
ani, dnis, openr2_proto_get_category_string(category));
@ -910,7 +909,6 @@ static void *ftdm_r2_channel_run(ftdm_thread_t *me, void *obj)
ftdm_sigmsg_t sigev;
ftdm_channel_t *ftdmchan = (ftdm_channel_t *)obj;
openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INTHREAD);

View File

@ -111,7 +111,6 @@ static uint16_t SETUP_GRID[FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN+1][FTDM_MAX_
static sangoma_boost_request_t OUTBOUND_REQUESTS[MAX_REQ_ID+1] = {{ 0 }};
static ftdm_mutex_t *request_mutex = NULL;
static ftdm_mutex_t *signal_mutex = NULL;
static uint8_t req_map[MAX_REQ_ID+1] = { 0 };
static uint8_t nack_map[MAX_REQ_ID+1] = { 0 };
@ -219,7 +218,6 @@ static ftdm_channel_t *find_ftdmchan(ftdm_span_t *span, sangomabc_short_event_t
targetchan = event->chan;
}
ftdm_mutex_lock(signal_mutex);
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];
@ -237,7 +235,6 @@ static ftdm_channel_t *find_ftdmchan(ftdm_span_t *span, sangomabc_short_event_t
}
}
}
ftdm_mutex_unlock(signal_mutex);
return ftdmchan;
}
@ -273,7 +270,12 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
ftdm_status_t status = FTDM_FAIL;
sangoma_boost_request_id_t r;
sangomabc_event_t event = {0};
int boost_request_timeout = 5000;
/* sanity has to be more than 8 seconds.
* In PRI specs, timeout is 4 seconds for remote switch to respond to a SETUP,
* 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;
@ -864,18 +866,8 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
ftdm_channel_t *ftdmchan;
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) {
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) {
ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d AT ALL\n", event->span+1,event->chan+1);
goto error;
}
/* this handles race conditions where state handlers are still pending to be executed for finished calls
but an incoming call arrives first, we must complete the channel states and then try again to get the
ftdm channel */
advance_chan_states(ftdmchan);
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) {
ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d EVEN AFTER STATE ADVANCE\n", event->span+1,event->chan+1);
goto error;
}
ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d\n", event->span+1,event->chan+1);
goto error;
}
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
@ -931,6 +923,48 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
}
static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
{
ftdm_status_t res = FTDM_FAIL;
ftdm_channel_t *ftdmchan;
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) {
ftdm_log(FTDM_LOG_CRIT, "CANNOT START LOOP, CHAN NOT AVAILABLE %d:%d\n", event->span+1,event->chan+1);
return;
}
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "CANNOT START LOOP, CANT OPEN CHAN %d:%d\n", event->span+1,event->chan+1);
return;
}
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, 0, res);
if (res != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n");
ftdm_channel_done(ftdmchan);
return;
}
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL);
}
static void handle_call_loop_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
{
ftdm_channel_t *ftdmchan;
ftdm_status_t res = FTDM_FAIL;
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) {
ftdm_log(FTDM_LOG_CRIT, "CANNOT STOP LOOP, INVALID CHAN REQUESTED %d:%d\n", event->span+1,event->chan+1);
return;
}
if (ftdmchan->state != FTDM_CHANNEL_STATE_IN_LOOP) {
ftdm_log(FTDM_LOG_ERROR, "Got stop loop request in a channel that is not in loop, ignoring ...\n");
return;
}
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
/* even when we did not sent a msg we set this flag to avoid sending call stop in the DOWN state handler */
ftdm_set_flag(ftdmchan, SFLAG_SENT_FINAL_MSG);
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_DOWN, 0, res);
}
/**
* \brief Handler for heartbeat event
* \param mcon sangoma boost connection
@ -1015,6 +1049,53 @@ static void handle_incoming_digit(sangomabc_connection_t *mcon, ftdm_span_t *spa
return;
}
/**
* \brief Checks if span has state changes pending and processes
* \param span Span where event was fired
* \param event Event to handle
* \return The locked FTDM channel associated to the event if any, NULL otherwise
*/
static ftdm_channel_t* event_process_states(ftdm_span_t *span, sangomabc_short_event_t *event)
{
ftdm_channel_t *ftdmchan = NULL;
switch (event->event_id) {
case SIGBOOST_EVENT_CALL_START_NACK:
case SIGBOOST_EVENT_CALL_START_NACK_ACK:
if (event->call_setup_id) {
return NULL;
}
//if event->span and event->chan is valid, fall-through
case SIGBOOST_EVENT_CALL_START:
case SIGBOOST_EVENT_CALL_START_ACK:
case SIGBOOST_EVENT_CALL_STOPPED:
case SIGBOOST_EVENT_CALL_PROGRESS:
case SIGBOOST_EVENT_CALL_ANSWERED:
case SIGBOOST_EVENT_CALL_STOPPED_ACK:
case SIGBOOST_EVENT_DIGIT_IN:
case SIGBOOST_EVENT_INSERT_CHECK_LOOP:
case SIGBOOST_EVENT_REMOVE_CHECK_LOOP:
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) {
ftdm_log(FTDM_LOG_DEBUG, "PROCESS STATES CANT FIND CHAN %d:%d\n", event->span+1,event->chan+1);
return NULL;
}
break;
case SIGBOOST_EVENT_HEARTBEAT:
case SIGBOOST_EVENT_SYSTEM_RESTART_ACK:
case SIGBOOST_EVENT_SYSTEM_RESTART:
case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE:
return NULL;
default:
ftdm_log(FTDM_LOG_CRIT, "Unhandled event id:%d\n", event->event_id);
return NULL;
}
ftdm_mutex_lock(ftdmchan->mutex);
advance_chan_states(ftdmchan);
return ftdmchan;
}
/**
* \brief Handler for sangoma boost event
* \param span Span where event was fired
@ -1023,14 +1104,19 @@ static void handle_incoming_digit(sangomabc_connection_t *mcon, ftdm_span_t *spa
*/
static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
{
ftdm_mutex_lock(signal_mutex);
ftdm_channel_t* ftdmchan = NULL;
if (!ftdm_running()) {
ftdm_log(FTDM_LOG_WARNING, "System is shutting down.\n");
goto end;
return -1;
}
ftdm_assert_return(event->call_setup_id <= MAX_REQ_ID, -1, "Unexpected call setup id\n");
/* process all pending state changes for that channel before
* processing the new boost event */
ftdmchan = event_process_states(span, event);
switch(event->event_id) {
case SIGBOOST_EVENT_CALL_START:
handle_call_start(span, mcon, (sangomabc_event_t*)event);
@ -1064,10 +1150,10 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
nack_map[event->call_setup_id] = 0;
break;
case SIGBOOST_EVENT_INSERT_CHECK_LOOP:
//handle_call_loop_start(event);
handle_call_loop_start(span, mcon, event);
break;
case SIGBOOST_EVENT_REMOVE_CHECK_LOOP:
//handle_call_stop(event);
handle_call_loop_stop(span, mcon, event);
break;
case SIGBOOST_EVENT_SYSTEM_RESTART_ACK:
handle_restart_ack(mcon, span, event);
@ -1086,11 +1172,13 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
break;
}
end:
ftdm_mutex_unlock(signal_mutex);
if(ftdmchan != NULL) {
advance_chan_states(ftdmchan);
ftdm_mutex_unlock(ftdmchan->mutex);
}
return 0;
}
/**
@ -1290,6 +1378,11 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
status = ftdm_span_send_signal(ftdmchan->span, &sig);
}
break;
case FTDM_CHANNEL_STATE_IN_LOOP:
{
/* nothing to do, we sent the FTDM_COMMAND_ENABLE_LOOP command in handle_call_loop_start() right away */
}
break;
default:
break;
}
@ -1297,13 +1390,11 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan)
{
ftdm_mutex_lock(ftdmchan->mutex);
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
state_advance(ftdmchan);
ftdm_channel_complete_state(ftdmchan);
}
ftdm_mutex_unlock(ftdmchan->mutex);
}
/**
@ -1668,7 +1759,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_boost_init)
return FTDM_FAIL;
}
ftdm_mutex_create(&request_mutex);
ftdm_mutex_create(&signal_mutex);
ftdm_mutex_create(&g_boost_modules_mutex);
memset(&g_trunkgroups[0], 0, sizeof(g_trunkgroups));
return FTDM_SUCCESS;
@ -1693,7 +1783,6 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_boost_destroy)
hashtable_destroy(g_boost_modules_hash);
ftdm_mutex_destroy(&request_mutex);
ftdm_mutex_destroy(&signal_mutex);
ftdm_mutex_destroy(&g_boost_modules_mutex);
return FTDM_SUCCESS;
}
@ -1811,6 +1900,18 @@ static ftdm_state_map_t boost_state_map = {
{FTDM_CHANNEL_STATE_RESTART, FTDM_END},
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DOWN},
{FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_IN_LOOP},
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,

View File

@ -497,6 +497,10 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
wanpipe_tdm_api_t tdm_api;
memset(&tdm_api,0,sizeof(tdm_api));
sangoma_tdm_flush_bufs(ftdmchan->sockfd, &tdm_api);
#ifdef LIBSANGOMA_VERSION
sangoma_flush_event_bufs(ftdmchan->sockfd, &tdm_api);
#endif
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921 || ftdmchan->type == FTDM_CHAN_TYPE_DQ931) {
ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE;
@ -605,6 +609,14 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
//code me
}
break;
case FTDM_COMMAND_ENABLE_LOOP:
{
// code me
}
case FTDM_COMMAND_DISABLE_LOOP:
{
// code me
}
case FTDM_COMMAND_SET_INTERVAL:
{
err=sangoma_tdm_set_usr_period(ftdmchan->sockfd, &tdm_api, FTDM_COMMAND_OBJ_INT);
@ -1051,7 +1063,9 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
ftdm_channel_queue_dtmf(ftdmchan, tmp_dtmf);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
ftdm_channel_queue_dtmf(ftdmchan, tmp_dtmf);
}
}
}
break;

View File

@ -315,6 +315,8 @@ typedef enum {
FTDM_COMMAND_SET_PRE_BUFFER_SIZE,
FTDM_COMMAND_SET_LINK_STATUS,
FTDM_COMMAND_GET_LINK_STATUS,
FTDM_COMMAND_ENABLE_LOOP,
FTDM_COMMAND_DISABLE_LOOP,
FTDM_COMMAND_COUNT
} ftdm_command_t;
@ -374,6 +376,7 @@ typedef enum {
FTDM_CHANNEL_STATE_CANCEL,
FTDM_CHANNEL_STATE_HANGUP,
FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
FTDM_CHANNEL_STATE_IN_LOOP,
FTDM_CHANNEL_STATE_INVALID
} ftdm_channel_state_t;
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \