diff --git a/UPGRADE.txt b/UPGRADE.txt index 61d4ec148..79c1b958a 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -18,7 +18,7 @@ === =========================================================== -From 1.6.2 to 1.6.3: +From 1.6.2 to 1.8: * Asterisk-addons no longer exists as an independent package. Those modules now live in the addons directory of the main Asterisk source tree. They @@ -53,7 +53,7 @@ From 1.6.2 to 1.6.3: the channel name to infer what B channel a call is using and to avoid name collisions, the channel name format is changed. The new channel naming for PRI channels is: - DAHDI/ISDN-- + DAHDI/i/[:]- From 1.6.1 to 1.6.2: diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 583408e43..b81c7a8ef 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -1039,6 +1039,8 @@ struct dahdi_pvt { int cid_ton; /*! \brief Caller ID name from an incoming call. */ char cid_name[AST_MAX_EXTENSION]; + /*! \brief Caller ID subaddress from an incoming call. */ + char cid_subaddr[AST_MAX_EXTENSION]; char *origcid_num; /*!< malloced original callerid */ char *origcid_name; /*!< malloced original callerid */ /*! \brief Call waiting number. */ @@ -2719,6 +2721,12 @@ static void my_pri_set_callerid(void *pvt, const struct ast_party_caller *caller ast_copy_string(p->cid_num, S_OR(caller->id.number, ""), sizeof(p->cid_num)); ast_copy_string(p->cid_name, S_OR(caller->id.name, ""), sizeof(p->cid_name)); + if (caller->id.subaddress.valid) { + ast_copy_string(p->cid_subaddr, S_OR(caller->id.subaddress.str, ""), + sizeof(p->cid_subaddr)); + } else { + p->cid_subaddr[0] = '\0'; + } p->cid_ton = caller->id.number_type; p->callingpres = caller->id.number_presentation; ast_copy_string(p->cid_ani, S_OR(caller->ani, ""), sizeof(p->cid_ani)); @@ -3073,6 +3081,7 @@ static void dahdi_r2_on_call_init(openr2_chan_t *r2chan) /* better safe than sorry ... */ p->cid_name[0] = '\0'; p->cid_num[0] = '\0'; + p->cid_subaddr[0] = '\0'; p->rdnis[0] = '\0'; p->exten[0] = '\0'; p->mfcr2_ani_index = '\0'; @@ -5430,6 +5439,7 @@ static int dahdi_hangup(struct ast_channel *ast) } else { p->cid_num[0] = '\0'; p->cid_name[0] = '\0'; + p->cid_subaddr[0] = '\0'; } ast_mutex_lock(&p->lock); @@ -8528,7 +8538,22 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb #if defined(HAVE_PRI) } else if (i->pri) { ast_mutex_lock(&i->pri->lock); - ast_str_set(&chan_name, 0, "ISDN-%d-%d", i->pri->span, ++i->pri->new_chan_seq); + y = ++i->pri->new_chan_seq; + if (i->outgoing) { + /* + * The dnid has been stuffed with the called-number[:subaddress] + * by dahdi_request(). + */ + ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->dnid, y); + i->dnid[0] = '\0'; + } else if (ast_strlen_zero(i->cid_subaddr)) { + /* Put in caller-id number only since there is no subaddress. */ + ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, y); + } else { + /* Put in caller-id number and subaddress. */ + ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num, + i->cid_subaddr, y); + } ast_mutex_unlock(&i->pri->lock); #endif /* defined(HAVE_PRI) */ } else { @@ -11559,6 +11584,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, tmp->cid_num[0] = '\0'; tmp->cid_name[0] = '\0'; } + tmp->cid_subaddr[0] = '\0'; ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) { char *mailbox, *context; @@ -12098,6 +12124,8 @@ static struct ast_channel *dahdi_request(const char *type, int format, const str tmp = analog_request(p->sig_pvt, &callwait, requestor); #ifdef HAVE_PRI } else if (dahdi_sig_pri_lib_handles(p->sig)) { + sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid, + sizeof(p->dnid)); tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor); #endif } else { @@ -14319,6 +14347,11 @@ static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli ast_cli(a->fd, "Context: %s\n", tmp->context); ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num); ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton); +#if defined(HAVE_PRI) +#if defined(HAVE_PRI_SUBADDR) + ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr); +#endif /* defined(HAVE_PRI_SUBADDR) */ +#endif /* defined(HAVE_PRI) */ ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name); ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none")); if (tmp->vars) { diff --git a/channels/sig_pri.c b/channels/sig_pri.c index f369fa381..dbbeccf78 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -129,6 +129,12 @@ static void sig_pri_set_caller_id(struct sig_pri_chan *p) ast_party_caller_init(&caller); caller.id.number = p->cid_num; caller.id.name = p->cid_name; + if (!ast_strlen_zero(p->cid_subaddr)) { + caller.id.subaddress.valid = 1; + //caller.id.subaddress.type = 0;/* nsap */ + //caller.id.subaddress.odd_even_indicator = 0; + caller.id.subaddress.str = p->cid_subaddr; + } caller.id.number_type = p->cid_ton; caller.id.number_presentation = p->callingpres; caller.ani = p->cid_ani; @@ -1520,10 +1526,16 @@ static void sig_pri_handle_subcmds(struct sig_pri_pri *pri, int chanpos, int eve } ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; + pri->pvts[chanpos]->cid_subaddr[0] = '\0'; #if defined(HAVE_PRI_SUBADDR) if (ast_connected.id.subaddress.valid) { ast_party_subaddress_set(&owner->cid.subaddress, &ast_connected.id.subaddress); + if (ast_connected.id.subaddress.str) { + ast_copy_string(pri->pvts[chanpos]->cid_subaddr, + ast_connected.id.subaddress.str, + sizeof(pri->pvts[chanpos]->cid_subaddr)); + } } #endif /* defined(HAVE_PRI_SUBADDR) */ if (caller_id_update) { @@ -2335,6 +2347,22 @@ static void *pri_dchannel(void *vpri) pri->pvts[chanpos]->cid_ani[0] = '\0'; } #endif + pri->pvts[chanpos]->cid_subaddr[0] = '\0'; +#if defined(HAVE_PRI_SUBADDR) + if (e->ring.calling.subaddress.valid) { + struct ast_party_subaddress calling_subaddress; + + ast_party_subaddress_init(&calling_subaddress); + sig_pri_set_subaddress(&calling_subaddress, + &e->ring.calling.subaddress); + if (calling_subaddress.str) { + ast_copy_string(pri->pvts[chanpos]->cid_subaddr, + calling_subaddress.str, + sizeof(pri->pvts[chanpos]->cid_subaddr)); + } + ast_party_subaddress_free(&calling_subaddress); + } +#endif /* defined(HAVE_PRI_SUBADDR) */ ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name)); pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */ pri->pvts[chanpos]->callingpres = e->ring.callingpres; @@ -2343,6 +2371,7 @@ static void *pri_dchannel(void *vpri) } } else { pri->pvts[chanpos]->cid_num[0] = '\0'; + pri->pvts[chanpos]->cid_subaddr[0] = '\0'; pri->pvts[chanpos]->cid_ani[0] = '\0'; pri->pvts[chanpos]->cid_name[0] = '\0'; pri->pvts[chanpos]->cid_ton = 0; @@ -3170,6 +3199,7 @@ int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast) p->alerting = 0; p->setup_ack = 0; p->cid_num[0] = '\0'; + p->cid_subaddr[0] = '\0'; p->cid_name[0] = '\0'; p->exten[0] = '\0'; sig_pri_set_dialing(p, 0); @@ -3219,6 +3249,95 @@ exit: return res; } +/*! + * \brief Extract the called number and subaddress from the dial string. + * \since 1.6.3 + * + * \param p sig_pri channel structure. + * \param rdest Dial string buffer to extract called number and subaddress. + * \param called Buffer to fill with extracted [:] + * \param called_buff_size Size of buffer to fill. + * + * \note Parsing must remain in sync with sig_pri_call(). + * + * \return Nothing + */ +void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size) +{ + char *dial; + char *number; + char *subaddr; + + /* Get private copy of dial string. */ + dial = ast_strdupa(rdest); + + /* Skip channel selection section. */ + number = strchr(dial, '/'); + if (number) { + ++number; + } else { + number = ""; + } + +#if defined(HAVE_PRI_SETUP_KEYPAD) + /* + * v--- number points here + * /[K/]extension + */ + if (number[0] == 'K') { + /* Skip the keypad facility digits. */ + number = strchr(number + 1, '/'); + if (number) { + ++number; + } else { + number = ""; + } + } + /* + * v--- number points here + * /extension + */ +#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ + + /* Find and extract dialed_subaddress */ + subaddr = strchr(number, ':'); + if (subaddr) { + *subaddr++ = '\0'; + + /* Skip subaddress type prefix. */ + switch (*subaddr) { + case 'U': + case 'u': + case 'N': + case 'n': + ++subaddr; + break; + default: + break; + } + } + + /* Skip type-of-number/dial-plan prefix characters. */ + if (strlen(number) < p->stripmsd) { + number = ""; + } else { + number += p->stripmsd; + while (isalpha(*number)) { + ++number; + } + } + + /* Fill buffer with extracted number and subaddress. */ + if (ast_strlen_zero(subaddr)) { + /* Put in called number only since there is no subaddress. */ + snprintf(called, called_buff_size, "%s", number); + } else { + /* Put in called number and subaddress. */ + snprintf(called, called_buff_size, "%s:%s", number, subaddr); + } +} + +/*! \note Parsing must remain in sync with sig_pri_extract_called_num_subaddr(). */ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1) { char dest[256]; /* must be same length as p->dialdest */ diff --git a/channels/sig_pri.h b/channels/sig_pri.h index d04ffeb95..fa2767500 100644 --- a/channels/sig_pri.h +++ b/channels/sig_pri.h @@ -138,6 +138,7 @@ struct sig_pri_chan { int cid_ton; /*!< Type Of Number (TON) */ int callingpres; /*!< The value of calling presentation that we're going to use when placing a PRI call */ char cid_num[AST_MAX_EXTENSION]; + char cid_subaddr[AST_MAX_EXTENSION]; char cid_name[AST_MAX_EXTENSION]; char cid_ani[AST_MAX_EXTENSION]; char exten[AST_MAX_EXTENSION]; @@ -246,6 +247,7 @@ struct sig_pri_pri { struct sig_pri_callback *calls; }; +void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size); int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1); int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast);