aboutsummaryrefslogtreecommitdiffstats
path: root/channels/sig_pri.c
diff options
context:
space:
mode:
authorrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2009-11-02 17:34:22 +0000
committerrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2009-11-02 17:34:22 +0000
commit225f4a7ea1c36f5ac0bf9ac7eb29122c3655cba2 (patch)
treed196854b76b89353606f0e429a0bf9b3dbc3474d /channels/sig_pri.c
parent398f78ff7459d0fb8bbb4db965ca86d3b0fd7e4c (diff)
DAHDI ISDN channel names will not allow device state to work. (Interim solution.)
Since ISDN works like SIP and not analog ports in regard to devices, the device state based on the ISDN channel number could not work. This has not been an issue until the advent of PTMP NT mode. Previously, ISDN lines were used as trunks and did not have to keep track of specific devices. As an interim solution until device states are properly implemented, the channel name is being changed to the following format to use the generic device state support: DAHDI/i<span>/<number>[:<subaddress>]-<sequence-number> Dialplan hints would thus be: exten => xxx,hint,DAHDI/i2/5551212 This will work with the following restrictions: * The number of devices/phones cannot exceed the number of B channels. (i.e., BRI has 2) * Each device/phone can only have one number. No shared MSN's. * The phones/devices probably should not use subaddressing. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@226882 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/sig_pri.c')
-rw-r--r--channels/sig_pri.c119
1 files changed, 119 insertions, 0 deletions
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 */