aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_misdn.c156
-rw-r--r--channels/misdn/isdn_msg_parser.c66
2 files changed, 187 insertions, 35 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index d326e1511..ed41c25c3 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -6200,13 +6200,36 @@ static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bc
is_ptmp = !misdn_lib_is_ptp(bc->port);
if (is_ptmp) {
- /* Send NOTIFY(transfer-active, redirecting.to data) */
- bc->redirecting.to_changed = 1;
- bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE;
- misdn_lib_send_event(bc, EVENT_NOTIFY);
+ /*
+ * We should not send these messages to the network if we are
+ * the CPE side since phones do not transfer calls within
+ * themselves. Well... If you consider handing the handset to
+ * someone else a transfer then how is the network to know?
+ */
+ if (!misdn_lib_port_is_nt(bc->port)) {
+ return;
+ }
+ if (ch->state != MISDN_CONNECTED) {
+ /* Send NOTIFY(Nie(transfer-active), RDNie(redirecting.to data)) */
+ bc->redirecting.to_changed = 1;
+ bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE;
+ misdn_lib_send_event(bc, EVENT_NOTIFY);
+#if defined(AST_MISDN_ENHANCEMENTS)
+ } else {
+ /* Send FACILITY(Fie(RequestSubaddress), Nie(transfer-active), RDNie(redirecting.to data)) */
+ bc->redirecting.to_changed = 1;
+ bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE;
+ bc->fac_out.Function = Fac_RequestSubaddress;
+ bc->fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id;
+
+ /* Send message */
+ print_facility(&bc->fac_out, bc);
+ misdn_lib_send_event(bc, EVENT_FACILITY);
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
+ }
#if defined(AST_MISDN_ENHANCEMENTS)
} else {
- /* Send EctInform(transfer-active, redirecting.to data) */
+ /* Send FACILITY(Fie(EctInform(transfer-active, redirecting.to data))) */
bc->fac_out.Function = Fac_EctInform;
bc->fac_out.u.EctInform.InvokeID = ++misdn_invoke_id;
bc->fac_out.u.EctInform.Status = 1;/* active */
@@ -9191,7 +9214,59 @@ static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel
/* We do not have anything to do for this message since we do not handle subaddreses. */
break;
case Fac_RequestSubaddress:
- /* We do not have anything to do for this message since we do not handle subaddreses. */
+ /*
+ * We do not have anything to do for this message since we do not handle subaddreses.
+ * However, we do care about some other ie's that should be present.
+ */
+ if (bc->redirecting.to_changed) {
+ /* Add configured prefix to redirecting.to.number */
+ misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type,
+ bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
+ }
+ switch (bc->notify_description_code) {
+ case mISDN_NOTIFY_CODE_INVALID:
+ /* Notify ie was not present. */
+ bc->redirecting.to_changed = 0;
+ break;
+ case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING:
+ /*
+ * It would be preferable to update the connected line information
+ * only when the message callStatus is active. However, the
+ * optional redirection number may not be present in the active
+ * message if an alerting message were received earlier.
+ *
+ * The consequences if we wind up sending two updates is benign.
+ * The other end will think that it got transferred twice.
+ */
+ if (!bc->redirecting.to_changed) {
+ break;
+ }
+ bc->redirecting.to_changed = 0;
+ if (!ch || !ch->ast) {
+ break;
+ }
+ misdn_update_remote_party(ch->ast, &bc->redirecting.to,
+ AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING,
+ bc->incoming_cid_tag);
+ break;
+ case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE:
+ if (!bc->redirecting.to_changed) {
+ break;
+ }
+ bc->redirecting.to_changed = 0;
+ if (!ch || !ch->ast) {
+ break;
+ }
+ misdn_update_remote_party(ch->ast, &bc->redirecting.to,
+ AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag);
+ break;
+ default:
+ bc->redirecting.to_changed = 0;
+ chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
+ bc->notify_description_code);
+ break;
+ }
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
break;
case Fac_EctInform:
/* Private-Public ISDN interworking message */
@@ -10651,24 +10726,25 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
bc->redirecting.to_changed = 0;
break;
case mISDN_NOTIFY_CODE_CALL_IS_DIVERTING:
- if (bc->redirecting.to_changed) {
- bc->redirecting.to_changed = 0;
- if (ch && ch->ast) {
- switch (ch->state) {
- case MISDN_ALERTING:
- /* Call is deflecting after we have seen an ALERTING message */
- bc->redirecting.reason = mISDN_REDIRECTING_REASON_NO_REPLY;
- break;
- default:
- /* Call is deflecting for call forwarding unconditional or busy reason. */
- bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
- break;
- }
- misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
- ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting,
- NULL);
- }
+ if (!bc->redirecting.to_changed) {
+ break;
}
+ bc->redirecting.to_changed = 0;
+ if (!ch || !ch->ast) {
+ break;
+ }
+ switch (ch->state) {
+ case MISDN_ALERTING:
+ /* Call is deflecting after we have seen an ALERTING message */
+ bc->redirecting.reason = mISDN_REDIRECTING_REASON_NO_REPLY;
+ break;
+ default:
+ /* Call is deflecting for call forwarding unconditional or busy reason. */
+ bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
+ break;
+ }
+ misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
+ ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL);
break;
case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING:
/*
@@ -10680,22 +10756,27 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
* The consequences if we wind up sending two updates is benign.
* The other end will think that it got transferred twice.
*/
- if (bc->redirecting.to_changed) {
- bc->redirecting.to_changed = 0;
- if (ch && ch->ast) {
- misdn_update_remote_party(ch->ast, &bc->redirecting.to,
- AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, bc->incoming_cid_tag);
- }
+ if (!bc->redirecting.to_changed) {
+ break;
}
+ bc->redirecting.to_changed = 0;
+ if (!ch || !ch->ast) {
+ break;
+ }
+ misdn_update_remote_party(ch->ast, &bc->redirecting.to,
+ AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING,
+ bc->incoming_cid_tag);
break;
case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE:
- if (bc->redirecting.to_changed) {
- bc->redirecting.to_changed = 0;
- if (ch && ch->ast) {
- misdn_update_remote_party(ch->ast, &bc->redirecting.to,
- AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag);
- }
+ if (!bc->redirecting.to_changed) {
+ break;
}
+ bc->redirecting.to_changed = 0;
+ if (!ch || !ch->ast) {
+ break;
+ }
+ misdn_update_remote_party(ch->ast, &bc->redirecting.to,
+ AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag);
break;
default:
bc->redirecting.to_changed = 0;
@@ -10703,6 +10784,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
bc->notify_description_code);
break;
}
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
break;
case EVENT_FACILITY:
if (bc->fac_in.Function == Fac_None) {
@@ -10711,6 +10793,10 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
} else {
misdn_facility_ie_handler(event, bc, ch);
}
+
+ /* In case it came in on a FACILITY message and we did not handle it. */
+ bc->redirecting.to_changed = 0;
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
break;
case EVENT_RESTART:
if (!bc->dummy) {
diff --git a/channels/misdn/isdn_msg_parser.c b/channels/misdn/isdn_msg_parser.c
index fa1560e5d..3c7a8f33a 100644
--- a/channels/misdn/isdn_msg_parser.c
+++ b/channels/misdn/isdn_msg_parser.c
@@ -1282,6 +1282,13 @@ static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bch
FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
unsigned char *p = NULL;
+#if defined(AST_MISDN_ENHANCEMENTS)
+ int description_code;
+ int type;
+ int plan;
+ int present;
+ char number[sizeof(bc->redirecting.to.number)];
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
#ifdef DEBUG
printf("Parsing FACILITY Msg\n");
@@ -1301,6 +1308,37 @@ static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bch
if (decodeFac(p, &bc->fac_in)) {
cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
}
+
+#if defined(AST_MISDN_ENHANCEMENTS)
+ dec_ie_notify(facility->NOTIFY, qi, &description_code, nt, bc);
+ if (description_code < 0) {
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
+ } else {
+ bc->notify_description_code = description_code;
+ }
+
+ dec_ie_redir_dn(facility->REDIR_DN, qi, &type, &plan, &present, number, sizeof(number), nt, bc);
+ if (0 <= type) {
+ bc->redirecting.to_changed = 1;
+
+ bc->redirecting.to.number_type = type;
+ bc->redirecting.to.number_plan = plan;
+ switch (present) {
+ default:
+ case 0:
+ bc->redirecting.to.presentation = 0; /* presentation allowed */
+ break;
+ case 1:
+ bc->redirecting.to.presentation = 1; /* presentation restricted */
+ break;
+ case 2:
+ bc->redirecting.to.presentation = 2; /* Number not available */
+ break;
+ }
+ bc->redirecting.to.screening = 0; /* Unscreened */
+ strcpy(bc->redirecting.to.number, number);
+ }
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
}
static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
@@ -1324,6 +1362,12 @@ static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc,
* Clear facility information
*/
bc->fac_out.Function = Fac_None;
+
+#if defined(AST_MISDN_ENHANCEMENTS)
+ /* Clear other one shot information. */
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
+ bc->redirecting.to_changed = 0;
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
return NULL;
}
@@ -1351,6 +1395,27 @@ static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc,
enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
}
+#if defined(AST_MISDN_ENHANCEMENTS)
+ if (bc->notify_description_code != mISDN_NOTIFY_CODE_INVALID) {
+ enc_ie_notify(&facility->NOTIFY, msg, bc->notify_description_code, nt, bc);
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
+ }
+
+ if (bc->redirecting.to_changed) {
+ bc->redirecting.to_changed = 0;
+ switch (bc->outgoing_colp) {
+ case 0:/* pass */
+ case 1:/* restricted */
+ enc_ie_redir_dn(&facility->REDIR_DN, msg, bc->redirecting.to.number_type,
+ bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
+ bc->redirecting.to.number, nt, bc);
+ break;
+ default:
+ break;
+ }
+ }
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
+
return msg;
}
@@ -1469,6 +1534,7 @@ static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, i
notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
enc_ie_notify(&notify->NOTIFY, msg, bc->notify_description_code, nt, bc);
+ bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
if (bc->redirecting.to_changed) {
bc->redirecting.to_changed = 0;