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/netisdn/i4b_capi_msgs.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 /*      $NetBSD: i4b_capi_msgs.c,v 1.5 2003/10/28 17:02:54 pooka Exp $  */
    2 
    3 /*
    4  * Copyright (c) 2001-2003 Cubical Solutions Ltd. 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  * capi/capi_msgs.c     The CAPI i4b message handlers.
   28  *
   29  * $FreeBSD: src/sys/i4b/capi/capi_msgs.c,v 1.2 2001/10/21 08:51:54 hm Exp $
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: i4b_capi_msgs.c,v 1.5 2003/10/28 17:02:54 pooka Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/kernel.h>
   37 #include <sys/systm.h>
   38 #include <sys/mbuf.h>
   39 #include <sys/socket.h>
   40 #include <sys/callout.h>
   41 #include <net/if.h>
   42 
   43 #include <netisdn/i4b_debug.h>
   44 #include <netisdn/i4b_ioctl.h>
   45 #include <netisdn/i4b_cause.h>
   46 #include <netisdn/i4b_l3l4.h>
   47 #include <netisdn/i4b_mbuf.h>
   48 #include <netisdn/i4b_global.h>
   49 #include <netisdn/i4b_l4.h>
   50 #include <netisdn/i4b_capi.h>
   51 #include <netisdn/i4b_capi_msgs.h>
   52 
   53 /*
   54 //  Administrative messages:
   55 //  ------------------------
   56 */
   57 
   58 void capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
   59 {
   60     struct mbuf *m = i4b_Dgetmbuf(8 + 18);
   61     u_int8_t *msg;
   62     u_int16_t msgid;
   63 
   64     if (!m) {
   65         printf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
   66         return;
   67     }
   68 
   69     msgid = sc->sc_msgid++;
   70 
   71     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
   72     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
   73     msg = capimsg_setu16(msg, CAPI_LISTEN_REQ);
   74     msg = capimsg_setu16(msg, msgid);
   75 
   76     msg = capimsg_setu32(msg, sc->sc_unit + 1); /* Controller */
   77     msg = capimsg_setu32(msg, 0); /* Info mask */
   78     msg = capimsg_setu32(msg, CIP);
   79     msg = capimsg_setu32(msg, 0);
   80     msg = capimsg_setu8(msg, 0);
   81     msg = capimsg_setu8(msg, 0);
   82 
   83     sc->send(sc, m);
   84 }
   85 
   86 void capi_listen_conf(capi_softc_t *sc, struct mbuf *m_in)
   87 {
   88     struct isdn_l3_driver *l3drv;
   89     u_int8_t *msg = mtod(m_in, u_int8_t*);
   90     u_int16_t Info;
   91 
   92     capimsg_getu16(msg + 12, &Info);
   93 
   94     if (Info == 0) {
   95         /* We are now listening. */
   96 
   97         sc->sc_state = C_UP;
   98         l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
   99         l3drv->dl_est = DL_UP;
  100 
  101         i4b_l4_l12stat(l3drv, 1, 1);
  102         i4b_l4_l12stat(l3drv, 2, 1);
  103 
  104     } else {
  105         /* XXX sc->sc_state = C_DOWN ? XXX */
  106         printf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
  107     }
  108 }
  109 
  110 void capi_info_ind(capi_softc_t *sc, struct mbuf *m_in)
  111 {
  112     struct mbuf *m = i4b_Dgetmbuf(8 + 4);
  113     u_int8_t *msg = mtod(m_in, u_int8_t*);
  114     u_int16_t applid, msgid;
  115     u_int32_t PLCI;
  116 
  117     if (!m) {
  118         printf("capi%d: can't get mbuf for info_resp\n", sc->sc_unit);
  119         return;
  120     }
  121 
  122     msg = capimsg_getu16(msg + 2, &applid);
  123     msg = capimsg_getu16(msg + 2, &msgid);
  124     msg = capimsg_getu32(msg, &PLCI);
  125 
  126     /* i4b_l4_info_ind() */
  127     
  128     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  129     msg = capimsg_setu16(msg, applid);
  130     msg = capimsg_setu16(msg, CAPI_INFO_RESP);
  131     msg = capimsg_setu16(msg, msgid);
  132 
  133     msg = capimsg_setu32(msg, PLCI);
  134 
  135     sc->send(sc, m);
  136 }
  137 
  138 void capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
  139 {
  140     struct mbuf *m = i4b_Dgetmbuf(8 + 5);
  141     u_int8_t *msg;
  142     u_int16_t msgid;
  143     u_int32_t PLCI;
  144 
  145     if (!m) {
  146         printf("capi%d: can't get mbuf for alert_req\n", sc->sc_unit);
  147         return;
  148     }
  149 
  150     msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
  151     PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
  152 
  153     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  154     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  155     msg = capimsg_setu16(msg, CAPI_ALERT_REQ);
  156     msg = capimsg_setu16(msg, msgid);
  157 
  158     msg = capimsg_setu32(msg, PLCI);
  159     msg = capimsg_setu8(msg, 0);
  160 
  161     sc->send(sc, m);
  162 }
  163 
  164 void capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
  165 {
  166     u_int8_t *msg = mtod(m_in, u_int8_t*);
  167     u_int16_t Info;
  168 
  169     msg = capimsg_getu16(msg + 12, &Info);
  170 
  171     if (Info) {
  172         printf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
  173     }
  174 }
  175 
  176 /*
  177 //  Outgoing call setup:
  178 //  --------------------
  179 //
  180 //             CAPI_CONNECT_REQ -->
  181 //                              <-- CAPI_CONNECT_CONF
  182 //                       (notify Layer 4)
  183 //                              <-- CAPI_CONNECT_ACTIVE_IND
  184 //     CAPI_CONNECT_ACTIVE_RESP -->
  185 //          CAPI_CONNECT_B3_REQ -->
  186 //                              <-- CAPI_CONNECT_B3_CONF
  187 //                              <-- CAPI_CONNECT_B3_ACTIVE_IND
  188 //  CAPI_CONNECT_B3_ACTIVE_RESP -->
  189 //                       (notify Layer 4)
  190 */
  191 
  192 void capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
  193 {
  194     struct isdn_l3_driver *l3drv;
  195     struct mbuf *m;
  196     u_int8_t *msg;
  197     u_int16_t msgid;
  198     int slen = strlen(cd->src_telno);
  199     int dlen = strlen(cd->dst_telno);
  200 
  201     m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
  202     if (!m) {
  203         printf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
  204         return;
  205     }
  206 
  207     l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  208 
  209     cd->crflag = CRF_ORIG;
  210 
  211     sc->sc_bchan[cd->channelid].cdid = cd->cdid;
  212     sc->sc_bchan[cd->channelid].bprot = cd->bprot;
  213     sc->sc_bchan[cd->channelid].state = B_CONNECT_CONF;
  214     msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
  215     l3drv->bch_state[cd->channelid] = BCH_ST_RSVD;
  216 
  217     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  218     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  219     msg = capimsg_setu16(msg, CAPI_CONNECT_REQ);
  220     msg = capimsg_setu16(msg, msgid);
  221 
  222     msg = capimsg_setu32(msg, sc->sc_unit + 1); /* Controller */
  223 
  224     switch (cd->bprot) {
  225     case BPROT_NONE:
  226         msg = capimsg_setu16(msg, 0x0010); /* Telephony */
  227         break;
  228 
  229     case BPROT_RHDLC:
  230         msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
  231         break;
  232 
  233     default:
  234         msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
  235     }
  236 
  237     msg = capimsg_setu8(msg, 1 + dlen);
  238     msg = capimsg_setu8(msg, 0x80);
  239     strncpy(msg, cd->dst_telno, dlen);
  240 
  241     msg = capimsg_setu8(msg + dlen, 2 + slen);
  242     msg = capimsg_setu8(msg, 0x00);
  243     msg = capimsg_setu8(msg, 0x80); /* Presentation and screening indicator */
  244     strncpy(msg, cd->src_telno, slen);
  245 
  246     msg = capimsg_setu8(msg + slen, 0); /* Called & */
  247     msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
  248     
  249     msg = capimsg_setu8(msg, 15); /* B protocol */
  250     if (cd->bprot == BPROT_NONE)
  251         msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
  252     else
  253         msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
  254     msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
  255     msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
  256     msg = capimsg_setu8(msg, 0); /* B1 parameters */
  257     msg = capimsg_setu8(msg, 0); /* B2 parameters */
  258     msg = capimsg_setu8(msg, 0); /* B3 parameters */
  259 
  260     msg = capimsg_setu8(msg, 0); /* Bearer Capability */
  261     msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
  262     msg = capimsg_setu8(msg, 0); /* High Layer Compatibility */
  263     msg = capimsg_setu8(msg, 0); /* Additional Info */
  264 
  265     sc->send(sc, m);
  266 }
  267 
  268 void capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
  269 {
  270     u_int8_t *msg = mtod(m_in, u_int8_t*);
  271     call_desc_t *cd;
  272     u_int16_t msgid;
  273     u_int32_t PLCI;
  274     u_int16_t Info;
  275     int bch;
  276 
  277     msg = capimsg_getu16(msg + 6, &msgid);
  278     msg = capimsg_getu32(msg, &PLCI);
  279     msg = capimsg_getu16(msg, &Info);
  280 
  281     for (bch = 0; bch < sc->sc_nbch; bch++)
  282         if ((sc->sc_bchan[bch].state == B_CONNECT_CONF) &&
  283             (sc->sc_bchan[bch].msgid == msgid))
  284             break;
  285 
  286     if ((bch == sc->sc_nbch) ||
  287         (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
  288         printf("capi%d: can't find channel for connect_conf PLCI %x\n",
  289                sc->sc_unit, PLCI);
  290         return;
  291     }
  292 
  293     if (Info == 0) {
  294         sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
  295         sc->sc_bchan[bch].ncci = PLCI;
  296 
  297         i4b_l4_proceeding_ind(cd);
  298 
  299     } else {
  300         struct isdn_l3_driver *l3drv;
  301 
  302         l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  303         SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
  304         i4b_l4_disconnect_ind(cd);
  305         freecd_by_cd(cd);
  306 
  307         sc->sc_bchan[bch].state = B_FREE;
  308 
  309         l3drv->bch_state[bch] = BCH_ST_FREE;
  310 
  311         printf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
  312     }
  313 }
  314 
  315 void capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
  316 {
  317     struct mbuf *m = i4b_Dgetmbuf(8 + 4);
  318     u_int8_t *msg = mtod(m_in, u_int8_t*);
  319     call_desc_t *cd;
  320     u_int16_t applid, msgid;
  321     u_int32_t PLCI;
  322     int bch;
  323 
  324     if (!m) {
  325         printf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
  326         return;
  327     }
  328 
  329     msg = capimsg_getu16(msg + 2, &applid);
  330     msg = capimsg_getu16(msg + 2, &msgid);
  331     msg = capimsg_getu32(msg, &PLCI);
  332 
  333     for (bch = 0; bch < sc->sc_nbch; bch++)
  334         if ((sc->sc_bchan[bch].state == B_CONNECT_ACTIVE_IND) &&
  335             (sc->sc_bchan[bch].ncci == PLCI))
  336             break;
  337 
  338     if ((bch == sc->sc_nbch) ||
  339         (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
  340         printf("capi%d: can't find channel for active_resp, PLCI %x\n",
  341                sc->sc_unit, PLCI);
  342         return;
  343     }
  344 
  345     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  346     msg = capimsg_setu16(msg, applid);
  347     msg = capimsg_setu16(msg, CAPI_CONNECT_ACTIVE_RESP);
  348     msg = capimsg_setu16(msg, msgid);
  349 
  350     msg = capimsg_setu32(msg, PLCI);
  351 
  352     sc->send(sc, m);
  353 
  354     if (cd->crflag == CRF_ORIG) {
  355         capi_connect_b3_req(sc, cd);
  356 
  357     } else {
  358         sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
  359     }
  360 }
  361 
  362 void capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
  363 {
  364     struct mbuf *m = i4b_Dgetmbuf(8 + 5);
  365     u_int8_t *msg;
  366     u_int16_t msgid;
  367     u_int32_t PLCI;
  368 
  369     if (!m) {
  370         printf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
  371         return;
  372     }
  373 
  374     sc->sc_bchan[cd->channelid].state = B_CONNECT_B3_CONF;
  375     msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
  376     PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
  377 
  378     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  379     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  380     msg = capimsg_setu16(msg, CAPI_CONNECT_B3_REQ);
  381     msg = capimsg_setu16(msg, msgid);
  382 
  383     msg = capimsg_setu32(msg, PLCI);
  384     msg = capimsg_setu8(msg, 0); /* NCPI */
  385 
  386     sc->send(sc, m);
  387 }
  388 
  389 void capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
  390 {
  391     u_int8_t *msg = mtod(m_in, u_int8_t*);
  392     call_desc_t *cd;
  393     u_int16_t msgid;
  394     u_int32_t NCCI;
  395     u_int16_t Info;
  396     int bch;
  397 
  398     msg = capimsg_getu16(msg + 6, &msgid);
  399     msg = capimsg_getu32(msg, &NCCI);
  400     msg = capimsg_getu16(msg, &Info);
  401 
  402     for (bch = 0; bch < sc->sc_nbch; bch++)
  403         if ((sc->sc_bchan[bch].state == B_CONNECT_B3_CONF) &&
  404             (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
  405             break;
  406 
  407     if ((bch == sc->sc_nbch) ||
  408         (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
  409         printf("capi%d: can't find channel for connect_b3_conf NCCI %x\n",
  410                sc->sc_unit, NCCI);
  411         return;
  412     }
  413 
  414     if (Info == 0) {
  415         sc->sc_bchan[bch].ncci = NCCI;
  416         sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
  417 
  418     } else {
  419         struct isdn_l3_driver *l3drv;
  420 
  421         l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  422 
  423         SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
  424         i4b_l4_disconnect_ind(cd);
  425         freecd_by_cd(cd);
  426 
  427         l3drv->bch_state[bch] = BCH_ST_RSVD;
  428 
  429         printf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
  430 
  431         capi_disconnect_req(sc, cd);
  432     }
  433 }
  434 
  435 void capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
  436 {
  437     struct mbuf *m = i4b_Dgetmbuf(8 + 4);
  438     u_int8_t *msg = mtod(m_in, u_int8_t*);
  439     call_desc_t *cd;
  440     u_int16_t applid, msgid;
  441     u_int32_t NCCI;
  442     int bch;
  443 
  444     if (!m) {
  445         printf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
  446         return;
  447     }
  448 
  449     msg = capimsg_getu16(msg + 2, &applid);
  450     msg = capimsg_getu16(msg + 2, &msgid);
  451     msg = capimsg_getu32(msg, &NCCI);
  452 
  453     for (bch = 0; bch < sc->sc_nbch; bch++)
  454         if ((sc->sc_bchan[bch].state == B_CONNECT_B3_ACTIVE_IND) &&
  455             (sc->sc_bchan[bch].ncci == NCCI))
  456             break;
  457 
  458     if ((bch == sc->sc_nbch) ||
  459         (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
  460         printf("capi%d: can't find channel for b3_active_resp NCCI %x\n",
  461                sc->sc_unit, NCCI);
  462         return;
  463     }
  464 
  465     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  466     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  467     msg = capimsg_setu16(msg, CAPI_CONNECT_B3_ACTIVE_RESP);
  468     msg = capimsg_setu16(msg, msgid);
  469 
  470     msg = capimsg_setu32(msg, NCCI);
  471 
  472     sc->send(sc, m);
  473 
  474     sc->sc_bchan[bch].state = B_CONNECTED;
  475 
  476     i4b_l4_connect_active_ind(cd);
  477 }
  478 
  479 /*
  480 //  Incoming call setup:
  481 //  --------------------
  482 //
  483 //                              <-- CAPI_CONNECT_IND
  484 //                       (consult Layer 4)
  485 //            CAPI_CONNECT_RESP -->
  486 //                              <-- CAPI_CONNECT_ACTIVE_IND
  487 //     CAPI_CONNECT_ACTIVE_RESP -->
  488 //                              <-- CAPI_CONNECT_B3_IND
  489 //         CAPI_CONNECT_B3_RESP -->
  490 //                              <-- CAPI_CONNECT_B3_ACTIVE_IND
  491 //  CAPI_CONNECT_B3_ACTIVE_RESP -->
  492 //                       (notify Layer 4)
  493 */
  494 
  495 void capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
  496 {
  497     u_int8_t *msg = mtod(m_in, u_int8_t*);
  498     call_desc_t *cd;
  499     u_int16_t applid, msgid;
  500     u_int32_t PLCI;
  501     u_int16_t CIP;
  502     u_int8_t x, y, z;
  503     int bch;
  504 
  505     if ((cd = reserve_cd()) == NULL) {
  506         printf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
  507         return;
  508     }
  509 
  510     cd->isdnif = sc->capi_isdnif;
  511     cd->channelexcl = 0;
  512     cd->l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  513 
  514     for (bch = 0; bch < sc->sc_nbch; bch++)
  515         if (sc->sc_bchan[bch].state == B_FREE)
  516             break;
  517 
  518     sc->sc_bchan[bch].state = B_CONNECT_IND;
  519     cd->channelid = bch; /* XXX CHAN_ANY XXX */
  520 
  521     cd->crflag = CRF_DEST;
  522     cd->cr = get_rand_cr(sc->sc_unit);
  523     cd->scr_ind = SCR_NONE;
  524     cd->prs_ind = PRS_NONE;
  525     cd->bprot = BPROT_NONE;
  526     cd->ilt = NULL;
  527     cd->display[0] = '\0';
  528     cd->datetime[0] = '\0';
  529 
  530     msg = capimsg_getu16(msg + 2, &applid);
  531     msg = capimsg_getu16(msg + 2, &msgid);
  532     msg = capimsg_getu32(msg, &PLCI);
  533     msg = capimsg_getu16(msg, &CIP);
  534 
  535     cd->event = (int) msgid; /* XXX overload */
  536     cd->Q931state = (int) PLCI; /* XXX overload */
  537 
  538     switch (CIP) {
  539     case 0x0010:
  540     case 0x0001: cd->bprot = BPROT_NONE; break;
  541     case 0x0002: cd->bprot = BPROT_RHDLC; break;
  542     default:
  543 #if 0
  544         NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
  545 #endif
  546         cd->bprot = BPROT_NONE;
  547     }
  548 
  549     msg = capimsg_getu8(msg, &x); /* Called party struct len */
  550     if (x) {
  551         msg = capimsg_getu8(msg, &y); /* Numbering plan */
  552         z = x - 1;
  553         if (z >= TELNO_MAX) z = (TELNO_MAX-1);
  554         strncpy(cd->dst_telno, msg, z);
  555         msg += x;
  556         x = z;
  557     }
  558     cd->dst_telno[x] = '\0';
  559 
  560     msg = capimsg_getu8(msg, &x); /* Calling party struct len */
  561     if (x) {
  562         msg = capimsg_getu8(msg, &y); /* Numbering plan */
  563         msg = capimsg_getu8(msg, &y); /* Screening/Presentation */
  564         if ((y & 0x80) == 0) { /* screening used */
  565             cd->scr_ind = (y & 3) + SCR_USR_NOSC;
  566             cd->prs_ind = ((y >> 5) & 3) + PRS_ALLOWED;
  567         }
  568         z = x - 2;
  569         if (z >= TELNO_MAX) z = (TELNO_MAX-1);
  570         strncpy(cd->src_telno, msg, z);
  571         msg += x;
  572         x = z;
  573     }
  574     cd->src_telno[x] = '\0';
  575 
  576     i4b_l4_connect_ind(cd);
  577 }
  578 
  579 void capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
  580 {
  581     struct isdn_l3_driver *l3drv;
  582     struct mbuf *m;
  583     u_int8_t *msg;
  584     u_int16_t msgid;
  585     u_int32_t PLCI;
  586     int dlen = strlen(cd->dst_telno);
  587 
  588     m = i4b_Dgetmbuf(8 + 21 + dlen);
  589     if (!m) {
  590         printf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
  591         return;
  592     }
  593 
  594     l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  595 
  596     msgid = (u_int16_t) cd->event;
  597     PLCI = (u_int32_t) cd->Q931state;
  598 
  599     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  600     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  601     msg = capimsg_setu16(msg, CAPI_CONNECT_RESP);
  602     msg = capimsg_setu16(msg, msgid);
  603 
  604     msg = capimsg_setu32(msg, PLCI);
  605 
  606     switch (cd->response) {
  607     case SETUP_RESP_ACCEPT:
  608         sc->sc_bchan[cd->channelid].cdid = cd->cdid;
  609         sc->sc_bchan[cd->channelid].ncci = PLCI;
  610         sc->sc_bchan[cd->channelid].state = B_CONNECT_ACTIVE_IND;
  611         l3drv->bch_state[cd->channelid] = BCH_ST_USED;
  612         msg = capimsg_setu16(msg, 0); /* Accept the call */
  613         break;
  614 
  615     case SETUP_RESP_REJECT:
  616         sc->sc_bchan[cd->channelid].state = B_FREE;
  617         l3drv->bch_state[cd->channelid] = BCH_ST_FREE;
  618         msg = capimsg_setu16(msg, 2); /* Reject, normal call clearing */
  619         break;
  620 
  621     case SETUP_RESP_DNTCRE:
  622         sc->sc_bchan[cd->channelid].state = B_FREE;
  623         l3drv->bch_state[cd->channelid] = BCH_ST_FREE;
  624         if (sc->sc_nbch == 30) {
  625             /* With PRI, we can't really ignore calls  -- normal clearing */
  626             msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_NCCLR));
  627         } else {
  628             msg = capimsg_setu16(msg, 1); /* Ignore */
  629         }
  630         break;
  631 
  632     default:
  633         sc->sc_bchan[cd->channelid].state = B_FREE;
  634         l3drv->bch_state[cd->channelid] = BCH_ST_FREE;
  635         msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_CALLREJ));
  636     }
  637 
  638     msg = capimsg_setu8(msg, 15); /* B protocol */
  639     if (cd->bprot == BPROT_NONE)
  640         msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
  641     else
  642         msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
  643     msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
  644     msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
  645     msg = capimsg_setu8(msg, 0); /* B1 parameters */
  646     msg = capimsg_setu8(msg, 0); /* B2 parameters */
  647     msg = capimsg_setu8(msg, 0); /* B3 parameters */
  648 
  649     msg = capimsg_setu8(msg, 1 + dlen);
  650     msg = capimsg_setu8(msg, 0x80); /* Numbering plan */
  651     strncpy(msg, cd->dst_telno, dlen);
  652     msg = capimsg_setu8(msg + dlen, 0); /* Connected subaddress */
  653     msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
  654     msg = capimsg_setu8(msg, 0); /* Additional Info */
  655 
  656     sc->send(sc, m);
  657 }
  658 
  659 void capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
  660 {
  661     struct mbuf *m = i4b_Dgetmbuf(8 + 7);
  662     u_int8_t *msg = mtod(m_in, u_int8_t*);
  663     u_int16_t applid, msgid;
  664     u_int32_t NCCI;
  665     int bch;
  666 
  667     if (!m) {
  668         printf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
  669         return;
  670     }
  671 
  672     msg = capimsg_getu16(msg + 2, &applid);
  673     msg = capimsg_getu16(msg + 2, &msgid);
  674     msg = capimsg_getu32(msg, &NCCI);
  675 
  676     for (bch = 0; bch < sc->sc_nbch; bch++)
  677         if ((sc->sc_bchan[bch].state == B_CONNECT_B3_IND) &&
  678             (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
  679             break;
  680 
  681     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  682     msg = capimsg_setu16(msg, applid);
  683     msg = capimsg_setu16(msg, CAPI_CONNECT_B3_RESP);
  684     msg = capimsg_setu16(msg, msgid);
  685 
  686     msg = capimsg_setu32(msg, NCCI);
  687 
  688     if (bch == sc->sc_nbch) {
  689         printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
  690                sc->sc_unit, NCCI);
  691         msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
  692 
  693     } else {
  694         sc->sc_bchan[bch].ncci = NCCI;
  695         sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
  696         msg = capimsg_setu16(msg, 0); /* Accept */
  697     }
  698 
  699     msg = capimsg_setu8(msg, 0); /* NCPI */
  700 
  701     sc->send(sc, m);
  702 }
  703 
  704 /*
  705 //  Data transfer:
  706 //  --------------
  707 */
  708 
  709 void capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
  710 {
  711     struct mbuf *m = i4b_Dgetmbuf(8 + 14);
  712     u_int8_t *msg;
  713     u_int16_t msgid;
  714 
  715     if (!m) {
  716         printf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
  717         return;
  718     }
  719 
  720     msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
  721     sc->sc_bchan[chan].busy = 1;
  722 
  723     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  724     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  725     msg = capimsg_setu16(msg, CAPI_DATA_B3_REQ);
  726     msg = capimsg_setu16(msg, msgid);
  727 
  728     msg = capimsg_setu32(msg, sc->sc_bchan[chan].ncci);
  729     msg = capimsg_setu32(msg, (u_int32_t) m_b3->m_data); /* Pointer */
  730     msg = capimsg_setu16(msg, m_b3->m_len);
  731     msg = capimsg_setu16(msg, chan);
  732     msg = capimsg_setu16(msg, 0); /* Flags */
  733 
  734     m->m_next = m_b3;
  735 
  736     sc->send(sc, m);
  737 }
  738 
  739 void capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
  740 {
  741     u_int8_t *msg = mtod(m_in, u_int8_t*);
  742     u_int32_t NCCI;
  743     u_int16_t handle;
  744     u_int16_t Info;
  745 
  746     msg = capimsg_getu32(msg + 8, &NCCI);
  747     msg = capimsg_getu16(msg, &handle);
  748     msg = capimsg_getu16(msg, &Info);
  749 
  750     if (Info == 0) {
  751         sc->sc_bchan[handle].busy = 0;
  752         capi_start_tx(sc, handle);
  753 
  754     } else {
  755         printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
  756                sc->sc_unit, NCCI, handle, Info);
  757     }
  758 }
  759 
  760 void capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
  761 {
  762     struct mbuf *m = i4b_Dgetmbuf(8 + 6);
  763     u_int8_t *msg = mtod(m_in, u_int8_t*);
  764     u_int16_t applid, msgid;
  765     u_int32_t NCCI;
  766     u_int16_t handle;
  767     int bch;
  768 
  769     if (!m) {
  770         printf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
  771         return;
  772     }
  773 
  774     msg = capimsg_getu16(msg + 2, &applid);
  775     msg = capimsg_getu16(msg + 2, &msgid);
  776     msg = capimsg_getu32(msg, &NCCI);
  777     msg = capimsg_getu16(msg + 6, &handle);
  778 
  779     for (bch = 0; bch < sc->sc_nbch; bch++)
  780         if ((sc->sc_bchan[bch].state == B_CONNECTED) &&
  781             (sc->sc_bchan[bch].ncci == NCCI))
  782             break;
  783 
  784     if (bch == sc->sc_nbch) {
  785         printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
  786                sc->sc_unit, NCCI);
  787 
  788     } else {
  789         if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
  790             /* HDLC drivers use rx_mbuf */
  791 
  792             sc->sc_bchan[bch].in_mbuf = m_in->m_next;
  793             sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
  794             m_in->m_next = NULL; /* driver frees */
  795 
  796             (*sc->sc_bchan[bch].l4_driver->bch_rx_data_ready)(
  797                 sc->sc_bchan[bch].l4_driver_softc);
  798 
  799         } else {
  800             /* Telephony drivers use rx_queue */
  801 
  802             if (!IF_QFULL(&sc->sc_bchan[bch].rx_queue)) {
  803                 IF_ENQUEUE(&sc->sc_bchan[bch].rx_queue, m_in->m_next);
  804                 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
  805                 m_in->m_next = NULL; /* driver frees */
  806             }
  807 
  808             (*sc->sc_bchan[bch].l4_driver->bch_rx_data_ready)(
  809                 sc->sc_bchan[bch].l4_driver_softc);
  810         }
  811     }
  812 
  813     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  814     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  815     msg = capimsg_setu16(msg, CAPI_DATA_B3_RESP);
  816     msg = capimsg_setu16(msg, msgid);
  817 
  818     msg = capimsg_setu32(msg, NCCI);
  819     msg = capimsg_setu16(msg, handle);
  820 
  821     sc->send(sc, m);
  822 }
  823 
  824 /*
  825 //  Connection teardown:
  826 //  --------------------
  827 */
  828 
  829 void capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
  830 {
  831     struct isdn_l3_driver *l3drv;
  832     struct mbuf *m = i4b_Dgetmbuf(8 + 5);
  833     u_int8_t *msg;
  834     u_int16_t msgid;
  835     u_int32_t PLCI;
  836 
  837     if (!m) {
  838         printf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
  839         return;
  840     }
  841 
  842     l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  843 
  844     sc->sc_bchan[cd->channelid].state = B_DISCONNECT_CONF;
  845     l3drv->bch_state[cd->channelid] = BCH_ST_RSVD;
  846     msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
  847     PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
  848 
  849     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  850     msg = capimsg_setu16(msg, I4BCAPI_APPLID);
  851     msg = capimsg_setu16(msg, CAPI_DISCONNECT_REQ);
  852     msg = capimsg_setu16(msg, msgid);
  853 
  854     msg = capimsg_setu32(msg, PLCI);
  855     msg = capimsg_setu8(msg, 0); /* Additional Info */
  856 
  857     sc->send(sc, m);
  858 }
  859 
  860 void capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
  861 {
  862     struct isdn_l3_driver *l3drv;
  863     u_int8_t *msg = mtod(m_in, u_int8_t*);
  864     call_desc_t *cd;
  865     u_int32_t PLCI;
  866     int bch;
  867 
  868     msg = capimsg_getu32(msg + 8, &PLCI);
  869 
  870     for (bch = 0; bch < sc->sc_nbch; bch++)
  871         if ((sc->sc_bchan[bch].state == B_DISCONNECT_CONF) &&
  872             ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
  873             break;
  874 
  875     if (bch == sc->sc_nbch) {
  876         printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
  877                sc->sc_unit, PLCI);
  878         return;
  879     }
  880 
  881     cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
  882     if (!cd) {
  883         printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
  884                sc->sc_unit, PLCI);
  885     } else {
  886         i4b_l4_disconnect_ind(cd);
  887         freecd_by_cd(cd);
  888     }
  889 
  890     l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  891 
  892     sc->sc_bchan[bch].state = B_FREE;
  893     l3drv->bch_state[bch] = BCH_ST_FREE;
  894 }
  895 
  896 void capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
  897 {
  898     struct mbuf *m = i4b_Dgetmbuf(8 + 4);
  899     u_int8_t *msg = mtod(m_in, u_int8_t*);
  900     u_int16_t applid, msgid;
  901     u_int32_t NCCI;
  902 
  903     if (!m) {
  904         printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
  905         return;
  906     }
  907 
  908     msg = capimsg_getu16(msg + 2, &applid);
  909     msg = capimsg_getu16(msg + 2, &msgid);
  910     msg = capimsg_getu32(msg, &NCCI);
  911 
  912     /* XXX update bchan state? XXX */
  913 
  914     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  915     msg = capimsg_setu16(msg, applid);
  916     msg = capimsg_setu16(msg, CAPI_DISCONNECT_B3_RESP);
  917     msg = capimsg_setu16(msg, msgid);
  918 
  919     msg = capimsg_setu32(msg, NCCI);
  920 
  921     sc->send(sc, m);
  922 }
  923 
  924 void capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
  925 {
  926     struct isdn_l3_driver *l3drv;
  927     struct mbuf *m = i4b_Dgetmbuf(8 + 4);
  928     u_int8_t *msg = mtod(m_in, u_int8_t*);
  929     call_desc_t *cd;
  930     u_int16_t applid, msgid;
  931     u_int32_t PLCI;
  932     u_int16_t Reason;
  933     int bch;
  934 
  935     if (!m) {
  936         printf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
  937         return;
  938     }
  939 
  940     msg = capimsg_getu16(msg + 2, &applid);
  941     msg = capimsg_getu16(msg + 2, &msgid);
  942     msg = capimsg_getu32(msg, &PLCI);
  943     msg = capimsg_getu16(msg, &Reason);
  944 
  945     for (bch = 0; bch < sc->sc_nbch; bch++)
  946         if ((sc->sc_bchan[bch].state != B_FREE) &&
  947             ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
  948             break;
  949 
  950     if (bch < sc->sc_nbch) {
  951         /* We may not have a bchan assigned if call was ignored. */
  952 
  953         cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
  954         sc->sc_bchan[bch].state = B_DISCONNECT_IND;
  955     } else
  956         cd = NULL;
  957 
  958     if (cd) {
  959         if ((Reason & 0xff00) == 0x3400) {
  960             SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
  961         } else {
  962             SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
  963         }
  964 
  965         i4b_l4_disconnect_ind(cd);
  966         freecd_by_cd(cd);
  967 
  968         sc->sc_bchan[bch].state = B_FREE;
  969         l3drv = isdn_find_l3_by_isdnif(sc->capi_isdnif);
  970         l3drv->bch_state[bch] = BCH_ST_FREE;
  971     }
  972 
  973     msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
  974     msg = capimsg_setu16(msg, applid);
  975     msg = capimsg_setu16(msg, CAPI_DISCONNECT_RESP);
  976     msg = capimsg_setu16(msg, msgid);
  977 
  978     msg = capimsg_setu32(msg, PLCI);
  979 
  980     sc->send(sc, m);
  981 }

Cache object: c42269787e795416d0adbc9f3c0ba4ec


[ 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.