Support for early media

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@909 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
David Yat Sin 2009-11-27 16:53:16 +00:00
parent 3e7e7b6879
commit 7145817da4
3 changed files with 129 additions and 9 deletions

View File

@ -57,6 +57,7 @@ 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;
@ -217,6 +218,30 @@ static int check_congestion(int trunk_group)
return 0;
}
/**
* \brief determines whether media is ready
* \param event boost event
* \return 1 true, 0 for false
*/
static int boost_media_ready(sangomabc_event_t *event)
{
/* FORMAT is of type: SMG003-EVI-1-MEDIA-# */
char* p = NULL;
p = strstr(event->isup_in_rdnis, "MEDIA");
if (p) {
int media_ready = 0;
if ((sscanf(p, "MEDIA-%d", &media_ready)) == 1) {
if (media_ready) {
return 1;
} else {
}
} else {
zap_log(ZAP_LOG_ERROR, "Invalid boost isup_rdnis MEDIA format %s\n", p);
}
}
return 0;
}
/**
* \brief Requests an sangoma boost channel on a span (outgoing call)
@ -334,11 +359,30 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
}
//printf("WTF %d\n", sanity);
}
if (OUTBOUND_REQUESTS[r].status == BST_ACK && OUTBOUND_REQUESTS[r].zchan) {
*zchan = OUTBOUND_REQUESTS[r].zchan;
status = ZAP_SUCCESS;
(*zchan)->init_state = ZAP_CHANNEL_STATE_PROGRESS;
zap_log(ZAP_LOG_DEBUG, "Channel state changed to PROGRESS [Csid:%d]\n", r);
}
sanity = 5000;
while(zap_running() && OUTBOUND_REQUESTS[r].status == BST_ACK) {
zap_sleep(1);
if (--sanity <= 0) {
status = ZAP_FAIL;
*zchan = NULL;
goto done;
}
//printf("WTF %d\n", sanity);
}
if (OUTBOUND_REQUESTS[r].status == BST_READY && OUTBOUND_REQUESTS[r].zchan) {
*zchan = OUTBOUND_REQUESTS[r].zchan;
status = ZAP_SUCCESS;
(*zchan)->init_state = ZAP_CHANNEL_STATE_PROGRESS_MEDIA;
zap_log(ZAP_LOG_DEBUG, "Channel state changed to PROGRESS_MEDIA [Csid:%d]\n", r);
} else {
status = ZAP_FAIL;
*zchan = NULL;
@ -377,6 +421,66 @@ static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(sangoma_boost_outgoing_call)
return status;
}
/**
* \brief Handler for call start ack no media event
* \param mcon sangoma boost connection
* \param event Event to handle
*/
static void handle_call_progress(sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
{
zap_channel_t *zchan;
if (nack_map[event->call_setup_id]) {
return;
}
//if we received a progress for this device already
if (OUTBOUND_REQUESTS[event->call_setup_id].status == BST_ACK) {
if (boost_media_ready((sangomabc_event_t*) event)) {
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY;
zap_log(ZAP_LOG_DEBUG, "chan media ready %d:%d CSid:%d\n", event->span+1, event->chan+1, event->call_setup_id);
}
return;
}
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, (sangomabc_short_event_t*) event, 0))) {
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+1,event->chan+1, event->call_setup_id);
zchan->sflags = 0;
OUTBOUND_REQUESTS[event->call_setup_id].zchan = zchan;
if (boost_media_ready((sangomabc_event_t*)event)) {
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY;
} else {
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_ACK;
}
return;
}
}
//printf("WTF BAD ACK CSid=%d span=%d chan=%d\n", event->call_setup_id, event->span+1,event->chan+1);
if ((zchan = find_zchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 1))) {
//printf("WTF BAD ACK2 %d:%d (%d:%d) CSid=%d xtra_id=%d out=%d state=%s\n", zchan->span_id, zchan->chan_id, event->span+1,event->chan+1, event->call_setup_id, zchan->extra_id, zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND), zap_channel_state2str(zchan->state));
}
zap_log(ZAP_LOG_CRIT, "START PROGRESS CANT FIND A CHAN %d:%d\n", event->span+1,event->chan+1);
sangomabc_exec_command(mcon,
event->span,
event->chan,
event->call_setup_id,
SIGBOOST_EVENT_CALL_STOPPED,
ZAP_CAUSE_DESTINATION_OUT_OF_ORDER);
OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL;
}
/**
* \brief Handler for call start ack event
* \param mcon sangoma boost connection
@ -586,8 +690,8 @@ static void handle_call_stop(zap_span_t *span, sangomabc_connection_t *mcon, san
0,
SIGBOOST_EVENT_CALL_STOPPED_ACK,
0);
release_request_id_span_chan(event->span, event->chan);
release_request_id_span_chan(event->span, event->chan);
}
/**
@ -799,6 +903,9 @@ static int parse_sangoma_event(zap_span_t *span, sangomabc_connection_t *mcon, s
case SIGBOOST_EVENT_CALL_START_ACK:
handle_call_start_ack(mcon, event);
break;
case SIGBOOST_EVENT_CALL_PROGRESS:
handle_call_progress(mcon, event);
break;
case SIGBOOST_EVENT_CALL_START_NACK:
handle_call_start_nack(span, mcon, event);
break;

View File

@ -53,9 +53,10 @@ struct sangomabc_map {
};
static struct sangomabc_map sangomabc_table[] = {
{SIGBOOST_EVENT_CALL_START, "CALL_START"},
{SIGBOOST_EVENT_CALL_START, "CALL_START"},
{SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"},
{SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"},
{SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"},
{SIGBOOST_EVENT_CALL_PROGRESS, "CALL PROGRESS"},
{SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"},
{SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"},
{SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"},
@ -75,7 +76,7 @@ static void sangomabc_print_event_call(sangomabc_connection_t *mcon, sangomabc_e
{
if (event->event_id == SIGBOOST_EVENT_HEARTBEAT)
return;
zap_log(file, func, line, ZAP_LOG_LEVEL_WARNING, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s]\n",
zap_log(file, func, line, ZAP_LOG_LEVEL_WARNING, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s] Rdnis=[%s]\n",
dir ? "TX":"RX",
sangomabc_event_id_name(event->event_id),
event->event_id,
@ -85,8 +86,8 @@ static void sangomabc_print_event_call(sangomabc_connection_t *mcon, sangomabc_e
event->fseqno,
strlen(event->calling_name)?event->calling_name:"N/A",
(event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
(event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
);
(event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"),
event->isup_in_rdnis);
}
static void sangomabc_print_event_short(sangomabc_connection_t *mcon, sangomabc_short_event_t *event, int priority, int dir, const char *file, const char *func, int line)

View File

@ -30,6 +30,7 @@ enum e_sigboost_event_id_values
SIGBOOST_EVENT_CALL_STOPPED_ACK = 0x86, /*134*/
SIGBOOST_EVENT_SYSTEM_RESTART = 0x87, /*135*/
SIGBOOST_EVENT_SYSTEM_RESTART_ACK = 0x88, /*136*/
SIGBOOST_EVENT_CALL_PROGRESS = 0x50, /*decimal 80*/
/* Following IDs are ss7boost to sangoma_mgd only. */
SIGBOOST_EVENT_HEARTBEAT = 0x89, /*137*/
SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/
@ -68,13 +69,21 @@ enum e_sigboost_huntgroup_values
SIGBOOST_HUNTGRP_RR_DESC = 0x03, /* round-robin with highest available first */
};
enum e_sigboost_event_info_par_values
{
SIGBOOST_EVI_SPARE = 0x00,
SIGBOOST_EVI_ALERTING = 0x01,
SIGBOOST_EVI_PROGRESS = 0x02,
};
#define MAX_DIALED_DIGITS 31
/* Next two defines are used to create the range of values for call_setup_id
* in the t_sigboost structure.
* 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */
#define CORE_MAX_SPANS 200
#define CORE_MAX_CHAN_PER_SPAN 30
#define CORE_MAX_CHAN_PER_SPAN 32
#define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN
/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */
#define SIZE_RDNIS 900
@ -99,6 +108,7 @@ typedef struct
uint32_t trunk_group;
uint8_t span;
uint8_t chan;
/* struct timeval tv; */
uint8_t called_number_digits_count;
char called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
uint8_t calling_number_digits_count; /* it's an array */
@ -126,15 +136,18 @@ typedef struct
uint32_t trunk_group;
uint8_t span;
uint8_t chan;
/* struct timeval tv; */
uint8_t release_cause;
} t_sigboost_short;
#pragma pack()
static inline int boost_full_event(int event_id)
{
switch (event_id) {
case SIGBOOST_EVENT_CALL_START:
case SIGBOOST_EVENT_DIGIT_IN:
case SIGBOOST_EVENT_CALL_PROGRESS:
return 1;
default:
return 0;
@ -143,5 +156,4 @@ static inline int boost_full_event(int event_id)
return 0;
}
#endif