summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UPGRADE.txt4
-rw-r--r--channels/chan_dahdi.c35
-rw-r--r--channels/sig_pri.c119
-rw-r--r--channels/sig_pri.h2
4 files changed, 157 insertions, 3 deletions
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-<span>-<sequence-number>
+ DAHDI/i<span>/<number>[:<subaddress>]-<sequence-number>
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 <number>[:<subaddress>]
+ * \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<keypad-digits>/]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);