Merge branch 'master' into netborder

Conflicts:
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
This commit is contained in:
David Yat Sin 2010-12-20 17:08:15 -05:00
commit c2d7957142
7 changed files with 478 additions and 57 deletions

View File

@ -3543,7 +3543,83 @@ SWITCH_STANDARD_API(ft_function)
goto end;
}
if (!strcasecmp(argv[0], "dump")) {
if (!strcasecmp(argv[0], "sigstatus")) {
ftdm_span_t *span = NULL;
ftdm_signaling_status_t sigstatus;
if (argc < 3) {
stream->write_function(stream, "-ERR Usage: ftdm sigstatus get|set [<span_id>] [<channel>] [<sigstatus>]\n");
goto end;
}
if (!strcasecmp(argv[1], "get") && argc < 3) {
stream->write_function(stream, "-ERR sigstatus get usage: get <span_id>\n");
goto end;
}
if (!strcasecmp(argv[1], "set") && argc != 5) {
stream->write_function(stream, "-ERR sigstatus set usage: set <span_id> <channel>|all <sigstatus>\n");
goto end;
}
ftdm_span_find_by_name(argv[2], &span);
if (!span) {
stream->write_function(stream, "-ERR invalid span\n");
goto end;
}
if (!strcasecmp(argv[1], "get")) {
if (argc == 4) {
uint32_t chan_id = atol(argv[3]);
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
if (!fchan) {
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
goto end;
}
if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) {
stream->write_function(stream, "channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus));
} else {
stream->write_function(stream, "-ERR failed to get channel sigstatus\n");
}
goto end;
} else {
if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) {
stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus));
} else {
stream->write_function(stream, "-ERR failed to read span status: %s\n", ftdm_span_get_last_error(span));
}
}
goto end;
}
if (!strcasecmp(argv[1], "set")) {
sigstatus = ftdm_str2ftdm_signaling_status(argv[4]);
if (!strcasecmp(argv[3], "all")) {
if ((FTDM_SUCCESS == ftdm_span_set_sig_status(span, sigstatus))) {
stream->write_function(stream, "Signaling status of all channels from span %s set to %s\n",
ftdm_span_get_name(span), ftdm_signaling_status2str(sigstatus));
} else {
stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
}
goto end;
} else {
uint32_t chan_id = atol(argv[3]);
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
if (!fchan) {
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
goto end;
}
if ((FTDM_SUCCESS == ftdm_channel_set_sig_status(fchan, sigstatus))) {
stream->write_function(stream, "Signaling status of channel %d set to %s\n", chan_id,
ftdm_signaling_status2str(sigstatus));
} else {
stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
}
goto end;
}
}
} else if (!strcasecmp(argv[0], "dump")) {
if (argc < 2) {
stream->write_function(stream, "-ERR Usage: ftdm dump <span_id> [<chan_id>]\n");
goto end;

View File

@ -55,10 +55,13 @@ static int32_t g_thread_count = 0;
typedef int openr2_call_status_t;
/* when the users kills a span we clear this flag to kill the signaling thread */
/* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread
* knows it must stop, and we wait for FTDM_R2_RUNNING to be clear, which tells us the
* signaling thread is done. */
/* FIXME: what about the calls that are already up-and-running? */
typedef enum {
FTDM_R2_RUNNING = (1 << 0),
FTDM_R2_SPAN_STARTED = (1 << 1),
} ftdm_r2_flag_t;
/* private call information stored in ftdmchan->call_data void* ptr,
@ -424,13 +427,14 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
static ftdm_status_t ftdm_r2_start(ftdm_span_t *span)
{
ftdm_r2_data_t *r2_data = span->signal_data;
ftdm_set_flag(r2_data, FTDM_R2_RUNNING);
ftdm_set_flag(r2_data, FTDM_R2_SPAN_STARTED);
return ftdm_thread_create_detached(ftdm_r2_run, span);
}
static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span)
{
ftdm_r2_data_t *r2_data = span->signal_data;
ftdm_clear_flag(r2_data, FTDM_R2_SPAN_STARTED);
while (ftdm_test_flag(r2_data, FTDM_R2_RUNNING)) {
ftdm_log(FTDM_LOG_DEBUG, "Waiting for R2 span %s\n", span->name);
ftdm_sleep(100);
@ -461,12 +465,74 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status)
openr2_chan_set_idle(r2chan);
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%s'\n", status);
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status);
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status)
{
ftdm_iterator_t *citer = NULL;
ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL);
if (!chaniter) {
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
return FTDM_FAIL;
}
/* if ALL channels are non-idle, report SUSPENDED. UP otherwise. */
*status = FTDM_SIG_STATE_SUSPENDED;
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) {
*status = FTDM_SIG_STATE_UP;
break;
}
}
ftdm_iterator_free(chaniter);
return FTDM_SUCCESS;
}
static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status)
{
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *citer = NULL;
uint32_t span_opr = -1;
/* we either set the channels to BLOCK or IDLE */
switch(status) {
case FTDM_SIG_STATE_DOWN:
case FTDM_SIG_STATE_SUSPENDED:
span_opr = 0;
break;
case FTDM_SIG_STATE_UP:
span_opr = 1;
break;
default:
ftdm_log(FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status);
return FTDM_FAIL;
}
chaniter = ftdm_span_get_chan_iterator(span, NULL);
if (!chaniter) {
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
return FTDM_FAIL;
}
/* iterate over all channels, setting them to the requested state */
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
openr2_chan_t *r2chan = R2CALL(fchan)->r2chan;
if (span_opr == 0) {
openr2_chan_set_blocked(r2chan);
ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel blocked\n");
} else {
openr2_chan_set_idle(r2chan);
ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel idle\n");
}
}
ftdm_iterator_free(chaniter);
return FTDM_SUCCESS;
}
/* always called from the monitor thread */
static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
{
@ -1441,6 +1507,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
span->signal_type = FTDM_SIGTYPE_R2;
span->signal_data = r2data;
span->outgoing_call = r2_outgoing_call;
span->get_span_sig_status = ftdm_r2_get_span_sig_status;
span->set_span_sig_status = ftdm_r2_set_span_sig_status;
span->get_channel_sig_status = ftdm_r2_get_channel_sig_status;
span->set_channel_sig_status = ftdm_r2_set_channel_sig_status;
@ -1690,6 +1758,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
uint32_t txqueue_size = 4;
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
/* as long as this thread is running, this flag is set */
ftdm_set_flag(r2data, FTDM_R2_RUNNING);
#ifdef __linux__
r2data->monitor_thread_id = syscall(SYS_gettid);
#endif
@ -1712,7 +1783,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
memset(&start, 0, sizeof(start));
memset(&end, 0, sizeof(end));
while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) {
while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_SPAN_STARTED)) {
res = gettimeofday(&end, NULL);
if (res) {
ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno));

