The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/ngatm/netnatm/sig/sig_coord.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1996-2003
    3  *      Fraunhofer Institute for Open Communication Systems (FhG Fokus).
    4  *      All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * Author: Hartmut Brandt <harti@freebsd.org>
   28  *
   29  * $Begemot: libunimsg/netnatm/sig/sig_coord.c,v 1.12 2004/08/05 07:11:01 brandt Exp $
   30  *
   31  * Coordinator
   32  */
   33 
   34 #include <netnatm/unimsg.h>
   35 #include <netnatm/saal/sscfudef.h>
   36 #include <netnatm/msg/unistruct.h>
   37 #include <netnatm/msg/unimsglib.h>
   38 #include <netnatm/sig/uni.h>
   39 
   40 #include <netnatm/sig/unipriv.h>
   41 #include <netnatm/sig/unimkmsg.h>
   42 
   43 #define STR(S) [S] = #S
   44 static const char *const cunames[] = {
   45         STR(CU_STAT0),
   46         STR(CU_STAT1),
   47         STR(CU_STAT2),
   48         STR(CU_STAT3),
   49 };
   50 
   51 #define DEF_PRIV_SIG(NAME, FROM)        [SIG##NAME] =   "SIG"#NAME,
   52 static const char *const coord_sigs[] = {
   53         DEF_COORD_SIGS
   54 };
   55 #undef DEF_PRIV_SIG
   56 
   57 static void sig_all_calls(struct uni *, u_int sig);
   58 static void set_custat(struct uni *, enum cu_stat);
   59 
   60 static void input_dummy(struct uni *uni, struct uni_msg *m, struct uni_all *u);
   61 static void input_global(struct uni *uni, struct uni_msg *m, struct uni_all *u);
   62 static void input_unknown(struct uni *uni, struct uni_msg *m, struct uni_all *u);
   63 static void input_cobi(struct call *c, struct uni_msg *m, struct uni_all *u);
   64 static void input_call(struct call *c, struct uni_msg *m, struct uni_all *u);
   65 
   66 TIMER_FUNC_UNI(t309, t309_func)
   67 
   68 /*
   69  * All those 'bogus signal' printouts are not specified in the SDLs.
   70  */
   71 
   72 
   73 /*
   74  * SAAL-ESTABLISH.indication
   75  *
   76  * This means either a resynchronisation or error-recovery or
   77  * an incoming SSCOP connection.
   78  */
   79 static void
   80 coord_saal_establish_indication(struct uni *uni)
   81 {
   82         switch (uni->custat) {
   83 
   84           case CU_STAT0:        /* Q.2931:Coord-U 4/10 */
   85           case CU_STAT3:        /* Q.2931:Coord-U 5/10 */
   86                 sig_all_calls(uni, SIGC_LINK_ESTABLISH_indication);
   87                 set_custat(uni, CU_STAT3);
   88                 break;
   89 
   90           case CU_STAT1:
   91           case CU_STAT2:
   92                 VERBOSE0(uni, UNI_FAC_COORD,
   93                     "signal saal_establish.indication in CU%u", uni->custat);
   94                 break;
   95 
   96           default:
   97                 ASSERT(0, ("CU_STAT*"));
   98         }
   99 }
  100 
  101 /*
  102  * SAAL-ESTABLISH.confirm
  103  */
  104 static void
  105 coord_saal_establish_confirm(struct uni *uni)
  106 {
  107         switch (uni->custat) {
  108 
  109           case CU_STAT0:
  110           case CU_STAT2:
  111                 VERBOSE0(uni, UNI_FAC_COORD,
  112                     "signal saal_establish.confirm in CU%u", uni->custat);
  113                 break;
  114 
  115           case CU_STAT1:
  116                 /*
  117                  * Q.2931:Co-ord-U 4/10
  118                  */
  119                 TIMER_STOP_UNI(uni, t309);
  120                 sig_all_calls(uni, SIGC_LINK_ESTABLISH_confirm);
  121                 uni->funcs->uni_output(uni, uni->arg,
  122                     UNIAPI_LINK_ESTABLISH_confirm, 0, NULL);
  123                 set_custat(uni, CU_STAT3);
  124                 break;
  125 
  126           case CU_STAT3:
  127                 /*
  128                  * Q.2931:Coord-U 5/10
  129                  */
  130                 sig_all_calls(uni, SIGC_LINK_ESTABLISH_confirm);
  131                 uni->funcs->uni_output(uni, uni->arg,
  132                     UNIAPI_LINK_ESTABLISH_confirm, 0, NULL);
  133                 break;
  134 
  135           default:
  136                 ASSERT(0, ("CU_STAT*"));
  137         }
  138 }
  139 
  140 /*
  141  * SAAL-RELEASE.confirm
  142  */
  143 static void
  144 coord_saal_release_confirm(struct uni *uni)
  145 {
  146         switch (uni->custat) {
  147 
  148           case CU_STAT0:
  149           case CU_STAT1:
  150           case CU_STAT3:
  151                 VERBOSE0(uni, UNI_FAC_COORD,
  152                     "signal saal_release.confirm in CU%u", uni->custat);
  153                 break;
  154 
  155           case CU_STAT2:
  156                 /*
  157                  * Q.2931:Coord-U 5/10
  158                  */
  159                 uni->funcs->uni_output(uni, uni->arg,
  160                     UNIAPI_LINK_RELEASE_confirm, 0, NULL);
  161                 set_custat(uni, CU_STAT0);
  162                 break;
  163 
  164           default:
  165                 ASSERT(0, ("CU_STAT*"));
  166         }
  167 }
  168 
  169 /*
  170  * SAAL failure.
  171  */
  172 static void
  173 coord_saal_release_indication(struct uni *uni)
  174 {
  175         switch (uni->custat) {
  176 
  177           case CU_STAT0:
  178           case CU_STAT2:
  179                 VERBOSE0(uni, UNI_FAC_COORD,
  180                     "signal saal_release.indication in CU%u", uni->custat);
  181                 break;
  182 
  183           case CU_STAT1:
  184           case CU_STAT3:
  185                 /*
  186                  * Q.2931:Coord-U 4/10
  187                  * Q.2931:Coord-U 5/10
  188                  */
  189                 sig_all_calls(uni, SIGC_LINK_RELEASE_indication);
  190                 set_custat(uni, CU_STAT0);
  191                 break;
  192 
  193           default:
  194                 ASSERT(0, ("CU_STAT*"));
  195         }
  196 }
  197 
  198 /*
  199  * Link-establish.request from USER. This can also come from
  200  * a call instance. In this case 'cookie' is zero.
  201  */
  202 static void
  203 coord_link_establish_request(struct uni *uni, uint32_t cookie)
  204 {
  205         switch (uni->custat) {
  206 
  207           case CU_STAT0:
  208                 /*
  209                  * Q.2931:Coord-U 4/10
  210                  */
  211                 uni->funcs->saal_output(uni, uni->arg,
  212                     SAAL_ESTABLISH_request, NULL);
  213                 if (!TIMER_ISACT(uni, t309))
  214                         TIMER_START_UNI(uni, t309, uni->timer309);
  215                 set_custat(uni, CU_STAT1);
  216                 if (cookie)
  217                         uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
  218                 break;
  219 
  220           case CU_STAT1:
  221                 /*
  222                  * Q.2931:Coord-U 4/10
  223                  * This is probably missing from the delay field.
  224                  */
  225                 uni_delenq_coord(uni, SIGO_LINK_ESTABLISH_request,
  226                     cookie, NULL);
  227                 break;
  228 
  229           case CU_STAT2:
  230                 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
  231                 if (cookie == 0)
  232                         VERBOSE0(uni, UNI_FAC_COORD,
  233                             "signal link-establish.request in CU%u",
  234                             uni->custat);
  235                 break;
  236 
  237           case CU_STAT3:
  238                 /*
  239                  * Q.2931:Coord-U 5/10
  240                  */
  241                 uni->funcs->uni_output(uni, uni->arg,
  242                     UNIAPI_LINK_ESTABLISH_confirm, 0, NULL);
  243                 uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
  244                 break;
  245 
  246           default:
  247                 ASSERT(0, ("CU_STAT*"));
  248         }
  249 }
  250 
  251 /*
  252  * Link-release.request from user
  253  */
  254 static void
  255 coord_link_release_request(struct uni *uni, u_int cookie)
  256 {
  257         switch (uni->custat) {
  258 
  259           case CU_STAT0:
  260           case CU_STAT1:
  261           case CU_STAT2:
  262                 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
  263                 break;
  264 
  265           case CU_STAT3:
  266                 /*
  267                  * Q.2931:Coord-U 5/10
  268                  */
  269                 uni->funcs->saal_output(uni, uni->arg,
  270                     SAAL_RELEASE_request, NULL);
  271                 set_custat(uni, CU_STAT2);
  272                 uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
  273                 break;
  274 
  275           default:
  276                 ASSERT(0, ("CU_STAT*"));
  277         }
  278 }
  279 
  280 /*
  281  * T309 timeout signal
  282  */
  283 static void
  284 coord_t309(struct uni *uni)
  285 {
  286         switch (uni->custat) {
  287 
  288           case CU_STAT0:
  289           case CU_STAT1:
  290                 /*
  291                  * Q.2931:Coord-U 4/10
  292                  */
  293                 sig_all_calls(uni, SIGC_LINK_ESTABLISH_ERROR_indication);
  294                 set_custat(uni, CU_STAT0);
  295                 /* this is not in the SDLs, but how will the call control
  296                  * know, that starting the LINK has failed otherwise? */
  297                 uni->funcs->uni_output(uni, uni->arg,
  298                     UNIAPI_LINK_RELEASE_confirm, 0, NULL);
  299                 break;
  300 
  301           case CU_STAT2:
  302           case CU_STAT3:
  303                 VERBOSE0(uni, UNI_FAC_COORD,
  304                     "signal T309 in CU%u", uni->custat);
  305                 break;
  306 
  307           default:
  308                 ASSERT(0, ("CU_STAT*"));
  309         }
  310 }
  311 
  312 /*
  313  * Message from SAAL
  314  */
  315 static void
  316 coord_saal_data_indication(struct uni *uni, struct uni_msg *m)
  317 {
  318         struct uni_all *u;
  319         struct call *c;
  320 
  321         memset(&uni->cause, 0, sizeof(uni->cause));
  322         if ((u = UNI_ALLOC()) == NULL) {
  323                 uni_msg_destroy(m);
  324                 return;
  325         }
  326         if (uni_decode_head(m, u, &uni->cx)) {
  327                 VERBOSE(uni, UNI_FAC_COORD, 2, "bogus message - ignored");
  328                 uni_msg_destroy(m);
  329                 UNI_FREE(u);
  330                 return;
  331         }
  332         if (u->u.hdr.cref.cref == CREF_DUMMY) {
  333                 if (uni->cx.q2932) {
  334                         input_dummy(uni, m, u);
  335                 } else {
  336                         VERBOSE(uni, UNI_FAC_COORD, 2, "dummy cref - ignored");
  337                         UNI_FREE(u);
  338                         uni_msg_destroy(m);
  339                 }
  340                 return;
  341         }
  342 
  343         if (u->u.hdr.cref.cref == CREF_GLOBAL)
  344                 input_global(uni, m, u);
  345         else if ((c = uni_find_call(uni, &u->u.hdr.cref)) == NULL)
  346                 input_unknown(uni, m, u);
  347         else if (c->type == CALL_COBI)
  348                 input_cobi(c, m, u);
  349         else
  350                 input_call(c, m, u);
  351 }
  352 
  353 /*
  354  * Message with global call reference
  355  *
  356  * Q.2931:Coord-U (X) 7/10
  357  */
  358 static void
  359 input_global(struct uni *uni, struct uni_msg *m, struct uni_all *u)
  360 {
  361         VERBOSE(uni, UNI_FAC_COORD, 2, "GLOB MTYPE = %x", u->mtype);
  362 
  363         switch (u->mtype) {
  364 
  365           default:
  366                 /*
  367                  * Q.2931:Coord-U 7/10
  368                  * Q.2931: 5.6.3.2e
  369                  * Amd4:   29e
  370                  */
  371                 uni_respond_status(uni, &u->u.hdr.cref,
  372                     u->u.hdr.cref.flag ? uni->glob_start : uni->glob_respond,
  373                     UNI_CAUSE_CREF_INV);
  374                 break;
  375 
  376           case UNI_RESTART:
  377                 if (u->u.hdr.cref.flag) {
  378                         /*
  379                          * Q.2931:Coord-U 7/10 (5.6.3.2h)
  380                          */
  381                         uni_respond_status(uni, &u->u.hdr.cref,
  382                             uni->glob_start, UNI_CAUSE_CREF_INV);
  383                         break;
  384                 }
  385                 uni_enq_resp(uni, SIGR_RESTART, 0, m, u);
  386                 return;
  387 
  388           case UNI_RESTART_ACK:
  389                 if (!u->u.hdr.cref.flag) {
  390                         /*
  391                          * Q.2931:Coord-U 7/10 (5.6.3.2h)
  392                          * Note, that the SDL diagram contains an error.
  393                          * The error with the 'YES' label should go to the
  394                          * box below 'OTHER'.
  395                          */
  396                         uni_respond_status(uni, &u->u.hdr.cref,
  397                             uni->glob_respond, UNI_CAUSE_CREF_INV);
  398                         break;
  399                 }
  400                 uni_enq_start(uni, SIGS_RESTART_ACK, 0, m, u);
  401                 return;
  402 
  403           case UNI_STATUS:
  404                 if (u->u.hdr.cref.flag)
  405                         uni_enq_start(uni, SIGS_STATUS, 0, m, u);
  406                 else
  407                         uni_enq_resp(uni, SIGR_STATUS, 0, m, u);
  408                 return;
  409         }
  410         uni_msg_destroy(m);
  411         UNI_FREE(u);
  412 }
  413 
  414 /*
  415  * Q.2931:Coord-U 8/10
  416  *
  417  * Message for an unknown call reference
  418  */
  419 static void
  420 input_unknown(struct uni *uni, struct uni_msg *m, struct uni_all *u)
  421 {
  422         struct uni_all *resp;
  423         struct call *c;
  424         u_int cause = UNI_CAUSE_CREF_INV;
  425 
  426         VERBOSE(uni, UNI_FAC_COORD, 2, "UNKNOWN MTYPE = %x", u->mtype);
  427 
  428         switch (u->mtype) {
  429 
  430           default:
  431                 /*
  432                  * This message type is entirly unknown
  433                  *
  434                  * 5.6.4 and 5.7.1 are only when the call is not in the
  435                  * NULL state. This means, 5.6.3.2a takes over.
  436                  */
  437                 break;
  438 
  439           case UNI_SETUP:
  440                 if (u->u.hdr.cref.flag)
  441                         /*
  442                          * 5.6.3.2c
  443                          */
  444                         goto drop;
  445                 if ((c = uni_create_call(uni, u->u.hdr.cref.cref, 0, 0)) != NULL) {
  446                         uni_enq_call(c, SIGC_SETUP, 0, m, u);
  447                         return;
  448                 }
  449                 goto drop;
  450 
  451           case UNI_RELEASE_COMPL:
  452                 /*
  453                  * 5.6.3.2c
  454                  */
  455                 goto drop;
  456 
  457           case UNI_STATUS:
  458                 /*
  459                  * 5.6.12
  460                  *
  461                  * The SDLs don't use the verify procedure and don't
  462                  * handle the case of an invalid callstate - we
  463                  * ignore the message, if the callstate is not good.
  464                  */
  465                 (void)uni_decode_body(m, u, &uni->cx);
  466                 if (!IE_ISGOOD(u->u.status.callstate))
  467                         goto drop;
  468                 if (u->u.status.callstate.state == UNI_CALLSTATE_U0)
  469                         goto drop;
  470                 cause = UNI_CAUSE_MSG_INCOMP;
  471                 break;
  472 
  473           case UNI_STATUS_ENQ:
  474                 if ((resp = UNI_ALLOC()) == NULL)
  475                         goto drop;
  476 
  477                 (void)uni_decode_body(m, u, &uni->cx);
  478                 MK_MSG_RESP(resp, UNI_STATUS, &u->u.hdr.cref);
  479                 MK_IE_CALLSTATE(resp->u.status.callstate, UNI_CALLSTATE_U0);
  480                 MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER,
  481                     UNI_CAUSE_STATUS);
  482 
  483                 if (IE_ISGOOD(u->u.status_enq.epref)) {
  484                         /* reflect epref as required by L3MU_PO */
  485                         resp->u.status.epref = u->u.status_enq.epref;
  486                         MK_IE_EPREF(resp->u.status.epref,
  487                             u->u.status_enq.epref.epref,
  488                             !u->u.status_enq.epref.flag);
  489                         MK_IE_EPSTATE(resp->u.status.epstate, UNI_EPSTATE_NULL);
  490                 }
  491 
  492                 (void)uni_send_output(resp, uni);
  493 
  494                 UNI_FREE(resp);
  495                 goto drop;
  496 
  497           case UNI_COBISETUP:
  498                 if (u->u.hdr.cref.flag)
  499                         /*
  500                          * 5.6.3.2c (probably)
  501                          */
  502                         goto drop;
  503                 if ((c = uni_create_call(uni, u->u.hdr.cref.cref, 0, 0)) != NULL) {
  504                         uni_enq_call(c, SIGC_COBISETUP, 0, m, u);
  505                         return;
  506                 }
  507                 goto drop;
  508         }
  509 
  510         /*
  511          * 5.6.3.2a)
  512          *
  513          * Respond with a RELEASE COMPLETE
  514          */
  515         if ((resp = UNI_ALLOC()) == NULL)
  516                 goto drop;
  517 
  518         MK_MSG_RESP(resp, UNI_RELEASE_COMPL, &u->u.hdr.cref);
  519         MK_IE_CAUSE(resp->u.release_compl.cause[0], UNI_CAUSE_LOC_USER, cause);
  520         if (uni_diag(cause, UNI_CODING_ITU) == UNI_DIAG_MTYPE)
  521                 ADD_CAUSE_MTYPE(resp->u.release_compl.cause[0], u->mtype);
  522 
  523         (void)uni_send_output(resp, uni);
  524 
  525         UNI_FREE(resp);
  526 
  527   drop:
  528         UNI_FREE(u);
  529         uni_msg_destroy(m);
  530 }
  531 
  532 static void
  533 input_cobi(struct call *c __unused, struct uni_msg *m, struct uni_all *u)
  534 {
  535         /* XXX */
  536         UNI_FREE(u);
  537         uni_msg_destroy(m);
  538 }
  539 
  540 static void
  541 input_dummy(struct uni *uni __unused, struct uni_msg *m, struct uni_all *u)
  542 {
  543         /* XXX */
  544         UNI_FREE(u);
  545         uni_msg_destroy(m);
  546 }
  547 
  548 static void
  549 input_call(struct call *c, struct uni_msg *m, struct uni_all *u)
  550 {
  551         VERBOSE(c->uni, UNI_FAC_COORD, 2, "CALL MTYPE = %x %d/%s", 
  552                 u->mtype, c->cref, c->mine ? "mine":"his");
  553 
  554         switch (u->mtype) {
  555 
  556           case UNI_SETUP:
  557                 /*
  558                  * Ignored
  559                  */
  560                 break;
  561 
  562           case UNI_CALL_PROC:
  563                 uni_enq_call(c, SIGC_CALL_PROC, 0, m, u);
  564                 return;
  565 
  566           case UNI_ALERTING:
  567                 uni_enq_call(c, SIGC_ALERTING, 0, m, u);
  568                 return;
  569 
  570           case UNI_RELEASE:
  571                 uni_enq_call(c, SIGC_RELEASE, 0, m, u);
  572                 return;
  573 
  574           case UNI_RELEASE_COMPL:
  575                 uni_enq_call(c, SIGC_RELEASE_COMPL, 0, m, u);
  576                 return;
  577 
  578           case UNI_CONNECT:
  579                 uni_enq_call(c, SIGC_CONNECT, 0, m, u);
  580                 return;
  581 
  582           case UNI_CONNECT_ACK:
  583                 uni_enq_call(c, SIGC_CONNECT_ACK, 0, m, u);
  584                 return;
  585 
  586           case UNI_NOTIFY:
  587                 uni_enq_call(c, SIGC_NOTIFY, 0, m, u);
  588                 return;
  589 
  590           case UNI_STATUS:
  591                 uni_enq_call(c, SIGC_STATUS, 0, m, u);
  592                 return;
  593 
  594           case UNI_STATUS_ENQ:
  595                 uni_enq_call(c, SIGC_STATUS_ENQ, 0, m, u);
  596                 return;
  597 
  598           case UNI_ADD_PARTY:
  599                 uni_enq_call(c, SIGC_ADD_PARTY, 0, m, u);
  600                 return;
  601 
  602           case UNI_PARTY_ALERTING:
  603                 uni_enq_call(c, SIGC_PARTY_ALERTING, 0, m, u);
  604                 return;
  605 
  606           case UNI_ADD_PARTY_ACK:
  607                 uni_enq_call(c, SIGC_ADD_PARTY_ACK, 0, m, u);
  608                 return;
  609 
  610           case UNI_ADD_PARTY_REJ:
  611                 uni_enq_call(c, SIGC_ADD_PARTY_REJ, 0, m, u);
  612                 return;
  613 
  614           case UNI_DROP_PARTY:
  615                 uni_enq_call(c, SIGC_DROP_PARTY, 0, m, u);
  616                 return;
  617 
  618           case UNI_DROP_PARTY_ACK:
  619                 uni_enq_call(c, SIGC_DROP_PARTY_ACK, 0, m, u);
  620                 return;
  621 
  622           default:
  623                 uni_enq_call(c, SIGC_UNKNOWN, 0, m, u);
  624                 return;
  625         }
  626         UNI_FREE(u);
  627         uni_msg_destroy(m);
  628 }
  629 
  630 
  631 /*
  632  * This macro tries to implement the delaying behaviour for
  633  * message from the API when we are in the Awaiting-Establish state.
  634  * In this state, the message is delayed. If we drop back to CU 0,
  635  * everything gets unqueued and errors are returned for all that stuff.
  636  * If we progess to CUSTAT2 we process the requests.
  637  */
  638 #define COMMON_DELAY(SIG, COOKIE)                                       \
  639                 if (uni->custat == CU_STAT0 || uni->custat == CU_STAT2) {\
  640                         uniapi_uni_error(uni, UNIAPI_ERROR_BADCU,       \
  641                             COOKIE, 0);                                 \
  642                         break;                                          \
  643                 }                                                       \
  644                 if (uni->custat == CU_STAT1) {                          \
  645                         uni_delenq_coord(uni, SIG, COOKIE, msg);        \
  646                         break;                                          \
  647                 }
  648 
  649 /*
  650  * Signal handler of the coordinator
  651  */
  652 void
  653 uni_sig_coord(struct uni *uni, enum coord_sig sig, uint32_t cookie,
  654     struct uni_msg *msg)
  655 {
  656         struct call *c;
  657 
  658         if (sig >= SIGO_END) {
  659                 VERBOSE(uni, UNI_FAC_ERR, 1, "Signal %d outside of range to "
  660                     "Coord", sig);
  661                 if (msg)
  662                         uni_msg_destroy(msg);
  663                 return;
  664         }
  665 
  666         VERBOSE(uni, UNI_FAC_COORD, 1, "Signal %s in state %s",
  667             coord_sigs[sig], cunames[uni->custat]);
  668 
  669         switch (sig) {
  670 
  671           case SIGO_END:
  672                 break;
  673 
  674           case SIGO_DATA:       /* delayed output */
  675                 if (uni->custat == CU_STAT0 || uni->custat == CU_STAT1)
  676                         break;  /* drop */
  677                 if (uni->custat == CU_STAT1)
  678                         uni_delenq_coord(uni, SIGO_DATA, cookie, msg);/* ??? */
  679                 else
  680                         uni->funcs->saal_output(uni, uni->arg,
  681                             SAAL_DATA_request, msg);
  682                 msg = NULL;
  683                 break;
  684 
  685           /*
  686            * SAAL signals
  687            */
  688           case SIGO_SAAL_ESTABLISH_indication:
  689                 coord_saal_establish_indication(uni);
  690                 break;
  691 
  692           case SIGO_SAAL_ESTABLISH_confirm:
  693                 coord_saal_establish_confirm(uni);
  694                 break;
  695 
  696           case SIGO_SAAL_RELEASE_confirm:
  697                 coord_saal_release_confirm(uni);
  698                 break;
  699 
  700           case SIGO_SAAL_RELEASE_indication:
  701                 coord_saal_release_indication(uni);
  702                 break;
  703 
  704           case SIGO_SAAL_DATA_indication:
  705                 coord_saal_data_indication(uni, msg);
  706                 msg = NULL;
  707                 break;
  708 
  709           case SIGO_SAAL_UDATA_indication:
  710                 VERBOSE0(uni, UNI_FAC_ERR, "SAAL_UDATA_indication");
  711                 break;
  712 
  713           /*
  714            * Signals from USER
  715            */
  716           case SIGO_LINK_ESTABLISH_request:
  717                 coord_link_establish_request(uni, cookie);
  718                 break;
  719 
  720           case SIGO_LINK_RELEASE_request:
  721                 coord_link_release_request(uni, cookie);
  722                 break;
  723 
  724           case SIGO_RESET_request:
  725                 uni_enq_start(uni, SIGS_RESET_request, cookie, msg, NULL);
  726                 msg = NULL;
  727                 if (uni->custat == CU_STAT0) {
  728                         uni->funcs->saal_output(uni, uni->arg,
  729                             SAAL_ESTABLISH_request, NULL);
  730                         if (!TIMER_ISACT(uni, t309))
  731                                 TIMER_START_UNI(uni, t309, uni->timer309);
  732                         set_custat(uni, CU_STAT1);
  733                 }
  734                 break;
  735 
  736           case SIGO_RESET_ERROR_response:
  737                 COMMON_DELAY(SIGO_RESET_ERROR_response, cookie);
  738                 uni_enq_resp(uni, SIGR_RESET_ERROR_response, cookie, msg, NULL);
  739                 msg = NULL;
  740                 break;
  741 
  742           case SIGO_RESET_response:
  743                 COMMON_DELAY(SIGO_RESET_response, cookie);
  744                 uni_enq_resp(uni, SIGR_RESET_response, cookie, msg, NULL);
  745                 msg = NULL;
  746                 break;
  747 
  748           case SIGO_SETUP_request:
  749                 if ((c = uni_create_new_call(uni, cookie)) != NULL) {
  750                         uni_enq_call(c, SIGC_SETUP_request, cookie, msg, NULL);
  751                         msg = NULL;
  752                         if (uni->custat == CU_STAT0) {
  753                                 uni->funcs->saal_output(uni, uni->arg,
  754                                     SAAL_ESTABLISH_request, NULL);
  755                                 if (!TIMER_ISACT(uni, t309))
  756                                         TIMER_START_UNI(uni, t309, uni->timer309);
  757                                 set_custat(uni, CU_STAT1);
  758                         }
  759                 } else {
  760                         uniapi_uni_error(uni, UNIAPI_ERROR_NOMEM, cookie,
  761                             UNI_CALLSTATE_U0);
  762                 }
  763                 break;
  764 
  765           case SIGO_PROCEEDING_request:
  766             {
  767                 struct uniapi_proceeding_request *arg =
  768                     uni_msg_rptr(msg, struct uniapi_proceeding_request *);
  769 
  770                 COMMON_DELAY(SIGO_PROCEEDING_request, cookie);
  771                 if ((c = uni_find_call(uni, &arg->call_proc.hdr.cref)) != NULL) {
  772                         uni_enq_call(c, SIGC_PROCEEDING_request, cookie, msg, NULL);
  773                         msg = NULL;
  774                 } else {
  775                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  776                             UNI_CALLSTATE_U0);
  777                 }
  778                 break;
  779             }
  780 
  781           case SIGO_ALERTING_request:
  782             {
  783                 struct uniapi_alerting_request *arg =
  784                     uni_msg_rptr(msg, struct uniapi_alerting_request *);
  785 
  786                 COMMON_DELAY(SIGO_ALERTING_request, cookie);
  787                 if ((c = uni_find_call(uni, &arg->alerting.hdr.cref)) != NULL) {
  788                         uni_enq_call(c, SIGC_ALERTING_request, cookie, msg, NULL);
  789                         msg = NULL;
  790                 } else {
  791                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  792                             UNI_CALLSTATE_U0);
  793                 }
  794                 break;
  795             }
  796 
  797           case SIGO_SETUP_response:
  798             {
  799                 struct uniapi_setup_response *arg =
  800                     uni_msg_rptr(msg, struct uniapi_setup_response *);
  801 
  802                 COMMON_DELAY(SIGO_SETUP_response, cookie);
  803                 if ((c = uni_find_call(uni, &arg->connect.hdr.cref)) != NULL) {
  804                         uni_enq_call(c, SIGC_SETUP_response, cookie, msg, NULL);
  805                         msg = NULL;
  806                 } else {
  807                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  808                             UNI_CALLSTATE_U0);
  809                 }
  810                 break;
  811             }
  812 
  813           case SIGO_SETUP_COMPLETE_request:
  814             {
  815                 struct uniapi_setup_complete_request *arg =
  816                     uni_msg_rptr(msg, struct uniapi_setup_complete_request *);
  817 
  818                 COMMON_DELAY(SIGO_SETUP_COMPLETE_request, cookie);
  819                 if ((c = uni_find_call(uni, &arg->connect_ack.hdr.cref)) != NULL) {
  820                         uni_enq_call(c, SIGC_SETUP_COMPLETE_request,
  821                             cookie, msg, NULL);
  822                         msg = NULL;
  823                 } else {
  824                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  825                             UNI_CALLSTATE_U0);
  826                 }
  827                 break;
  828             }
  829 
  830           case SIGO_RELEASE_request:
  831             {
  832                 struct uniapi_release_request *arg =
  833                     uni_msg_rptr(msg, struct uniapi_release_request *);
  834 
  835                 COMMON_DELAY(SIGO_RELEASE_request, cookie);
  836                 if ((c = uni_find_call(uni, &arg->release.hdr.cref)) != NULL) {
  837                         uni_enq_call(c, SIGC_RELEASE_request, cookie, msg, NULL);
  838                         msg = NULL;
  839                 } else {
  840                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  841                             UNI_CALLSTATE_U0);
  842                 }
  843                 break;
  844             }
  845 
  846           case SIGO_RELEASE_response:
  847             {
  848                 struct uniapi_release_response *arg =
  849                     uni_msg_rptr(msg, struct uniapi_release_response *);
  850 
  851                 COMMON_DELAY(SIGO_RELEASE_response, cookie);
  852                 if ((c = uni_find_call(uni, &arg->release_compl.hdr.cref)) != NULL) {
  853                         uni_enq_call(c, SIGC_RELEASE_response, cookie, msg, NULL);
  854                         msg = NULL;
  855                 } else {
  856                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  857                             UNI_CALLSTATE_U0);
  858                 }
  859                 break;
  860             }
  861 
  862           case SIGO_NOTIFY_request:
  863             {
  864                 struct uniapi_notify_request *arg =
  865                     uni_msg_rptr(msg, struct uniapi_notify_request *);
  866 
  867                 COMMON_DELAY(SIGO_NOTIFY_request, cookie);
  868                 if ((c = uni_find_call(uni, &arg->notify.hdr.cref)) != NULL) {
  869                         uni_enq_call(c, SIGC_NOTIFY_request, cookie, msg, NULL);
  870                         msg = NULL;
  871                 } else {
  872                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  873                             UNI_CALLSTATE_U0);
  874                 }
  875                 break;
  876             }
  877 
  878           case SIGO_STATUS_ENQUIRY_request:
  879             {
  880                 struct uniapi_status_enquiry_request *arg =
  881                     uni_msg_rptr(msg, struct uniapi_status_enquiry_request *);
  882 
  883                 COMMON_DELAY(SIGO_STATUS_ENQUIRY_request, cookie);
  884                 if ((c = uni_find_call(uni, &arg->cref)) != NULL) {
  885                         uni_enq_call(c, SIGC_STATUS_ENQUIRY_request, cookie, msg, NULL);
  886                         msg = NULL;
  887                 } else {
  888                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  889                             UNI_CALLSTATE_U0);
  890                 }
  891                 break;
  892             }
  893 
  894           case SIGO_ADD_PARTY_request:
  895             {
  896                 struct uniapi_add_party_request *arg =
  897                     uni_msg_rptr(msg, struct uniapi_add_party_request *);
  898 
  899                 COMMON_DELAY(SIGO_ADD_PARTY_request, cookie);
  900                 if ((c = uni_find_call(uni, &arg->add.hdr.cref)) != NULL) {
  901                         if (c->type != CALL_ROOT) {
  902                                 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
  903                                     cookie);
  904                                 break;
  905                         }
  906                         uni_enq_call(c, SIGC_ADD_PARTY_request, cookie, msg, NULL);
  907                         msg = NULL;
  908                 } else {
  909                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  910                             UNI_CALLSTATE_U0);
  911                 }
  912                 break;
  913             }
  914 
  915           case SIGO_PARTY_ALERTING_request:
  916             {
  917                 struct uniapi_party_alerting_request *arg =
  918                     uni_msg_rptr(msg, struct uniapi_party_alerting_request *);
  919 
  920                 COMMON_DELAY(SIGO_PARTY_ALERTING_request, cookie);
  921                 if ((c = uni_find_call(uni, &arg->alert.hdr.cref)) != NULL) {
  922                         if (c->type != CALL_LEAF) {
  923                                 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
  924                                     cookie);
  925                                 break;
  926                         }
  927                         uni_enq_call(c, SIGC_PARTY_ALERTING_request, cookie, msg, NULL);
  928                         msg = NULL;
  929                 } else {
  930                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  931                             UNI_CALLSTATE_U0);
  932                 }
  933                 break;
  934             }
  935 
  936           case SIGO_ADD_PARTY_ACK_request:
  937             {
  938                 struct uniapi_add_party_ack_request *arg =
  939                     uni_msg_rptr(msg, struct uniapi_add_party_ack_request *);
  940 
  941                 COMMON_DELAY(SIGO_ADD_PARTY_ACK_request, cookie);
  942                 if ((c = uni_find_call(uni, &arg->ack.hdr.cref)) != NULL) {
  943                         if (c->type != CALL_LEAF) {
  944                                 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
  945                                     cookie);
  946                                 break;
  947                         }
  948                         uni_enq_call(c, SIGC_ADD_PARTY_ACK_request, cookie, msg, NULL);
  949                         msg = NULL;
  950                 } else {
  951                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  952                             UNI_CALLSTATE_U0);
  953                 }
  954                 break;
  955             }
  956 
  957           case SIGO_ADD_PARTY_REJ_request:
  958             {
  959                 struct uniapi_add_party_rej_request *arg =
  960                     uni_msg_rptr(msg, struct uniapi_add_party_rej_request *);
  961 
  962                 COMMON_DELAY(SIGO_ADD_PARTY_REJ_request, cookie);
  963                 if ((c = uni_find_call(uni, &arg->rej.hdr.cref)) != NULL) {
  964                         if (c->type != CALL_LEAF) {
  965                                 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
  966                                     cookie);
  967                                 break;
  968                         }
  969                         uni_enq_call(c, SIGC_ADD_PARTY_REJ_request, cookie, msg, NULL);
  970                         msg = NULL;
  971                 } else {
  972                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  973                             UNI_CALLSTATE_U0);
  974                 }
  975                 break;
  976             }
  977 
  978           case SIGO_DROP_PARTY_request:
  979             {
  980                 struct uniapi_drop_party_request *arg =
  981                     uni_msg_rptr(msg, struct uniapi_drop_party_request *);
  982 
  983                 COMMON_DELAY(SIGO_DROP_PARTY_request, cookie);
  984                 if ((c = uni_find_call(uni, &arg->drop.hdr.cref)) != NULL) {
  985                         if (c->type != CALL_ROOT && c->type != CALL_LEAF) {
  986                                 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
  987                                     cookie);
  988                                 break;
  989                         }
  990                         uni_enq_call(c, SIGC_DROP_PARTY_request, cookie, msg, NULL);
  991                         msg = NULL;
  992                 } else {
  993                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
  994                             UNI_CALLSTATE_U0);
  995                 }
  996                 break;
  997             }
  998 
  999           case SIGO_DROP_PARTY_ACK_request:
 1000             {
 1001                 struct uniapi_drop_party_ack_request *arg =
 1002                     uni_msg_rptr(msg, struct uniapi_drop_party_ack_request *);
 1003 
 1004                 COMMON_DELAY(SIGO_DROP_PARTY_ACK_request, cookie);
 1005                 if ((c = uni_find_call(uni, &arg->ack.hdr.cref)) != NULL) {
 1006                         if (c->type != CALL_ROOT && c->type != CALL_LEAF) {
 1007                                 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
 1008                                     cookie);
 1009                                 break;
 1010                         }
 1011                         uni_enq_call(c, SIGC_DROP_PARTY_ACK_request, cookie, msg, NULL);
 1012                         msg = NULL;
 1013                 } else {
 1014                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
 1015                             UNI_CALLSTATE_U0);
 1016                 }
 1017                 break;
 1018             }
 1019 
 1020           case SIGO_ABORT_CALL_request:
 1021             {
 1022                 struct uniapi_abort_call_request *arg = 
 1023                     uni_msg_rptr(msg, struct uniapi_abort_call_request *);
 1024 
 1025                 if ((c = uni_find_call(uni, &arg->cref)) != NULL) {
 1026                         uni_enq_call(c, SIGC_ABORT_CALL_request, cookie, NULL, NULL);
 1027                 } else {
 1028                         uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
 1029                             UNI_CALLSTATE_U0);
 1030                 }
 1031                 break;
 1032             }
 1033 
 1034           /*
 1035            * Call-Control
 1036            */
 1037           case SIGO_CALL_DESTROYED:
 1038                 uni->funcs->uni_output(uni, uni->arg,
 1039                     UNIAPI_CALL_DESTROYED, 0, msg);
 1040                 msg = NULL;
 1041                 break;
 1042 
 1043           /*
 1044            * ResetRespond
 1045            */
 1046           case SIGO_RESET_indication:
 1047                 uni->funcs->uni_output(uni, uni->arg,
 1048                     UNIAPI_RESET_indication, 0, msg);
 1049                 msg = NULL;
 1050                 break;
 1051 
 1052           /*
 1053            * Timeouts
 1054            */
 1055           case SIGO_T309:
 1056                 coord_t309(uni);
 1057                 break;
 1058 
 1059         }
 1060         if (msg != NULL)
 1061                 uni_msg_destroy(msg);
 1062 }
 1063 
 1064 /*
 1065  * Send a signal to all call instances
 1066  */
 1067 static void
 1068 sig_all_calls(struct uni *uni, u_int sig)
 1069 {
 1070         struct call *call;
 1071 
 1072         TAILQ_FOREACH(call, &uni->calls, link)
 1073                 uni_enq_call(call, sig, 0, NULL, NULL);
 1074 }
 1075 
 1076 /*
 1077  * Set a new coordinator state - this moves all delayed coordinator
 1078  * signals from the delayed queue to the signal queue.
 1079  */
 1080 static int
 1081 cufilt(struct sig *s, void *arg __unused)
 1082 {
 1083         return (s->type == SIG_COORD);
 1084 }
 1085 
 1086 static void
 1087 set_custat(struct uni *uni, enum cu_stat nstate)
 1088 {
 1089         if (uni->custat != nstate) {
 1090                 uni->custat = nstate;
 1091                 uni_undel(uni, cufilt, NULL);
 1092         }
 1093 }
 1094 
 1095 /*
 1096  * T309 timeout function
 1097  */
 1098 static void
 1099 t309_func(struct uni *uni)
 1100 {
 1101         uni_enq_coord(uni, SIGO_T309, 0, NULL);
 1102 }
 1103 
 1104 /*
 1105  * Respond with a status message
 1106  */
 1107 void
 1108 uni_respond_status(struct uni *uni, struct uni_cref *cref,
 1109     enum uni_callstate cs, enum uni_cause c1)
 1110 {
 1111         struct uni_all *resp;
 1112 
 1113         if ((resp = UNI_ALLOC()) == NULL)
 1114                 return;
 1115 
 1116         MK_MSG_RESP(resp, UNI_STATUS, cref);
 1117         MK_IE_CALLSTATE(resp->u.status.callstate, cs);
 1118         MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, c1);
 1119 
 1120         (void)uni_send_output(resp, uni);
 1121 
 1122         UNI_FREE(resp);
 1123 }
 1124 
 1125 /*
 1126  * Respond with a status message
 1127  */
 1128 void
 1129 uni_respond_status_mtype(struct uni *uni, struct uni_cref *cref,
 1130     enum uni_callstate cs, enum uni_cause c1, u_int mtype)
 1131 {
 1132         struct uni_all *resp;
 1133 
 1134         if((resp = UNI_ALLOC()) == NULL)
 1135                 return;
 1136 
 1137         MK_MSG_RESP(resp, UNI_STATUS, cref);
 1138         MK_IE_CALLSTATE(resp->u.status.callstate, cs);
 1139         MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, c1);
 1140         ADD_CAUSE_MTYPE(resp->u.status.cause, mtype);
 1141 
 1142         (void)uni_send_output(resp, uni);
 1143 
 1144         UNI_FREE(resp);
 1145 }
 1146 
 1147 /*
 1148  * Send a message. If we are in CUSTAT1, delay the message if we
 1149  * are in CUSTAT3 send it, else drop it.
 1150  */
 1151 int
 1152 uni_send_output(struct uni_all *u, struct uni *uni)
 1153 {
 1154         struct uni_msg *m;
 1155         int err;
 1156 
 1157         if (uni->custat == CU_STAT0 || uni->custat == CU_STAT2)
 1158                 return (0);
 1159 
 1160         m = uni_msg_alloc(1024);
 1161         if ((err = uni_encode(m, u, &uni->cx)) != 0) {
 1162                 VERBOSE0(uni, UNI_FAC_ERR, "uni_encode failed: %08x", err);
 1163                 uni_msg_destroy(m);
 1164                 return (-1);
 1165         }
 1166         if (uni->custat == CU_STAT1)
 1167                 uni_delenq_coord(uni, SIGO_DATA, 0, m);
 1168         else
 1169                 uni->funcs->saal_output(uni, uni->arg, SAAL_DATA_request, m);
 1170         return (0);
 1171 }

Cache object: 0c90efc0fae84bc54f773ee4a8ac4a68


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.