File:  [DragonFly] / src / sys / net / i4b / capi / capi_msgs.c
Revision 1.4: download - view: text, annotated - select for diffs
Thu Aug 7 21:54:30 2003 UTC (11 years ago) by dillon
Branches: MAIN
CVS tags: HEAD
kernel tree reorganization stage 1: Major cvs repository work (not logged as
commits) plus a major reworking of the #include's to accomodate the
relocations.

    * CVS repository files manually moved.  Old directories left intact
      and empty (temporary).

    * Reorganize all filesystems into vfs/, most devices into dev/,
      sub-divide devices by function.

    * Begin to move device-specific architecture files to the device
      subdirs rather then throwing them all into, e.g. i386/include

    * Reorganize files related to system busses, placing the related code
      in a new bus/ directory.  Also move cam to bus/cam though this may
      not have been the best idea in retrospect.

    * Reorganize emulation code and place it in a new emulation/ directory.

    * Remove the -I- compiler option in order to allow #include file
      localization, rename all config generated X.h files to use_X.h to
      clean up the conflicts.

    * Remove /usr/src/include (or /usr/include) dependancies during the
      kernel build, beyond what is normally needed to compile helper
      programs.

    * Make config create 'machine' softlinks for architecture specific
      directories outside of the standard <arch>/include.

    * Bump the config rev.

    WARNING! after this commit /usr/include and /usr/src/sys/compile/*
    should be regenerated from scratch.

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