From 89351e02528f7048306923ae57566f62f6c9d3fb Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 15 Oct 2010 13:40:20 -0400 Subject: [PATCH 1/5] freetdm: ss7 - added support for sending sub-address values freetdm: ss7 - switch back to sending RSC at startup rather then GRS --- .../ftmod_sangoma_ss7_main.c | 2 +- .../ftmod_sangoma_ss7_main.h | 9 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 88 +++++++- .../ftmod_sangoma_ss7_support.c | 211 ++++++++++++++++++ 4 files changed, 306 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 30cb31691d..cff9711814 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1332,7 +1332,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); } -#if 1 +#if 0 /* throw the grp reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); if (x == 1) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index a358236ed0..5de237dcbf 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -58,6 +58,8 @@ #define SNGSS7_EVENT_QUEUE_SIZE 100 +#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */ + typedef enum { SNGSS7_CON_IND_EVENT = 0, SNGSS7_CON_CFM_EVENT, @@ -83,6 +85,11 @@ typedef enum { SNGSS7_PAUSED = (1 << 7) } sng_flag_t; +typedef enum { + SNG_CALLED = 1, + SNG_CALLING = 2 +} sng_addr_type_t; + typedef struct sng_mtp_link { char name[MAX_NAME_LEN]; uint32_t id; @@ -579,6 +586,8 @@ ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); +ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); +ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); /* in ftmod_sangoma_ss7_timers.c */ void handle_isup_t35(void *userdata); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 973fbf47c7..3571a9ef0a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -76,6 +76,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; const char *clg_nadi = NULL; const char *cld_nadi = NULL; + const char *clg_subAddr = NULL; + const char *cld_subAddr = NULL; + char subAddrIE[MAX_SIZEOF_SUBADDR_IE]; SiConEvnt iam; sngss7_info->suInstId = get_unique_id (); @@ -186,7 +189,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* check if the user would like a custom NADI value for the calling Pty Num */ clg_nadi = ftdm_channel_get_var(ftdmchan, "ss7_clg_nadi"); if ((clg_nadi != NULL) && (*clg_nadi)) { - SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", clg_nadi); + SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi); iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi); } else { iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].clg_nadi; @@ -195,14 +198,93 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) cld_nadi = ftdm_channel_get_var(ftdmchan, "ss7_cld_nadi"); if ((cld_nadi != NULL) && (*cld_nadi)) { - SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", cld_nadi); + SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi); iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi); } else { iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].cld_nadi; SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val); - } + /* check if the user would like us to send a clg_sub-address */ + clg_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_clg_subaddr"); + if ((clg_subAddr != NULL) && (*clg_subAddr)) { + SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr); + + /* clean out the subAddrIE */ + memset(subAddrIE, 0x0, sizeof(subAddrIE)); + + /* check the first character in the sub-address to see what type of encoding to use */ + switch (clg_subAddr[0]) { + case '0': /* NSAP */ + encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING); + break; + case '1': /* national variant */ + encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING); + break; + default: + SS7_ERROR_CHAN(ftdmchan,"Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]); + break; + } /* switch (cld_subAddr[0]) */ + + + /* if subaddIE is still empty don't copy it in */ + if (subAddrIE[0] != '0') { + /* check if the clg_subAddr has already been added */ + if (iam.accTrnspt.eh.pres == PRSNT_NODEF) { + /* append the subAddrIE */ + memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2)); + iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2; + } else { + /* fill in from the beginning */ + iam.accTrnspt.eh.pres = PRSNT_NODEF; + iam.accTrnspt.infoElmts.pres = PRSNT_NODEF; + memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2)); + iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2; + } /* if (iam.accTrnspt.eh.pres */ + } /* if (subAddrIE[0] != '0') */ + } + + /* check if the user would like us to send a cld_sub-address */ + cld_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_cld_subaddr"); + if ((cld_subAddr != NULL) && (*cld_subAddr)) { + SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr); + + /* clean out the subAddrIE */ + memset(subAddrIE, 0x0, sizeof(subAddrIE)); + + /* check the first character in the sub-address to see what type of encoding to use */ + switch (cld_subAddr[0]) { + case '0': /* NSAP */ + encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED); + break; + case '1': /* national variant */ + encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED); + break; + default: + SS7_ERROR_CHAN(ftdmchan,"Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]); + break; + } /* switch (cld_subAddr[0]) */ + + /* if subaddIE is still empty don't copy it in */ + if (subAddrIE[0] != '0') { + /* check if the cld_subAddr has already been added */ + if (iam.accTrnspt.eh.pres == PRSNT_NODEF) { + /* append the subAddrIE */ + memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2)); + iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2; + } else { + /* fill in from the beginning */ + iam.accTrnspt.eh.pres = PRSNT_NODEF; + iam.accTrnspt.infoElmts.pres = PRSNT_NODEF; + memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2)); + iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2; + } /* if (iam.accTrnspt.eh.pres */ + } /* if (subAddrIE[0] != '0') */ + } /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */ + + + + sng_cc_con_request (sngss7_info->spId, sngss7_info->suInstId, sngss7_info->spInstId, diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 41db1fe140..718663950a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -71,6 +71,9 @@ ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info); ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); + +ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); +ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -884,6 +887,214 @@ ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info) } /******************************************************************************/ +ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type) +{ + /* Q931 4.5.9 + * 8 7 6 5 4 3 2 1 (octet) + * + * 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7) + * X X X X X X X X (length of IE contents) + * 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3) + * X X X X X X X X (sub address encoded in ia5) + */ + + int x = 0; + int p = 0; + int len = 0; + char tmp[2]; + + /* initalize the second element of tmp to \0 so that atoi doesn't go to far */ + tmp[1]='\0'; + + /* set octet 1 aka IE id */ + p = 0; + switch(type) { + /**************************************************************************/ + case SNG_CALLED: /* called party sub address */ + subAddrIE[p] = 0x71; + break; + /**************************************************************************/ + case SNG_CALLING: /* calling party sub address */ + subAddrIE[p] = 0x6d; + break; + /**************************************************************************/ + default: /* not good */ + SS7_ERROR("Sub-Address type is invalid: %d\n", type); + return FTDM_FAIL; + break; + /**************************************************************************/ + } /* switch(type) */ + + /* set octet 3 aka type and o/e */ + p = 2; + subAddrIE[p] = 0x80; + + /* set the subAddrIE pointer octet 4 */ + p = 3; + + /* loop through all digits in subAddr and insert them into subAddrIE */ + while (subAddr[x] != '\0') { + + /* grab a character */ + tmp[0] = subAddr[x]; + + /* confirm it is a digit */ + if (!isdigit(tmp[0])) { + /* move to the next character in subAddr */ + x++; + + /* restart the loop */ + continue; + } + + /* convert the character to IA5 encoding and write into subAddrIE */ + subAddrIE[p] = atoi(&tmp[0]); /* lower nibble is the digit */ + subAddrIE[p] |= 0x3 << 4; /* upper nibble is 0x3 */ + + /* increment address length counter */ + len++; + + /* increment the subAddrIE pointer */ + p++; + + /* move to the next character in subAddr */ + x++; + + } /* while (subAddr[x] != '\0') */ + + /* set octet 2 aka length of subaddr */ + p = 1; + subAddrIE[p] = len + 1; + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type) +{ + /* Q931 4.5.9 + * 8 7 6 5 4 3 2 1 (octet) + * + * 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7) + * X X X X X X X X (length of IE contents) + * 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3) + * X X X X X X X X (sub address encoded in ia5) + */ + + int x = 0; + int p = 0; + int len = 0; + char tmp[2]; + int flag = 0; + int odd = 0; + uint8_t lower = 0x0; + uint8_t upper = 0x0; + + /* initalize the second element of tmp to \0 so that atoi doesn't go to far */ + tmp[1]='\0'; + + /* set octet 1 aka IE id */ + p = 0; + switch(type) { + /**************************************************************************/ + case SNG_CALLED: /* called party sub address */ + subAddrIE[p] = 0x71; + break; + /**************************************************************************/ + case SNG_CALLING: /* calling party sub address */ + subAddrIE[p] = 0x6d; + break; + /**************************************************************************/ + default: /* not good */ + SS7_ERROR("Sub-Address type is invalid: %d\n", type); + return FTDM_FAIL; + break; + /**************************************************************************/ + } /* switch(type) */ + + /* set the subAddrIE pointer octet 4 */ + p = 3; + + /* loop through all digits in subAddr and insert them into subAddrIE */ + while (1) { + + /* grab a character */ + tmp[0] = subAddr[x]; + + /* confirm it is a hex digit */ + while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) { + /* move to the next character in subAddr */ + x++; + tmp[0] = subAddr[x]; + } + + /* check if tmp is null or a digit */ + if (tmp[0] != '\0') { + /* push it into the lower nibble using strtol to allow a-f chars */ + lower = strtol(&tmp[0], (char **)NULL, 16); + /* move to the next digit */ + x++; + /* grab a digit from the ftdm digits */ + tmp[0] = subAddr[x]; + + /* check if the digit is a hex digit and that is not null */ + while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { + x++; + tmp[0] = subAddr[x]; + } /* while(!(isdigit(tmp))) */ + + /* check if tmp is null or a digit */ + if (tmp[0] != '\0') { + /* push the digit into the upper nibble using strtol to allow a-f chars */ + upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4; + } else { + /* there is no upper ... fill in spare */ + upper = 0x00; + /* throw the odd flag since we need to buffer */ + odd = 1; + /* throw the end flag */ + flag = 1; + } /* if (tmp != '\0') */ + } else { + /* keep the odd flag down */ + odd = 0; + + /* throw the flag */ + flag = 1; + + /* bounce out right away */ + break; + } + + /* fill in the octet */ + subAddrIE[p] = upper | lower; + + /* increment address length counter */ + len++; + + /* if the flag is we're through all the digits */ + if (flag) break; + + /* increment the subAddrIE pointer */ + p++; + + /* move to the next character in subAddr */ + x++; + + } /* while (subAddr[x] != '\0') */ + + /* set octet 2 aka length of subaddr */ + p = 1; + subAddrIE[p] = len + 1; + + /* set octet 3 aka type and o/e */ + p = 2; + subAddrIE[p] = 0xa0 | (odd << 3); + + + return FTDM_SUCCESS; +} /******************************************************************************/ /* For Emacs: From d2691a7ff53cd36ddad01abeadf405b627800c24 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Mon, 18 Oct 2010 11:07:47 -0400 Subject: [PATCH 2/5] freetdm: ss7 - updated libSng-SS7 api, fixed spelling mistake in cli, added support for obci_bita --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 88 +++++++++++++++++-- .../ftmod_sangoma_ss7_main.c | 2 +- .../ftmod_sangoma_ss7_main.h | 10 +++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 16 +++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c | 18 +++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 14 ++- 6 files changed, 135 insertions(+), 13 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 92284edba3..38d3723061 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -616,8 +616,8 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream) stream->write_function(stream, "Sangoma SS7 CLI usuage:\n\n"); stream->write_function(stream, "Ftmod_sangoma_ss7 general control:\n"); - stream->write_function(stream, "ftdm ss7 set ftace X Y\n"); - stream->write_function(stream, "ftdm ss7 set mtace X Y\n"); + stream->write_function(stream, "ftdm ss7 set ftrace X Y\n"); + stream->write_function(stream, "ftdm ss7 set mtrace X Y\n"); stream->write_function(stream, "\n"); stream->write_function(stream, "Ftmod_sangoma_ss7 information:\n"); stream->write_function(stream, "ftdm ss7 show status link X\n"); @@ -1064,7 +1064,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, /* grab the signaling_status */ ftdm_channel_get_sig_status(ftdmchan, &sigstatus); - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|", + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%4s|state=%s|", ckt->span, ckt->chan, ckt->cic, @@ -1281,13 +1281,17 @@ static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name (sta.t.ssta.s.snDLSAP.remBlkd) ? "Y":"N", (sta.t.ssta.s.snDLSAP.locInhbt) ? "Y":"N", (sta.t.ssta.s.snDLSAP.rmtInhbt) ? "Y":"N"); - break; + + goto success; } /* move to the next link */ x++; } /* while (id != 0) */ + stream->write_function(stream, "Failed to find link=\"%s\"\n", name); + +success: return FTDM_SUCCESS; } @@ -1313,13 +1317,17 @@ static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *n name, DECODE_LSN_LINKSET_STATUS(sta.t.ssta.s.snLnkSet.state), sta.t.ssta.s.snLnkSet.nmbActLnks); - break; + + goto success; } /* move to the next linkset */ x++; } /* while (id != 0) */ + stream->write_function(stream, "Failed to find link=\"%s\"\n", name); + +success: return FTDM_SUCCESS; } @@ -1342,13 +1350,16 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name /* print the new status of the link */ handle_status_link(stream, &name[0]); - break; + goto success; } /* move to the next linkset */ x++; } /* while (id != 0) */ + stream->write_function(stream, "Failed to find link=\"%s\"\n", name); + +success: return FTDM_SUCCESS; } @@ -1371,13 +1382,16 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na /* print the new status of the link */ handle_status_link(stream, &name[0]); - break; + goto success; } /* move to the next linkset */ x++; } /* while (id != 0) */ + stream->write_function(stream, "Failed to find link=\"%s\"\n", name); + +success: return FTDM_SUCCESS; } @@ -1440,6 +1454,10 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c /* go the next circuit */ x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + + /* print the status of channels */ + handle_show_status(stream, span, chan, verbose); + return FTDM_SUCCESS; @@ -1505,6 +1523,24 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + handle_show_status(stream, span, chan, verbose); + } + } /* if ( cic == voice) */ + + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ return FTDM_SUCCESS; } @@ -1585,6 +1621,25 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c /* send the circuit group block */ ft_to_sngss7_cgb(main_chan); + + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + handle_show_status(stream, span, chan, verbose); + } + } /* if ( cic == voice) */ + + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ return FTDM_SUCCESS; @@ -1666,6 +1721,25 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c /* send the circuit group block */ ft_to_sngss7_cgu(main_chan); + + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + handle_show_status(stream, span, chan, verbose); + } + } /* if ( cic == voice) */ + + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ return FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index cff9711814..2b267e716c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1480,7 +1480,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sngss7_id = 0; - cmbLinkSetId = 1; + cmbLinkSetId = 0; /* initalize the global gen_config flag */ g_ftdm_sngss7_data.gen_config = 0; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 5de237dcbf..f41664a5b6 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -85,6 +85,10 @@ typedef enum { SNGSS7_PAUSED = (1 << 7) } sng_flag_t; +typedef enum { + SNGSS7_ACM_OBCI_BITA = (1 << 0) /* in-band indication */ +} sng_intf_options_t; + typedef enum { SNG_CALLED = 1, SNG_CALLING = 2 @@ -205,6 +209,7 @@ typedef struct sng_route { typedef struct sng_isup_intf { uint32_t id; char name[MAX_NAME_LEN]; + uint32_t options; uint32_t flags; uint32_t spc; uint32_t dpc; @@ -721,6 +726,11 @@ void handle_isup_t35(void *userdata); #define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag)) #define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag)) +#define sngss7_test_options(obj, option) ((obj)->options & option) +#define sngss7_clear_options(obj, option) ((obj)->options &= ~(option)) +#define sngss7_set_options(obj, option) ((obj)->options |= (option)) + + #ifdef SS7_PRODUCTION # define SS7_ASSERT \ SS7_INFO_CHAN(ftdmchan,"Production Mode, continuing%s\n", ""); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 3571a9ef0a..8cbe6d9498 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -308,7 +308,8 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) { SS7_FUNC_TRACE_ENTER (__FUNCTION__); - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + sng_isup_inf_t *isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; SiCnStEvnt acm; memset (&acm, 0x0, sizeof (acm)); @@ -337,7 +338,18 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */ acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND; - + + /* fill in any optional parameters */ + if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) { + acm.optBckCalInd.eh.pres = PRSNT_NODEF; + acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF; + acm.optBckCalInd.inbndInfoInd.val = sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA); + acm.optBckCalInd.caFwdMayOcc.pres = PRSNT_DEF; + acm.optBckCalInd.simpleSegmInd.pres = PRSNT_DEF; + acm.optBckCalInd.mlppUserInd.pres = PRSNT_DEF; + acm.optBckCalInd.usrNetIneractInd.pres = PRSNT_DEF; + } /* if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) */ + /* send the ACM request to LibSngSS7 */ sng_cc_con_status (1, sngss7_info->suInstId, diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c index d238462046..1235238452 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c @@ -50,27 +50,41 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm) { SnMngmt sta; + Pst pst; memset(&sta, 0x0, sizeof(sta)); + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + sta.hdr.elmId.elmnt = STDLSAP; sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; - return(sng_sta_mtp3(&sta, cfm)); + return(sng_sta_mtp3(&pst, &sta, cfm)); } /******************************************************************************/ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm) { SnMngmt sta; + Pst pst; memset(&sta, 0x0, sizeof(sta)); + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + sta.hdr.elmId.elmnt = STLNKSET; sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0]; - return(sng_sta_mtp3(&sta, cfm)); + return(sng_sta_mtp3(&pst, &sta, cfm)); } /******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index 359055fe2a..52295426c0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -1249,6 +1249,18 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) sng_isup.cld_nadi = atoi(parm->val); SS7_DEBUG("\tFound default CLD_NADI value = %d\n", sng_isup.cld_nadi); /**********************************************************************/ + } else if (!strcasecmp(parm->var, "obci_bita")) { + /**********************************************************************/ + if (*parm->val == '1') { + sngss7_set_options(&sng_isup, SNGSS7_ACM_OBCI_BITA); + SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) enable option\n"); + } else if (*parm->val == '0') { + sngss7_clear_options(&sng_isup, SNGSS7_ACM_OBCI_BITA); + SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) disable option\n"); + } else { + SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n"); + } + /**********************************************************************/ } else { SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); return FTDM_FAIL; @@ -1671,7 +1683,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap; g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi; g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi; - + g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options; if (sng_isup->t4 != 0) { g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4; } else { From 118403c5bfe111614eca66afba0cfd1aa45c9d54 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 19 Oct 2010 10:18:27 -0400 Subject: [PATCH 3/5] freetdm: ss7 - added support for 64bit to configure.ac --- libs/freetdm/configure.ac | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index a8ed67f228..18f83d8f1d 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -205,6 +205,18 @@ if test "${have_sng_isdn}" = "yes"; then fi fi +if test "${have_sng_ss7}" = "yes"; then + if test "${build}" == "${host}" + then + case "${host}" in + x86_64-*) + # X86_64 machines need additional flags when compiling against libsng_isdn + CFLAGS="$CFLAGS -DBIT_64 -DALIGN_64BIT" + ;; + esac + fi +fi + COMP_VENDOR_CFLAGS="$COMP_VENDOR_CFLAGS" AC_SUBST(COMP_VENDOR_CFLAGS) AC_CONFIG_FILES([Makefile From f0f2dfc5ace0ba634651cd0a6f99c65a01db8acc Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Wed, 20 Oct 2010 10:14:35 -0400 Subject: [PATCH 4/5] freetdm: ss7 - bug fix for call-resume and call-suspend handling, added isup interface option for lpa_on_cot --- .../ftmod_sangoma_ss7_handle.c | 73 ++++++++++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c | 124 +++++++++++++++++- .../ftmod_sangoma_ss7_main.c | 44 +++++-- .../ftmod_sangoma_ss7_main.h | 15 ++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 12 ++ 5 files changed, 252 insertions(+), 16 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index ac58abd412..807b3b62c7 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -51,6 +51,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); +ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); @@ -298,8 +300,21 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* need to grab the sp instance id */ sngss7_info->spInstId = spInstId; - /* go to PROGRESS */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + if ((siCnStEvnt->optBckCalInd.eh.pres) && + (siCnStEvnt->optBckCalInd.inbndInfoInd.pres)) { + + if (siCnStEvnt->optBckCalInd.inbndInfoInd.val) { + /* go to PROGRESS_MEDIA */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } else { + /* go to PROGRESS */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + } /* if (inband) */ + } else { + /* go to PROGRESS_MEDIA */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } + break; /**********************************************************************/ default: /* incorrect state...reset the CIC */ @@ -733,6 +748,60 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir return FTDM_SUCCESS; } +/******************************************************************************/ +ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Suspend msg\n", sngss7_info->circuit->cic); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Resume msg\n", sngss7_info->circuit->cic); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + /******************************************************************************/ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c index 34893cf5aa..06fae0cd37 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c @@ -52,7 +52,9 @@ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiIn void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); - +void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); +void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); +void sngss7_ssp_sta_cfm(uint32_t infId); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -442,7 +444,127 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint } /******************************************************************************/ +void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); + + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_SUSP_IND_EVENT; + if (siSuspEvnt != NULL) { + memcpy(&sngss7_event->event.siSuspEvnt, siSuspEvnt, sizeof(*siSuspEvnt)); + } + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + +} + +/******************************************************************************/ +void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); + + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_RESM_IND_EVENT; + if (siResmEvnt != NULL) { + memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt)); + } + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + +} + +/******************************************************************************/ +void sngss7_ssp_sta_cfm(uint32_t infId) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); +#if 0 + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); + + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_RESM_IND_EVENT; + if (siSuspEvnt != NULL) { + memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt)); + } + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); +#endif + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + +} /******************************************************************************/ /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 2b267e716c..587242d94e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -208,7 +208,7 @@ ftdm_state_map_t sangoma_ss7_state_map = { {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_UP, FTDM_END} + FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_END} }, { ZSD_OUTBOUND, @@ -448,6 +448,17 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt); break; /**************************************************************************/ + case (SNGSS7_SUSP_IND_EVENT): + handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt); + break; + /**************************************************************************/ + case (SNGSS7_RESM_IND_EVENT): + handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt); + break; + /**************************************************************************/ + case (SNGSS7_SSP_STA_CFM_EVENT): + break; + /**************************************************************************/ default: SS7_ERROR("Unknown Event Id!\n"); break; @@ -469,6 +480,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) { sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + sng_isup_inf_t *isup_intf = NULL; int i = 0; ftdm_sigmsg_t sigev; @@ -589,17 +601,16 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /*check if the channel is inbound or outbound */ - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) { /*OUTBOUND...so we were told by the line of this so noifiy the user */ sigev.event_id = FTDM_SIGEVENT_PROGRESS; ftdm_span_send_signal (ftdmchan->span, &sigev); + /* move to progress media */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else { /* inbound call so we need to send out ACM */ - ft_to_sngss7_acm (ftdmchan); - - ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + ft_to_sngss7_acm(ftdmchan); } break; @@ -611,6 +622,13 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) break; } + if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + /* inform the user there is media avai */ + sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; + ftdm_span_send_signal (ftdmchan->span, &sigev); + } + + /* nothing to do at this time */ break; /**************************************************************************/ @@ -1155,11 +1173,15 @@ suspend_goto_restart: ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART); break; -/**************************************************************************/ + /**************************************************************************/ case FTDM_CHANNEL_STATE_IN_LOOP: /* COT test */ - /* send the lpa */ - ft_to_sngss7_lpa (ftdmchan); + isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + + if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) { + /* send the lpa */ + ft_to_sngss7_lpa (ftdmchan); + } break; /**************************************************************************/ @@ -1507,9 +1529,9 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sng_event.cc.sng_fac_cfm = sngss7_fac_cfm; sng_event.cc.sng_sta_ind = sngss7_sta_ind; sng_event.cc.sng_umsg_ind = sngss7_umsg_ind; - sng_event.cc.sng_susp_ind = NULL; - sng_event.cc.sng_resm_ind = NULL; - sng_event.cc.sng_ssp_sta_cfm = NULL; + sng_event.cc.sng_susp_ind = sngss7_susp_ind; + sng_event.cc.sng_resm_ind = sngss7_resm_ind; + sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm; sng_event.sm.sng_log = handle_sng_log; sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index f41664a5b6..27833cb2a2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -70,7 +70,10 @@ typedef enum { SNGSS7_FAC_IND_EVENT, SNGSS7_FAC_CFM_EVENT, SNGSS7_UMSG_IND_EVENT, - SNGSS7_STA_IND_EVENT + SNGSS7_STA_IND_EVENT, + SNGSS7_SUSP_IND_EVENT, + SNGSS7_RESM_IND_EVENT, + SNGSS7_SSP_STA_CFM_EVENT } sng_event_type_t; typedef enum { @@ -86,7 +89,8 @@ typedef enum { } sng_flag_t; typedef enum { - SNGSS7_ACM_OBCI_BITA = (1 << 0) /* in-band indication */ + SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */ + SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */ } sng_intf_options_t; typedef enum { @@ -397,6 +401,8 @@ typedef struct sngss7_event_data SiInfoEvnt siInfoEvnt; SiFacEvnt siFacEvnt; SiStaEvnt siStaEvnt; + SiSuspEvnt siSuspEvnt; + SiResmEvnt siResmEvnt; } event; } sngss7_event_data_t; @@ -526,6 +532,9 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); +void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); +void sngss7_ssp_sta_cfm(uint32_t infId); /* in ftmod_sangoma_ss7_handle.c */ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); @@ -537,6 +546,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); +ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index 52295426c0..0f81d61f25 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -1261,6 +1261,18 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n"); } /**********************************************************************/ + } else if (!strcasecmp(parm->var, "lpa_on_cot")) { + /**********************************************************************/ + if (*parm->val == '1') { + sngss7_set_options(&sng_isup, SNGSS7_LPA_FOR_COT); + SS7_DEBUG("\tFound Tx LPA on COT enable option\n"); + } else if (*parm->val == '0') { + sngss7_clear_options(&sng_isup, SNGSS7_LPA_FOR_COT); + SS7_DEBUG("\tFound Tx LPA on COT disable option\n"); + } else { + SS7_DEBUG("\tInvalid value for \"lpa_on_cot\" option\n"); + } + /**********************************************************************/ } else { SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); return FTDM_FAIL; From df005951ebbbd0e25551158bfcb0f87ee27dfc6f Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 21 Oct 2010 10:45:03 -0700 Subject: [PATCH 5/5] freetdm: Added Print for Called Number, Calling Name on incoming/outgoing calls --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 5 ++--- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 827647f1f6..41833c54d3 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -79,6 +79,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) 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; @@ -128,14 +129,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) #if 0 /* Export ftdmchan variables here if we need to */ ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); - ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap"); - ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s"); - ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad"); #endif /* Fill in call information */ cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); cpy_calling_name_from_stack(&ftdmchan->caller_data, &conEvnt->display); + ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); if (conEvnt->bearCap[0].eh.pres) { ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 80a85ceec8..3284d54165 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -143,6 +143,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) signal_data->signalling == SNGISDN_SIGNALING_NET) { sngisdn_info->ces = CES_MNGMNT; } + ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data); cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);