Merged revisions 287017 via svnmerge from
authorRichard Mudgett <rmudgett@digium.com>
Wed, 15 Sep 2010 20:56:21 +0000 (20:56 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 15 Sep 2010 20:56:21 +0000 (20:56 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r287017 | rmudgett | 2010-09-15 15:53:38 -0500 (Wed, 15 Sep 2010) | 65 lines

  Merged revision 287014 from
  https://origsvn.digium.com/svn/asterisk/be/branches/C.3-bier

  ..........
    r287014 | rmudgett | 2010-09-15 15:32:24 -0500 (Wed, 15 Sep 2010) | 58 lines

    The handling of call transfer signaling for mISDN PTMP is not fully implemented.

    The handling of call transfer signaling for mISDN PTMP is not fully
    implemented.  The signaling of number updates with ISDN/DSS1 ECT
    supplementary services (ETS 300 369-1) comes along with a notification
    indicator IE and redirection number IE for PTMP.  The implementation in
    the current Asterisk mISDN channel unfortunately can handle these
    information elements only in a NOTIFY message.  These information elements
    are also signaled in a FACILTY message with a RequestSubaddress facility,
    when the subscriber is already in the active state (see 9.2.4 and 9.2.5 of
    ETS 300 369-1).

    **********

    abe_2526_ast.patch

    * Added support to handle the notification indicator IE and redirection
    number IE with the RequestSubaddress facility.

    * Made misdn_update_connected_line() send a NOTIFY message if Asterisk
    originated the call and it is not connected yet.

    * Made misdn_update_connected_line() send a FACILITY message if the call
    is already connected.

    This patch requires the presence of the associated mISDN patches to
    compile.  I had to enhance mISDN to allow the notification indicator IE
    and the redirection number IE to be used with a FACILITY message.  Earlier
    versions of the Digium enhanced mISDN are no longer going to work.

    **********

    abe_2526_misdn.patch

    * Made an incoming FACILITY message allow the presence of the notification
    indicator IE and the redirection number IE.

    **********

    abe_2526_misdnuser_v3.patch

    * Added support to send and receive a FACILITY message with the
    notification indicator IE and the redirection number IE.

    * Added the ability to send a NOTIFY message in PTMP/NT mode to all
    responding subcalls in Q.931 states 6, 7, 8, 9, and 25.

    **********

    Patches:
   abe_2526_ast.patch uploaded by rmudgett (license 664)
   abe_2526_misdn.patch uploaded by rmudgett (license 664)
   abe_2526_misdnuser_v3.patch uploaded by rmudgett (license 664)
    Tested by: rmudgett and reporter

    JIRA SWP-2146
    JIRA ABE-2526
  ..........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@287018 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_misdn.c
channels/misdn/isdn_msg_parser.c

index d326e15..ed41c25 100644 (file)
@@ -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) {
index fa1560e..3c7a8f3 100644 (file)
@@ -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;