View File

@ -167,6 +167,7 @@ typedef struct sngisdn_chan_data {
uint32_t flags;
uint8_t ces; /* used only for BRI, otherwise always 0 */
uint8_t dchan_id;
uint16_t call_ref; /* Q.931 call reference, only valid for ETSI/INSNET/QSIG */
uint32_t suInstId; /* instance ID generated locally */
uint32_t spInstId; /* instance ID generated by stack */
@ -380,6 +381,9 @@ void sngisdn_rcv_cc_ind(CcMngmt *status);
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
void sngisdn_rcv_sng_assert(char *message);
#ifdef NETBORDER_CALL_REF
ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef);
#endif
ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);

View File

@ -71,13 +71,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
sngisdn_info->glare.spInstId = spInstId;
sngisdn_info->glare.dChan = dChan;
sngisdn_info->glare.ces = ces;
sngisdn_info->glare.ces = ces;
break;
}
sngisdn_info->suInstId = get_unique_suInstId(suId);
sngisdn_info->spInstId = spInstId;
if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) {
uint8_t local_number_matched = 0;
@ -125,6 +124,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
}
/* Fill in call information */
#ifdef NETBORDER_CALL_REF
get_callref(ftdmchan, &conEvnt->callRef);
#endif
get_calling_num(ftdmchan, &conEvnt->cgPtyNmb);
get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2);
get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
@ -282,6 +284,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_DIALING:
get_callref(ftdmchan, &cnStEvnt->callRef);
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
@ -354,6 +357,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
case MI_CALLPROC:
case MI_PROGRESS:
case MI_ALERTING:
get_callref(ftdmchan, &cnStEvnt->callRef);
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);

