2 * Copyright (c) 2001 Cubical Solutions Ltd. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 * capi/capi_msgs.c The CAPI i4b message handlers.
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.8 2006/12/22 23:44:55 swildner Exp $
31 #include <sys/param.h>
32 #include <sys/kernel.h>
33 #include <sys/systm.h>
35 #include <sys/socket.h>
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>
42 #include "../include/i4b_l3l4.h"
43 #include "../include/i4b_mbuf.h"
44 #include "../include/i4b_global.h"
45 #include "../layer4/i4b_l4.h"
48 #include "capi_msgs.h"
51 // Administrative messages:
52 // ------------------------
56 capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
58 struct mbuf *m = i4b_Dgetmbuf(8 + 18);
63 kprintf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
67 msgid = sc->sc_msgid++;
69 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
70 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
71 msg = capimsg_setu16(msg, CAPI_LISTEN_REQ);
72 msg = capimsg_setu16(msg, msgid);
74 msg = capimsg_setu32(msg, 1); /* Controller */
75 msg = capimsg_setu32(msg, 0); /* Info mask */
76 msg = capimsg_setu32(msg, CIP);
77 msg = capimsg_setu32(msg, 0);
78 msg = capimsg_setu8(msg, 0);
79 msg = capimsg_setu8(msg, 0);
85 capi_listen_conf(capi_softc_t *sc, struct mbuf *m_in)
87 u_int8_t *msg = mtod(m_in, u_int8_t*);
90 capimsg_getu16(msg + 12, &Info);
93 /* We are now listening. */
96 ctrl_desc[sc->ctrl_unit].dl_est = DL_UP;
98 i4b_l4_l12stat(sc->ctrl_unit, 1, 1);
99 i4b_l4_l12stat(sc->ctrl_unit, 2, 1);
102 /* XXX sc->sc_state = C_DOWN ? XXX */
103 kprintf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
108 capi_info_ind(capi_softc_t *sc, struct mbuf *m_in)
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;
116 kprintf("capi%d: can't get mbuf for info_resp\n", sc->sc_unit);
120 msg = capimsg_getu16(msg + 2, &applid);
121 msg = capimsg_getu16(msg + 2, &msgid);
122 msg = capimsg_getu32(msg, &PLCI);
124 /* i4b_l4_info_ind() */
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);
131 msg = capimsg_setu32(msg, PLCI);
137 capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
139 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
145 kprintf("capi%d: can't get mbuf for alert_req\n", sc->sc_unit);
149 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
150 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
152 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
153 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
154 msg = capimsg_setu16(msg, CAPI_ALERT_REQ);
155 msg = capimsg_setu16(msg, msgid);
157 msg = capimsg_setu32(msg, PLCI);
158 msg = capimsg_setu8(msg, 0);
164 capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
166 u_int8_t *msg = mtod(m_in, u_int8_t*);
169 msg = capimsg_getu16(msg + 12, &Info);
172 kprintf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
177 // Outgoing call setup:
178 // --------------------
180 // CAPI_CONNECT_REQ -->
181 // <-- CAPI_CONNECT_CONF
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 -->
193 capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
198 int slen = strlen(cd->src_telno);
199 int dlen = strlen(cd->dst_telno);
201 m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
203 kprintf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
207 cd->crflag = CRF_ORIG;
209 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
210 sc->sc_bchan[cd->channelid].bprot = cd->bprot;
211 sc->sc_bchan[cd->channelid].state = B_CONNECT_CONF;
212 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
213 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
215 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
216 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
217 msg = capimsg_setu16(msg, CAPI_CONNECT_REQ);
218 msg = capimsg_setu16(msg, msgid);
220 msg = capimsg_setu32(msg, 1); /* Controller */
224 msg = capimsg_setu16(msg, 0x0010); /* Telephony */
228 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
232 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
235 msg = capimsg_setu8(msg, 1 + dlen);
236 msg = capimsg_setu8(msg, 0x80);
237 strncpy(msg, cd->dst_telno, dlen);
239 msg = capimsg_setu8(msg + dlen, 2 + slen);
240 msg = capimsg_setu8(msg, 0x00);
241 msg = capimsg_setu8(msg, 0x80); /* Presentation and screening indicator */
242 strncpy(msg, cd->src_telno, slen);
244 msg = capimsg_setu8(msg + slen, 0); /* Called & */
245 msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
247 msg = capimsg_setu8(msg, 15); /* B protocol */
248 if (cd->bprot == BPROT_NONE)
249 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
251 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
252 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
253 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
254 msg = capimsg_setu8(msg, 0); /* B1 parameters */
255 msg = capimsg_setu8(msg, 0); /* B2 parameters */
256 msg = capimsg_setu8(msg, 0); /* B3 parameters */
258 msg = capimsg_setu8(msg, 0); /* Bearer Capability */
259 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
260 msg = capimsg_setu8(msg, 0); /* High Layer Compatibility */
261 msg = capimsg_setu8(msg, 0); /* Additional Info */
267 capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
269 u_int8_t *msg = mtod(m_in, u_int8_t*);
276 msg = capimsg_getu16(msg + 6, &msgid);
277 msg = capimsg_getu32(msg, &PLCI);
278 msg = capimsg_getu16(msg, &Info);
280 for (bch = 0; bch < sc->sc_nbch; bch++)
281 if ((sc->sc_bchan[bch].state == B_CONNECT_CONF) &&
282 (sc->sc_bchan[bch].msgid == msgid))
285 if ((bch == sc->sc_nbch) ||
286 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
287 kprintf("capi%d: can't find channel for connect_conf PLCI %x\n",
293 sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
294 sc->sc_bchan[bch].ncci = PLCI;
296 i4b_l4_proceeding_ind(cd);
299 SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
300 i4b_l4_disconnect_ind(cd);
303 sc->sc_bchan[bch].state = B_FREE;
304 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
306 kprintf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
311 capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
313 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
314 u_int8_t *msg = mtod(m_in, u_int8_t*);
316 u_int16_t applid, msgid;
321 kprintf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
325 msg = capimsg_getu16(msg + 2, &applid);
326 msg = capimsg_getu16(msg + 2, &msgid);
327 msg = capimsg_getu32(msg, &PLCI);
329 for (bch = 0; bch < sc->sc_nbch; bch++)
330 if ((sc->sc_bchan[bch].state == B_CONNECT_ACTIVE_IND) &&
331 (sc->sc_bchan[bch].ncci == PLCI))
334 if ((bch == sc->sc_nbch) ||
335 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
336 kprintf("capi%d: can't find channel for active_resp, PLCI %x\n",
341 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
342 msg = capimsg_setu16(msg, applid);
343 msg = capimsg_setu16(msg, CAPI_CONNECT_ACTIVE_RESP);
344 msg = capimsg_setu16(msg, msgid);
346 msg = capimsg_setu32(msg, PLCI);
350 if (cd->crflag == CRF_ORIG) {
351 capi_connect_b3_req(sc, cd);
354 sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
359 capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
361 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
367 kprintf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
371 sc->sc_bchan[cd->channelid].state = B_CONNECT_B3_CONF;
372 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
373 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
375 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
376 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
377 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_REQ);
378 msg = capimsg_setu16(msg, msgid);
380 msg = capimsg_setu32(msg, PLCI);
381 msg = capimsg_setu8(msg, 0); /* NCPI */
387 capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
389 u_int8_t *msg = mtod(m_in, u_int8_t*);
396 msg = capimsg_getu16(msg + 6, &msgid);
397 msg = capimsg_getu32(msg, &NCCI);
398 msg = capimsg_getu16(msg, &Info);
400 for (bch = 0; bch < sc->sc_nbch; bch++)
401 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_CONF) &&
402 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
405 if ((bch == sc->sc_nbch) ||
406 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
407 kprintf("capi%d: can't find channel for connect_b3_conf NCCI %x\n",
413 sc->sc_bchan[bch].ncci = NCCI;
414 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
417 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
418 i4b_l4_disconnect_ind(cd);
421 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_RSVD;
423 kprintf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
425 capi_disconnect_req(sc, cd);
430 capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
432 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
433 u_int8_t *msg = mtod(m_in, u_int8_t*);
435 u_int16_t applid, msgid;
440 kprintf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
444 msg = capimsg_getu16(msg + 2, &applid);
445 msg = capimsg_getu16(msg + 2, &msgid);
446 msg = capimsg_getu32(msg, &NCCI);
448 for (bch = 0; bch < sc->sc_nbch; bch++)
449 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_ACTIVE_IND) &&
450 (sc->sc_bchan[bch].ncci == NCCI))
453 if ((bch == sc->sc_nbch) ||
454 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
455 kprintf("capi%d: can't find channel for b3_active_resp NCCI %x\n",
460 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
461 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
462 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_ACTIVE_RESP);
463 msg = capimsg_setu16(msg, msgid);
465 msg = capimsg_setu32(msg, NCCI);
469 sc->sc_bchan[bch].state = B_CONNECTED;
470 i4b_l4_connect_active_ind(cd);
474 // Incoming call setup:
475 // --------------------
477 // <-- CAPI_CONNECT_IND
479 // CAPI_CONNECT_RESP -->
480 // <-- CAPI_CONNECT_ACTIVE_IND
481 // CAPI_CONNECT_ACTIVE_RESP -->
482 // <-- CAPI_CONNECT_B3_IND
483 // CAPI_CONNECT_B3_RESP -->
484 // <-- CAPI_CONNECT_B3_ACTIVE_IND
485 // CAPI_CONNECT_B3_ACTIVE_RESP -->
490 capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
492 u_int8_t *msg = mtod(m_in, u_int8_t*);
494 u_int16_t applid, msgid;
500 if ((cd = reserve_cd()) == NULL) {
501 kprintf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
505 cd->controller = sc->ctrl_unit;
506 cd->channelexcl = FALSE;
508 for (bch = 0; bch < sc->sc_nbch; bch++)
509 if (sc->sc_bchan[bch].state == B_FREE) break;
510 sc->sc_bchan[bch].state = B_CONNECT_IND;
511 cd->channelid = bch; /* XXX CHAN_ANY XXX */
513 cd->crflag = CRF_DEST;
514 cd->cr = get_rand_cr(sc->sc_unit);
515 cd->scr_ind = SCR_NONE;
516 cd->prs_ind = PRS_NONE;
517 cd->bprot = BPROT_NONE;
520 cd->display[0] = '\0';
521 cd->datetime[0] = '\0';
523 msg = capimsg_getu16(msg + 2, &applid);
524 msg = capimsg_getu16(msg + 2, &msgid);
525 msg = capimsg_getu32(msg, &PLCI);
526 msg = capimsg_getu16(msg, &CIP);
528 cd->event = (int) msgid; /* XXX overload */
529 cd->Q931state = (int) PLCI; /* XXX overload */
533 case 0x0001: cd->bprot = BPROT_NONE; break;
534 case 0x0002: cd->bprot = BPROT_RHDLC; break;
536 NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
537 cd->bprot = BPROT_NONE;
540 msg = capimsg_getu8(msg, &x); /* Called party struct len */
542 msg = capimsg_getu8(msg, &y); /* Numbering plan */
544 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
545 strncpy(cd->dst_telno, msg, z);
549 cd->dst_telno[x] = '\0';
551 msg = capimsg_getu8(msg, &x); /* Calling party struct len */
553 msg = capimsg_getu8(msg, &y); /* Numbering plan */
554 msg = capimsg_getu8(msg, &y); /* Screening/Presentation */
555 if ((y & 0x80) == 0) { /* screening used */
556 cd->scr_ind = (y & 3) + SCR_USR_NOSC;
557 cd->prs_ind = ((y >> 5) & 3) + PRS_ALLOWED;
560 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
561 strncpy(cd->src_telno, msg, z);
565 cd->src_telno[x] = '\0';
567 i4b_l4_connect_ind(cd);
571 capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
577 int dlen = strlen(cd->dst_telno);
579 m = i4b_Dgetmbuf(8 + 21 + dlen);
581 kprintf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
585 msgid = (u_int16_t) cd->event;
586 PLCI = (u_int32_t) cd->Q931state;
588 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
589 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
590 msg = capimsg_setu16(msg, CAPI_CONNECT_RESP);
591 msg = capimsg_setu16(msg, msgid);
593 msg = capimsg_setu32(msg, PLCI);
595 switch (cd->response) {
596 case SETUP_RESP_ACCEPT:
597 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
598 sc->sc_bchan[cd->channelid].ncci = PLCI;
599 sc->sc_bchan[cd->channelid].state = B_CONNECT_ACTIVE_IND;
600 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_USED;
601 msg = capimsg_setu16(msg, 0); /* Accept the call */
604 case SETUP_RESP_REJECT:
605 sc->sc_bchan[cd->channelid].state = B_FREE;
606 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
607 msg = capimsg_setu16(msg, 2); /* Reject, normal call clearing */
610 case SETUP_RESP_DNTCRE:
611 sc->sc_bchan[cd->channelid].state = B_FREE;
612 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
613 if (sc->sc_nbch == 30) {
614 /* With PRI, we can't really ignore calls -- normal clearing */
615 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_NCCLR));
617 msg = capimsg_setu16(msg, 1); /* Ignore */
622 sc->sc_bchan[cd->channelid].state = B_FREE;
623 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
624 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_CALLREJ));
627 msg = capimsg_setu8(msg, 15); /* B protocol */
628 if (cd->bprot == BPROT_NONE)
629 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
631 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
632 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
633 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
634 msg = capimsg_setu8(msg, 0); /* B1 parameters */
635 msg = capimsg_setu8(msg, 0); /* B2 parameters */
636 msg = capimsg_setu8(msg, 0); /* B3 parameters */
638 msg = capimsg_setu8(msg, 1 + dlen);
639 msg = capimsg_setu8(msg, 0x80); /* Numbering plan */
640 strncpy(msg, cd->dst_telno, dlen);
641 msg = capimsg_setu8(msg + dlen, 0); /* Connected subaddress */
642 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
643 msg = capimsg_setu8(msg, 0); /* Additional Info */
649 capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
651 struct mbuf *m = i4b_Dgetmbuf(8 + 7);
652 u_int8_t *msg = mtod(m_in, u_int8_t*);
653 u_int16_t applid, msgid;
658 kprintf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
662 msg = capimsg_getu16(msg + 2, &applid);
663 msg = capimsg_getu16(msg + 2, &msgid);
664 msg = capimsg_getu32(msg, &NCCI);
666 for (bch = 0; bch < sc->sc_nbch; bch++)
667 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_IND) &&
668 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
671 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
672 msg = capimsg_setu16(msg, applid);
673 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_RESP);
674 msg = capimsg_setu16(msg, msgid);
676 msg = capimsg_setu32(msg, NCCI);
678 if (bch == sc->sc_nbch) {
679 kprintf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
681 msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
684 sc->sc_bchan[bch].ncci = NCCI;
685 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
686 msg = capimsg_setu16(msg, 0); /* Accept */
689 msg = capimsg_setu8(msg, 0); /* NCPI */
700 capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
702 struct mbuf *m = i4b_Dgetmbuf(8 + 14);
707 kprintf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
711 msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
712 sc->sc_bchan[chan].busy = 1;
714 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
715 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
716 msg = capimsg_setu16(msg, CAPI_DATA_B3_REQ);
717 msg = capimsg_setu16(msg, msgid);
719 msg = capimsg_setu32(msg, sc->sc_bchan[chan].ncci);
720 msg = capimsg_setu32(msg, (u_int32_t) m_b3->m_data); /* Pointer */
721 msg = capimsg_setu16(msg, m_b3->m_len);
722 msg = capimsg_setu16(msg, chan);
723 msg = capimsg_setu16(msg, 0); /* Flags */
731 capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
733 u_int8_t *msg = mtod(m_in, u_int8_t*);
738 msg = capimsg_getu32(msg + 8, &NCCI);
739 msg = capimsg_getu16(msg, &handle);
740 msg = capimsg_getu16(msg, &Info);
743 sc->sc_bchan[handle].busy = 0;
744 capi_start_tx(sc, handle);
747 kprintf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
748 sc->sc_unit, NCCI, handle, Info);
753 capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
755 struct mbuf *m = i4b_Dgetmbuf(8 + 6);
756 u_int8_t *msg = mtod(m_in, u_int8_t*);
757 u_int16_t applid, msgid;
763 kprintf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
767 msg = capimsg_getu16(msg + 2, &applid);
768 msg = capimsg_getu16(msg + 2, &msgid);
769 msg = capimsg_getu32(msg, &NCCI);
770 msg = capimsg_getu16(msg + 6, &handle);
772 for (bch = 0; bch < sc->sc_nbch; bch++)
773 if ((sc->sc_bchan[bch].state == B_CONNECTED) &&
774 (sc->sc_bchan[bch].ncci == NCCI))
777 if (bch == sc->sc_nbch) {
778 kprintf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
782 if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
783 /* HDLC drivers use rx_mbuf */
785 sc->sc_bchan[bch].in_mbuf = m_in->m_next;
786 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
787 m_in->m_next = NULL; /* driver frees */
789 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
790 sc->sc_bchan[bch].capi_drvr_linktab->unit);
793 /* Telephony drivers use rx_queue */
795 if (!IF_QFULL(&sc->sc_bchan[bch].rx_queue)) {
796 IF_ENQUEUE(&sc->sc_bchan[bch].rx_queue, m_in->m_next);
797 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
798 m_in->m_next = NULL; /* driver frees */
801 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
802 sc->sc_bchan[bch].capi_drvr_linktab->unit);
806 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
807 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
808 msg = capimsg_setu16(msg, CAPI_DATA_B3_RESP);
809 msg = capimsg_setu16(msg, msgid);
811 msg = capimsg_setu32(msg, NCCI);
812 msg = capimsg_setu16(msg, handle);
818 // Connection teardown:
819 // --------------------
823 capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
825 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
831 kprintf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
835 sc->sc_bchan[cd->channelid].state = B_DISCONNECT_CONF;
836 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
837 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
838 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
840 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
841 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
842 msg = capimsg_setu16(msg, CAPI_DISCONNECT_REQ);
843 msg = capimsg_setu16(msg, msgid);
845 msg = capimsg_setu32(msg, PLCI);
846 msg = capimsg_setu8(msg, 0); /* Additional Info */
852 capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
854 u_int8_t *msg = mtod(m_in, u_int8_t*);
859 msg = capimsg_getu32(msg + 8, &PLCI);
861 for (bch = 0; bch < sc->sc_nbch; bch++)
862 if ((sc->sc_bchan[bch].state == B_DISCONNECT_CONF) &&
863 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
866 if (bch == sc->sc_nbch) {
867 kprintf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
872 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
874 kprintf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
877 i4b_l4_disconnect_ind(cd);
881 sc->sc_bchan[bch].state = B_FREE;
882 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
886 capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
888 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
889 u_int8_t *msg = mtod(m_in, u_int8_t*);
890 u_int16_t applid, msgid;
894 kprintf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
898 msg = capimsg_getu16(msg + 2, &applid);
899 msg = capimsg_getu16(msg + 2, &msgid);
900 msg = capimsg_getu32(msg, &NCCI);
902 /* XXX update bchan state? XXX */
904 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
905 msg = capimsg_setu16(msg, applid);
906 msg = capimsg_setu16(msg, CAPI_DISCONNECT_B3_RESP);
907 msg = capimsg_setu16(msg, msgid);
909 msg = capimsg_setu32(msg, NCCI);
915 capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
917 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
918 u_int8_t *msg = mtod(m_in, u_int8_t*);
920 u_int16_t applid, msgid;
926 kprintf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
930 msg = capimsg_getu16(msg + 2, &applid);
931 msg = capimsg_getu16(msg + 2, &msgid);
932 msg = capimsg_getu32(msg, &PLCI);
933 msg = capimsg_getu16(msg, &Reason);
935 for (bch = 0; bch < sc->sc_nbch; bch++)
936 if ((sc->sc_bchan[bch].state != B_FREE) &&
937 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
940 if (bch < sc->sc_nbch) {
941 /* We may not have a bchan assigned if call was ignored. */
943 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
944 sc->sc_bchan[bch].state = B_DISCONNECT_IND;
948 if ((Reason & 0xff00) == 0x3400) {
949 SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
951 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
954 i4b_l4_disconnect_ind(cd);
957 sc->sc_bchan[bch].state = B_FREE;
958 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
961 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
962 msg = capimsg_setu16(msg, applid);
963 msg = capimsg_setu16(msg, CAPI_DISCONNECT_RESP);
964 msg = capimsg_setu16(msg, msgid);
966 msg = capimsg_setu32(msg, PLCI);