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) {
#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,
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;
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);
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 ();
/* 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;
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,
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 ******************************************************************/
}
/******************************************************************************/
+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: