diff options
-rw-r--r-- | channels/chan_misdn.c | 156 | ||||
-rw-r--r-- | channels/misdn/isdn_msg_parser.c | 66 |
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(¬ify->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; |