View File

@ -161,6 +161,32 @@ ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t ava
return FTDM_SUCCESS;
}
#ifdef NETBORDER_CALL_REF
ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
if (signal_data->raw_trace_q931) {
if (callRef->eh.pres != PRSNT_NODEF || callRef->reference.pres != PRSNT_NODEF) {
/* Netborder only supports BRI, so we only care for BRI for now */
if (FTDM_SPAN_IS_BRI(ftdmchan->span) && !sngisdn_info->call_ref) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to obtain call reference\n");
}
return FTDM_FAIL;
}
if (FTDM_SPAN_IS_BRI(ftdmchan->span)) {
sngisdn_info->call_ref = 0x7F & callRef->reference.val;
} else {
sngisdn_info->call_ref = 0x7FFF & callRef->reference.val;
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call reference:%04x\n", sngisdn_info->call_ref);
}
return FTDM_SUCCESS;
}
#endif
ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
{
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;

View File

@ -38,14 +38,26 @@
#define OCTET(x) (ieData[x-1] & 0xFF)
#define MAX_DECODE_STR_LEN 2000
typedef struct sngisdn_trace_info
{
uint8_t call_ref_flag;
uint16_t call_ref;
uint8_t msgtype;
uint8_t bchan_no;
ftdm_trace_dir_t dir;
} sngisdn_frame_info_t;
void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end);
uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start);
static ftdm_status_t sngisdn_map_call(sngisdn_span_data_t *signal_data, sngisdn_frame_info_t frame_info, ftdm_channel_t **found);
static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *frame_info);
uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi);
char* get_code_2_str(int code, struct code2str *pCodeTable);
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len);
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len);
char* get_code_2_str(int code, struct code2str *pCodeTable)
{
struct code2str* pCode2txt;
@ -121,9 +133,6 @@ void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d
sigev.ev_data.trace.dir = dir;
sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q921;
/* TODO: Map trace to call ID here */
sigev.call_id = 0;
raw_data = ftdm_malloc(data_len);
ftdm_assert(raw_data, "Failed to malloc");
@ -218,26 +227,33 @@ void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d
{
uint8_t *raw_data;
ftdm_sigmsg_t sigev;
ftdm_channel_t *ftdmchan;
sngisdn_frame_info_t frame_info;
memset(&sigev, 0, sizeof(sigev));
sigev.span_id = signal_data->ftdm_span->span_id;
sigev.chan_id = signal_data->dchan->chan_id;
sigev.channel = signal_data->dchan;
sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
/* Note: Mapped raw trace assume only exclusive b-channel selection is used. i.e the b-channel selected on outgoing SETUP is always used for the call */
if (sngisdn_get_frame_info(data, data_len, dir, &frame_info) == FTDM_SUCCESS) {
if (sngisdn_map_call(signal_data, frame_info, &ftdmchan) == FTDM_SUCCESS) {
sigev.call_id = ftdmchan->caller_data.call_id;
sigev.span_id = ftdmchan->physical_span_id;
sigev.chan_id = ftdmchan->physical_chan_id;
sigev.channel = ftdmchan;
}
sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
sigev.ev_data.trace.dir = dir;
sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q931;
/* TODO: Map trace to call ID here */
raw_data = ftdm_malloc(data_len);
ftdm_assert(raw_data, "Failed to malloc");
memcpy(raw_data, data, data_len);
sigev.raw_data = raw_data;
sigev.raw_data_len = data_len;
ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
sigev.ev_data.trace.dir = dir;
sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q931;
raw_data = ftdm_malloc(data_len);
ftdm_assert(raw_data, "Failed to malloc");
memcpy(raw_data, data, data_len);
sigev.raw_data = raw_data;
sigev.raw_data_len = data_len;
ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
}
}
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len)
@ -253,9 +269,6 @@ void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len)
prot_disc = (uint8_t)data[0];
str_len += sprintf(&str[str_len], " Prot Disc:%s (0x%02x)\n", get_code_2_str(prot_disc, dcodQ931ProtDiscTable), prot_disc);
/* Decode Call Reference */
lenCallRef = (uint8_t) (data[1] & 0x0F);
@ -747,4 +760,203 @@ void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_
return;
}
static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *target)
{
uint8_t pos = 0;
uint8_t flag;
uint16_t ref = 0;
uint8_t ref_len = 0;
uint8_t bchan_no = 0;
uint8_t msgtype;
/* First octet is protocol discriminator */
pos++;
/* Second octet contains length of call reference */
ref_len = data[pos++] & 0x0F;
/* third octet is call reference */
flag = (data[pos] & 0x80) >> 7;
if (ref_len == 2) {
ref = (data[pos++] & 0x7F) << 8;
ref |= (data[pos++] & 0xFF) ;
} else {
ref = (data[pos++] & 0x7F);
}
/* Next octet is the message type */
msgtype = data[pos++] & 0x7F;
/*
ftdm_log(FTDM_LOG_DEBUG, "Raw frame:call_ref:0x%04x flag:%d msgtype:%d\n", ref, flag, msgtype);
*/
if (!ref) {
/* This is not a call specific message (RESTART for example and we do not care about it) */
return FTDM_FAIL;
}
/* Look for the b-channel */
if (msgtype == PROT_Q931_MSGTYPE_SETUP) {
/* Try to find the b-channel no*/
for(; pos < data_len; pos++) {
uint8_t ie_id = data[pos];
uint8_t ie_len = data[pos+1];
switch(ie_id) {
case PROT_Q931_IE_SENDING_COMPLETE:
/* Single octet ie's do not have a length */
ie_len = 0;
break;
case PROT_Q931_IE_CHANNEL_ID:
{
/* Try to obtain the b-channel */
uint8_t ie_pos = pos+2;
//ifaceIdPresent = get_bits(OCTET(3),7,7);
if (data[ie_pos] & 0x20) {
/* Interface type is Primary Rate */
ie_pos+=2;
bchan_no = data[ie_pos] & 0x7F;
} else {
/* Interface type is Basic Interface */
/* Get the channel number from info channel selection */
bchan_no = data[ie_pos] & 0x03;
}
ftdm_log(FTDM_LOG_DEBUG, "Found b-channel:%d\n", bchan_no);
goto parse_ies_done;
}
break;
default:
pos = pos+ie_len+1;
}
//ftdm_log(FTDM_LOG_DEBUG, "Decoded IE:%s\n", get_code_2_str(ie_id, dcodQ931IEIDTable));
}
if (!bchan_no) {
char tmp[1000];
print_hex_dump(tmp, 0, data, 0, data_len);
ftdm_log(FTDM_LOG_WARNING, "Failed to determine b-channel on SETUP message\n%s\n", tmp);
}
}
parse_ies_done:
target->call_ref = ref;
target->call_ref_flag = flag;
target->msgtype = msgtype;
target->bchan_no = bchan_no;
target->dir = dir;
return FTDM_SUCCESS;
}
static ftdm_status_t sngisdn_map_call(sngisdn_span_data_t *signal_data, sngisdn_frame_info_t frame_info, ftdm_channel_t **found)
{
ftdm_channel_t *ftdmchan;
sngisdn_chan_data_t *sngisdn_info;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_status_t status = FTDM_FAIL;
uint8_t outbound_call = 0;
if ((!frame_info.call_ref_flag && frame_info.dir == FTDM_TRACE_DIR_OUTGOING) ||
(frame_info.call_ref_flag && frame_info.dir == FTDM_TRACE_DIR_INCOMING)) {
/* If this is an outgoing frame and this frame was sent by the originating side
of the call (frame_info.call_ref_flag == 0), then this is an outbound call */
outbound_call = 1;
} else {
outbound_call = 0;
}
switch (frame_info.msgtype) {
case PROT_Q931_MSGTYPE_SETUP:
/* We initiated this outgoing call try to match the call reference with our internal call-id*/
if (!frame_info.bchan_no) {
/* We were not able to determine the bchannel on this call, so we will not be able to match it anyway */
status = FTDM_FAIL;
}
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdmchan = (ftdm_channel_t*)(ftdm_iterator_current(curr));
ftdm_channel_lock(ftdmchan);
if (outbound_call) {
sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
if (sngisdn_info && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
if (ftdmchan->caller_data.call_id && ftdmchan->physical_chan_id == frame_info.bchan_no) {
sngisdn_info->call_ref = frame_info.call_ref;
*found = ftdmchan;
status = FTDM_SUCCESS;
}
}
} else {
if (ftdmchan->physical_chan_id == frame_info.bchan_no) {
*found = ftdmchan;
status = FTDM_SUCCESS;
}
}
ftdm_channel_unlock(ftdmchan);
}
ftdm_iterator_free(chaniter);
break;
case PROT_Q931_MSGTYPE_ALERTING:
case PROT_Q931_MSGTYPE_PROCEEDING:
case PROT_Q931_MSGTYPE_PROGRESS:
case PROT_Q931_MSGTYPE_CONNECT:
case PROT_Q931_MSGTYPE_SETUP_ACK:
case PROT_Q931_MSGTYPE_CONNECT_ACK:
case PROT_Q931_MSGTYPE_USER_INFO:
case PROT_Q931_MSGTYPE_DISCONNECT:
case PROT_Q931_MSGTYPE_RELEASE:
case PROT_Q931_MSGTYPE_RELEASE_ACK:
case PROT_Q931_MSGTYPE_RELEASE_COMPLETE:
case PROT_Q931_MSGTYPE_FACILITY:
case PROT_Q931_MSGTYPE_NOTIFY:
case PROT_Q931_MSGTYPE_STATUS_ENQUIRY:
case PROT_Q931_MSGTYPE_INFORMATION:
case PROT_Q931_MSGTYPE_STATUS:
/* Look for an outbound call on that span and and try to match the call-id */
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdmchan = (ftdm_channel_t*)(ftdm_iterator_current(curr));
ftdm_channel_lock(ftdmchan);
sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
if (outbound_call) {
if (sngisdn_info && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
if (sngisdn_info->call_ref == frame_info.call_ref) {
*found = ftdmchan;
status = FTDM_SUCCESS;
}
}
} else {
if (sngisdn_info && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
if (sngisdn_info->call_ref && sngisdn_info->call_ref == frame_info.call_ref) {
*found = ftdmchan;
status = FTDM_SUCCESS;
}
}
}
ftdm_channel_unlock(ftdmchan);
}
ftdm_iterator_free(chaniter);
break;
default:
/* This frame is not call specific, ignore */
break;
}
if (status == FTDM_SUCCESS) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Mapped %s with Call Ref:%04x to call-id:%d\n", get_code_2_str(frame_info.msgtype, dcodQ931MsgTypeTable), frame_info.call_ref, (*found)->caller_data.call_id);
} else {
/* We could not map this frame to a call-id */
ftdm_log(FTDM_LOG_DEBUG, "Failed to map %s with Call Ref:%04x to local call\n",
get_code_2_str(frame_info.msgtype, dcodQ931MsgTypeTable), frame_info.call_ref);
}
return status;
}

