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.6 2005/01/23 13:47:24 joerg 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 // ------------------------
55 void capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
57 struct mbuf *m = i4b_Dgetmbuf(8 + 18);
62 printf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
66 msgid = sc->sc_msgid++;
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);
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);
83 void capi_listen_conf(capi_softc_t *sc, struct mbuf *m_in)
85 u_int8_t *msg = mtod(m_in, u_int8_t*);
88 capimsg_getu16(msg + 12, &Info);
91 /* We are now listening. */
94 ctrl_desc[sc->ctrl_unit].dl_est = DL_UP;
96 i4b_l4_l12stat(sc->ctrl_unit, 1, 1);
97 i4b_l4_l12stat(sc->ctrl_unit, 2, 1);
100 /* XXX sc->sc_state = C_DOWN ? XXX */
101 printf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
105 void capi_info_ind(capi_softc_t *sc, struct mbuf *m_in)
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;
113 printf("capi%d: can't get mbuf for info_resp\n", sc->sc_unit);
117 msg = capimsg_getu16(msg + 2, &applid);
118 msg = capimsg_getu16(msg + 2, &msgid);
119 msg = capimsg_getu32(msg, &PLCI);
121 /* i4b_l4_info_ind() */
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);
128 msg = capimsg_setu32(msg, PLCI);
133 void capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
135 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
141 printf("capi%d: can't get mbuf for alert_req\n", sc->sc_unit);
145 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
146 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
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);
153 msg = capimsg_setu32(msg, PLCI);
154 msg = capimsg_setu8(msg, 0);
159 void capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
161 u_int8_t *msg = mtod(m_in, u_int8_t*);
164 msg = capimsg_getu16(msg + 12, &Info);
167 printf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
172 // Outgoing call setup:
173 // --------------------
175 // CAPI_CONNECT_REQ -->
176 // <-- CAPI_CONNECT_CONF
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 -->
187 void capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
192 int slen = strlen(cd->src_telno);
193 int dlen = strlen(cd->dst_telno);
195 m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
197 printf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
201 cd->crflag = CRF_ORIG;
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;
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);
214 msg = capimsg_setu32(msg, 1); /* Controller */
218 msg = capimsg_setu16(msg, 0x0010); /* Telephony */
222 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
226 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
229 msg = capimsg_setu8(msg, 1 + dlen);
230 msg = capimsg_setu8(msg, 0x80);
231 strncpy(msg, cd->dst_telno, dlen);
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);
238 msg = capimsg_setu8(msg + slen, 0); /* Called & */
239 msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
241 msg = capimsg_setu8(msg, 15); /* B protocol */
242 if (cd->bprot == BPROT_NONE)
243 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
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 */
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 */
260 void capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
262 u_int8_t *msg = mtod(m_in, u_int8_t*);
269 msg = capimsg_getu16(msg + 6, &msgid);
270 msg = capimsg_getu32(msg, &PLCI);
271 msg = capimsg_getu16(msg, &Info);
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))
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",
286 sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
287 sc->sc_bchan[bch].ncci = PLCI;
289 i4b_l4_proceeding_ind(cd);
292 SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
293 i4b_l4_disconnect_ind(cd);
296 sc->sc_bchan[bch].state = B_FREE;
297 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
299 printf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
303 void capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
305 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
306 u_int8_t *msg = mtod(m_in, u_int8_t*);
308 u_int16_t applid, msgid;
313 printf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
317 msg = capimsg_getu16(msg + 2, &applid);
318 msg = capimsg_getu16(msg + 2, &msgid);
319 msg = capimsg_getu32(msg, &PLCI);
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))
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",
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);
338 msg = capimsg_setu32(msg, PLCI);
342 if (cd->crflag == CRF_ORIG) {
343 capi_connect_b3_req(sc, cd);
346 sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
350 void capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
352 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
358 printf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
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);
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);
371 msg = capimsg_setu32(msg, PLCI);
372 msg = capimsg_setu8(msg, 0); /* NCPI */
377 void capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
379 u_int8_t *msg = mtod(m_in, u_int8_t*);
386 msg = capimsg_getu16(msg + 6, &msgid);
387 msg = capimsg_getu32(msg, &NCCI);
388 msg = capimsg_getu16(msg, &Info);
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)))
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",
403 sc->sc_bchan[bch].ncci = NCCI;
404 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
407 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
408 i4b_l4_disconnect_ind(cd);
411 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_RSVD;
413 printf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
415 capi_disconnect_req(sc, cd);
419 void capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
421 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
422 u_int8_t *msg = mtod(m_in, u_int8_t*);
424 u_int16_t applid, msgid;
429 printf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
433 msg = capimsg_getu16(msg + 2, &applid);
434 msg = capimsg_getu16(msg + 2, &msgid);
435 msg = capimsg_getu32(msg, &NCCI);
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))
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",
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);
454 msg = capimsg_setu32(msg, NCCI);
458 sc->sc_bchan[bch].state = B_CONNECTED;
459 i4b_l4_connect_active_ind(cd);
463 // Incoming call setup:
464 // --------------------
466 // <-- CAPI_CONNECT_IND
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 -->
478 void capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
480 u_int8_t *msg = mtod(m_in, u_int8_t*);
482 u_int16_t applid, msgid;
488 if ((cd = reserve_cd()) == NULL) {
489 printf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
493 cd->controller = sc->ctrl_unit;
494 cd->channelexcl = FALSE;
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 */
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;
508 cd->display[0] = '\0';
509 cd->datetime[0] = '\0';
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);
516 cd->event = (int) msgid; /* XXX overload */
517 cd->Q931state = (int) PLCI; /* XXX overload */
521 case 0x0001: cd->bprot = BPROT_NONE; break;
522 case 0x0002: cd->bprot = BPROT_RHDLC; break;
524 NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
525 cd->bprot = BPROT_NONE;
528 msg = capimsg_getu8(msg, &x); /* Called party struct len */
530 msg = capimsg_getu8(msg, &y); /* Numbering plan */
532 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
533 strncpy(cd->dst_telno, msg, z);
537 cd->dst_telno[x] = '\0';
539 msg = capimsg_getu8(msg, &x); /* Calling party struct len */
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;
548 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
549 strncpy(cd->src_telno, msg, z);
553 cd->src_telno[x] = '\0';
555 i4b_l4_connect_ind(cd);
558 void capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
564 int dlen = strlen(cd->dst_telno);
566 m = i4b_Dgetmbuf(8 + 21 + dlen);
568 printf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
572 msgid = (u_int16_t) cd->event;
573 PLCI = (u_int32_t) cd->Q931state;
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);
580 msg = capimsg_setu32(msg, PLCI);
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 */
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 */
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));
604 msg = capimsg_setu16(msg, 1); /* Ignore */
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));
614 msg = capimsg_setu8(msg, 15); /* B protocol */
615 if (cd->bprot == BPROT_NONE)
616 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
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 */
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 */
635 void capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
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;
644 printf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
648 msg = capimsg_getu16(msg + 2, &applid);
649 msg = capimsg_getu16(msg + 2, &msgid);
650 msg = capimsg_getu32(msg, &NCCI);
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)))
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);
662 msg = capimsg_setu32(msg, NCCI);
664 if (bch == sc->sc_nbch) {
665 printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
667 msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
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 */
675 msg = capimsg_setu8(msg, 0); /* NCPI */
685 void capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
687 struct mbuf *m = i4b_Dgetmbuf(8 + 14);
692 printf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
696 msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
697 sc->sc_bchan[chan].busy = 1;
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);
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 */
715 void capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
717 u_int8_t *msg = mtod(m_in, u_int8_t*);
722 msg = capimsg_getu32(msg + 8, &NCCI);
723 msg = capimsg_getu16(msg, &handle);
724 msg = capimsg_getu16(msg, &Info);
727 sc->sc_bchan[handle].busy = 0;
728 capi_start_tx(sc, handle);
731 printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
732 sc->sc_unit, NCCI, handle, Info);
736 void capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
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;
746 printf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
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);
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))
760 if (bch == sc->sc_nbch) {
761 printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
765 if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
766 /* HDLC drivers use rx_mbuf */
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 */
772 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
773 sc->sc_bchan[bch].capi_drvr_linktab->unit);
776 /* Telephony drivers use rx_queue */
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 */
784 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
785 sc->sc_bchan[bch].capi_drvr_linktab->unit);
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);
794 msg = capimsg_setu32(msg, NCCI);
795 msg = capimsg_setu16(msg, handle);
801 // Connection teardown:
802 // --------------------
805 void capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
807 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
813 printf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
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);
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);
827 msg = capimsg_setu32(msg, PLCI);
828 msg = capimsg_setu8(msg, 0); /* Additional Info */
833 void capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
835 u_int8_t *msg = mtod(m_in, u_int8_t*);
840 msg = capimsg_getu32(msg + 8, &PLCI);
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))
847 if (bch == sc->sc_nbch) {
848 printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
853 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
855 printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
858 i4b_l4_disconnect_ind(cd);
862 sc->sc_bchan[bch].state = B_FREE;
863 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
866 void capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
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;
874 printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
878 msg = capimsg_getu16(msg + 2, &applid);
879 msg = capimsg_getu16(msg + 2, &msgid);
880 msg = capimsg_getu32(msg, &NCCI);
882 /* XXX update bchan state? XXX */
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);
889 msg = capimsg_setu32(msg, NCCI);
894 void capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
896 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
897 u_int8_t *msg = mtod(m_in, u_int8_t*);
899 u_int16_t applid, msgid;
905 printf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
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);
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))
919 if (bch < sc->sc_nbch) {
920 /* We may not have a bchan assigned if call was ignored. */
922 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
923 sc->sc_bchan[bch].state = B_DISCONNECT_IND;
927 if ((Reason & 0xff00) == 0x3400) {
928 SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
930 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
933 i4b_l4_disconnect_ind(cd);
936 sc->sc_bchan[bch].state = B_FREE;
937 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
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);
945 msg = capimsg_setu32(msg, PLCI);