File:  [DragonFly] / src / sys / net / i4b / capi / capi_msgs.c
Revision 1.5: download - view: text, annotated - select for diffs
Fri Apr 16 15:40:20 2004 UTC (10 years, 5 months ago) by joerg
Branches: MAIN
CVS tags: HEAD, DragonFly_Snap29Sep2004, DragonFly_Snap13Sep2004, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
Merge changes from FreeBSD 5:
- remove dependency on device counting
- undo massive inlining on iavc

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