View File

@ -191,37 +191,65 @@ struct code2str dcodQ931CallRefLoTable[] = {
{13, "D"},
{14, "E"},
{15, "F"},
{-1,"?"},
{-1, "?"},
};
#define PROT_Q931_MSGTYPE_ALERTING 1
#define PROT_Q931_MSGTYPE_PROCEEDING 2
#define PROT_Q931_MSGTYPE_PROGRESS 3
#define PROT_Q931_MSGTYPE_SETUP 5
#define PROT_Q931_MSGTYPE_CONNECT 7
#define PROT_Q931_MSGTYPE_SETUP_ACK 13
#define PROT_Q931_MSGTYPE_CONNECT_ACK 15
#define PROT_Q931_MSGTYPE_USER_INFO 32
#define PROT_Q931_MSGTYPE_SUSPEND_REJ 33
#define PROT_Q931_MSGTYPE_RESUME_REJ 34
#define PROT_Q931_MSGTYPE_SUSPEND 37
#define PROT_Q931_MSGTYPE_RESUME 38
#define PROT_Q931_MSGTYPE_SUSPEND_ACK 45
#define PROT_Q931_MSGTYPE_RESUME_ACK 46
#define PROT_Q931_MSGTYPE_DISCONNECT 69
#define PROT_Q931_MSGTYPE_RESTART 70
#define PROT_Q931_MSGTYPE_RELEASE 77
#define PROT_Q931_MSGTYPE_RELEASE_ACK 78
#define PROT_Q931_MSGTYPE_RELEASE_COMPLETE 90
#define PROT_Q931_MSGTYPE_SEGMENT 96
#define PROT_Q931_MSGTYPE_FACILITY 98
#define PROT_Q931_MSGTYPE_NOTIFY 110
#define PROT_Q931_MSGTYPE_STATUS_ENQUIRY 117
#define PROT_Q931_MSGTYPE_CONGESTION_CNTRL 121
#define PROT_Q931_MSGTYPE_INFORMATION 123
#define PROT_Q931_MSGTYPE_STATUS 125
struct code2str dcodQ931MsgTypeTable[] = {
{1, "Alerting"},
{2, "Call Proceeding"},
{3, "Progress"},
{5, "Setup"},
{7, "Connect"},
{13, "Setup Ack"},
{15, "Connect Ack"},
{32, "User Info"},
{33, "Suspend Rej"},
{34, "Resume Rej"},
{37, "Suspend"},
{38, "Resume"},
{45, "Suspend Ack"},
{46, "Resume Ack"},
{69, "Disconnect"},
{70, "Restart"},
{77, "Release"},
{78, "Release Ack"},
{90, "Release Compl"},
{96, "Segment"},
{98, "Facility"},
{110, "Notify"},
{117, "Status Enquiry"},
{121, "Congest Cntrl"},
{123, "Information"},
{125, "Status"},
{-1, "Unknown"},
{PROT_Q931_MSGTYPE_ALERTING, "ALERT"},
{PROT_Q931_MSGTYPE_PROCEEDING, "PROCEED"},
{PROT_Q931_MSGTYPE_PROGRESS, "PROGRESS"},
{PROT_Q931_MSGTYPE_SETUP, "SETUP"},
{PROT_Q931_MSGTYPE_CONNECT, "CONNECT"},
{PROT_Q931_MSGTYPE_SETUP_ACK, "SETUP ACK"},
{PROT_Q931_MSGTYPE_CONNECT_ACK, "CONNECT ACK"},
{PROT_Q931_MSGTYPE_USER_INFO, "USER INFO"},
{PROT_Q931_MSGTYPE_SUSPEND_REJ, "SUSPEND REJ"},
{PROT_Q931_MSGTYPE_RESUME_REJ, "RESUME REJ"},
{PROT_Q931_MSGTYPE_SUSPEND, "SUSPEND"},
{PROT_Q931_MSGTYPE_RESUME, "RESUME"},
{PROT_Q931_MSGTYPE_SUSPEND_ACK, "SUSPEND ACK"},
{PROT_Q931_MSGTYPE_RESUME_ACK, "RESUME ACK"},
{PROT_Q931_MSGTYPE_DISCONNECT, "DISCONNECT"},
{PROT_Q931_MSGTYPE_RESTART, "RESTART"},
{PROT_Q931_MSGTYPE_RELEASE, "RELEASE"},
{PROT_Q931_MSGTYPE_RELEASE_ACK, "RELEASR ACK"},
{PROT_Q931_MSGTYPE_RELEASE_COMPLETE, "RELEASE COMPLETE"},
{PROT_Q931_MSGTYPE_SEGMENT, "SEGMENT"},
{PROT_Q931_MSGTYPE_FACILITY, "FACILITY"},
{PROT_Q931_MSGTYPE_NOTIFY, "NOTIFY"},
{PROT_Q931_MSGTYPE_STATUS_ENQUIRY, "STATUS ENQ"},
{PROT_Q931_MSGTYPE_CONGESTION_CNTRL, "CONGESTION CTRL"},
{PROT_Q931_MSGTYPE_INFORMATION, "INFO"},
{PROT_Q931_MSGTYPE_STATUS, "STATUS"},
{-1, "UNKNOWN"},
};
struct code2str dcodQ931CauseCodeTable[] = {