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
26 /* capi/capi_msgs.c The CAPI i4b message handlers.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/systm.h>
36 #include <sys/socket.h>
39 #include <i4b/include/i4b_debug.h>
40 #include <i4b/include/i4b_ioctl.h>
41 #include <i4b/include/i4b_cause.h>
43 #include <i4b/include/i4b_l3l4.h>
44 #include <i4b/include/i4b_mbuf.h>
45 #include <i4b/include/i4b_global.h>
47 #include <i4b/layer4/i4b_l4.h>
49 #include <i4b/capi/capi.h>
50 #include <i4b/capi/capi_msgs.h>
53 // Administrative messages:
54 // ------------------------
57 void capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
59 struct mbuf *m = i4b_Dgetmbuf(8 + 18);
64 printf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
68 msgid = sc->sc_msgid++;
70 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
71 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
72 msg = capimsg_setu16(msg, CAPI_LISTEN_REQ);
73 msg = capimsg_setu16(msg, msgid);
75 msg = capimsg_setu32(msg, 1); /* Controller */
76 msg = capimsg_setu32(msg, 0); /* Info mask */
77 msg = capimsg_setu32(msg, CIP);
78 msg = capimsg_setu32(msg, 0);
79 msg = capimsg_setu8(msg, 0);
80 msg = capimsg_setu8(msg, 0);
85 void 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 printf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
107 void capi_info_ind(capi_softc_t *sc, struct mbuf *m_in)
109 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
110 u_int8_t *msg = mtod(m_in, u_int8_t*);
111 u_int16_t applid, msgid;
115 printf("capi%d: can't get mbuf for info_resp\n", sc->sc_unit);
119 msg = capimsg_getu16(msg + 2, &applid);
120 msg = capimsg_getu16(msg + 2, &msgid);
121 msg = capimsg_getu32(msg, &PLCI);
123 /* i4b_l4_info_ind() */
125 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
126 msg = capimsg_setu16(msg, applid);
127 msg = capimsg_setu16(msg, CAPI_INFO_RESP);
128 msg = capimsg_setu16(msg, msgid);
130 msg = capimsg_setu32(msg, PLCI);
135 void capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
137 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
143 printf("capi%d: can't get mbuf for alert_req\n", sc->sc_unit);
147 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
148 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
150 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
151 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
152 msg = capimsg_setu16(msg, CAPI_ALERT_REQ);
153 msg = capimsg_setu16(msg, msgid);
155 msg = capimsg_setu32(msg, PLCI);
156 msg = capimsg_setu8(msg, 0);
161 void capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
163 u_int8_t *msg = mtod(m_in, u_int8_t*);
166 msg = capimsg_getu16(msg + 12, &Info);
169 printf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
174 // Outgoing call setup:
175 // --------------------
177 // CAPI_CONNECT_REQ -->
178 // <-- CAPI_CONNECT_CONF
180 // <-- CAPI_CONNECT_ACTIVE_IND
181 // CAPI_CONNECT_ACTIVE_RESP -->
182 // CAPI_CONNECT_B3_REQ -->
183 // <-- CAPI_CONNECT_B3_CONF
184 // <-- CAPI_CONNECT_B3_ACTIVE_IND
185 // CAPI_CONNECT_B3_ACTIVE_RESP -->
189 void capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
194 int slen = strlen(cd->src_telno);
195 int dlen = strlen(cd->dst_telno);
197 m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
199 printf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
203 cd->crflag = CRF_ORIG;
205 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
206 sc->sc_bchan[cd->channelid].bprot = cd->bprot;
207 sc->sc_bchan[cd->channelid].state = B_CONNECT_CONF;
208 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
209 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
211 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
212 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
213 msg = capimsg_setu16(msg, CAPI_CONNECT_REQ);
214 msg = capimsg_setu16(msg, msgid);
216 msg = capimsg_setu32(msg, 1); /* Controller */
220 msg = capimsg_setu16(msg, 0x0010); /* Telephony */
224 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
228 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
231 msg = capimsg_setu8(msg, 1 + dlen);
232 msg = capimsg_setu8(msg, 0x80);
233 strncpy(msg, cd->dst_telno, dlen);
235 msg = capimsg_setu8(msg + dlen, 2 + slen);
236 msg = capimsg_setu8(msg, 0x00);
237 msg = capimsg_setu8(msg, 0x80); /* Presentation and screening indicator */
238 strncpy(msg, cd->src_telno, slen);
240 msg = capimsg_setu8(msg + slen, 0); /* Called & */
241 msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
243 msg = capimsg_setu8(msg, 15); /* B protocol */
244 if (cd->bprot == BPROT_NONE)
245 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
247 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
248 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
249 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
250 msg = capimsg_setu8(msg, 0); /* B1 parameters */
251 msg = capimsg_setu8(msg, 0); /* B2 parameters */
252 msg = capimsg_setu8(msg, 0); /* B3 parameters */
254 msg = capimsg_setu8(msg, 0); /* Bearer Capability */
255 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
256 msg = capimsg_setu8(msg, 0); /* High Layer Compatibility */
257 msg = capimsg_setu8(msg, 0); /* Additional Info */
262 void capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
264 u_int8_t *msg = mtod(m_in, u_int8_t*);
271 msg = capimsg_getu16(msg + 6, &msgid);
272 msg = capimsg_getu32(msg, &PLCI);
273 msg = capimsg_getu16(msg, &Info);
275 for (bch = 0; bch < sc->sc_nbch; bch++)
276 if ((sc->sc_bchan[bch].state == B_CONNECT_CONF) &&
277 (sc->sc_bchan[bch].msgid == msgid))
280 if ((bch == sc->sc_nbch) ||
281 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
282 printf("capi%d: can't find channel for connect_conf PLCI %x\n",
288 sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
289 sc->sc_bchan[bch].ncci = PLCI;
291 i4b_l4_proceeding_ind(cd);
294 SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
295 i4b_l4_disconnect_ind(cd);
298 sc->sc_bchan[bch].state = B_FREE;
299 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
301 printf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
305 void capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
307 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
308 u_int8_t *msg = mtod(m_in, u_int8_t*);
310 u_int16_t applid, msgid;
315 printf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
319 msg = capimsg_getu16(msg + 2, &applid);
320 msg = capimsg_getu16(msg + 2, &msgid);
321 msg = capimsg_getu32(msg, &PLCI);
323 for (bch = 0; bch < sc->sc_nbch; bch++)
324 if ((sc->sc_bchan[bch].state == B_CONNECT_ACTIVE_IND) &&
325 (sc->sc_bchan[bch].ncci == PLCI))
328 if ((bch == sc->sc_nbch) ||
329 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
330 printf("capi%d: can't find channel for active_resp, PLCI %x\n",
335 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
336 msg = capimsg_setu16(msg, applid);
337 msg = capimsg_setu16(msg, CAPI_CONNECT_ACTIVE_RESP);
338 msg = capimsg_setu16(msg, msgid);
340 msg = capimsg_setu32(msg, PLCI);
344 if (cd->crflag == CRF_ORIG) {
345 capi_connect_b3_req(sc, cd);
348 sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
352 void capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
354 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
360 printf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
364 sc->sc_bchan[cd->channelid].state = B_CONNECT_B3_CONF;
365 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
366 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
368 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
369 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
370 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_REQ);
371 msg = capimsg_setu16(msg, msgid);
373 msg = capimsg_setu32(msg, PLCI);
374 msg = capimsg_setu8(msg, 0); /* NCPI */
379 void capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
381 u_int8_t *msg = mtod(m_in, u_int8_t*);
388 msg = capimsg_getu16(msg + 6, &msgid);
389 msg = capimsg_getu32(msg, &NCCI);
390 msg = capimsg_getu16(msg, &Info);
392 for (bch = 0; bch < sc->sc_nbch; bch++)
393 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_CONF) &&
394 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
397 if ((bch == sc->sc_nbch) ||
398 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
399 printf("capi%d: can't find channel for connect_b3_conf NCCI %x\n",
405 sc->sc_bchan[bch].ncci = NCCI;
406 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
409 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
410 i4b_l4_disconnect_ind(cd);
413 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_RSVD;
415 printf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
417 capi_disconnect_req(sc, cd);
421 void capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
423 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
424 u_int8_t *msg = mtod(m_in, u_int8_t*);
426 u_int16_t applid, msgid;
431 printf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
435 msg = capimsg_getu16(msg + 2, &applid);
436 msg = capimsg_getu16(msg + 2, &msgid);
437 msg = capimsg_getu32(msg, &NCCI);
439 for (bch = 0; bch < sc->sc_nbch; bch++)
440 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_ACTIVE_IND) &&
441 (sc->sc_bchan[bch].ncci == NCCI))
444 if ((bch == sc->sc_nbch) ||
445 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
446 printf("capi%d: can't find channel for b3_active_resp NCCI %x\n",
451 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
452 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
453 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_ACTIVE_RESP);
454 msg = capimsg_setu16(msg, msgid);
456 msg = capimsg_setu32(msg, NCCI);
460 sc->sc_bchan[bch].state = B_CONNECTED;
461 i4b_l4_connect_active_ind(cd);
465 // Incoming call setup:
466 // --------------------
468 // <-- CAPI_CONNECT_IND
470 // CAPI_CONNECT_RESP -->
471 // <-- CAPI_CONNECT_ACTIVE_IND
472 // CAPI_CONNECT_ACTIVE_RESP -->
473 // <-- CAPI_CONNECT_B3_IND
474 // CAPI_CONNECT_B3_RESP -->
475 // <-- CAPI_CONNECT_B3_ACTIVE_IND
476 // CAPI_CONNECT_B3_ACTIVE_RESP -->
480 void capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
482 u_int8_t *msg = mtod(m_in, u_int8_t*);
484 u_int16_t applid, msgid;
490 if ((cd = reserve_cd()) == NULL) {
491 printf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
495 cd->controller = sc->ctrl_unit;
496 cd->channelexcl = FALSE;
498 for (bch = 0; bch < sc->sc_nbch; bch++)
499 if (sc->sc_bchan[bch].state == B_FREE) break;
500 sc->sc_bchan[bch].state = B_CONNECT_IND;
501 cd->channelid = bch; /* XXX CHAN_ANY XXX */
503 cd->crflag = CRF_DEST;
504 cd->cr = get_rand_cr(sc->sc_unit);
505 cd->scr_ind = SCR_NONE;
506 cd->prs_ind = PRS_NONE;
507 cd->bprot = BPROT_NONE;
510 cd->display[0] = '\0';
511 cd->datetime[0] = '\0';
513 msg = capimsg_getu16(msg + 2, &applid);
514 msg = capimsg_getu16(msg + 2, &msgid);
515 msg = capimsg_getu32(msg, &PLCI);
516 msg = capimsg_getu16(msg, &CIP);
518 cd->event = (int) msgid; /* XXX overload */
519 cd->Q931state = (int) PLCI; /* XXX overload */
523 case 0x0001: cd->bprot = BPROT_NONE; break;
524 case 0x0002: cd->bprot = BPROT_RHDLC; break;
526 NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
527 cd->bprot = BPROT_NONE;
530 msg = capimsg_getu8(msg, &x); /* Called party struct len */
532 msg = capimsg_getu8(msg, &y); /* Numbering plan */
534 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
535 strncpy(cd->dst_telno, msg, z);
539 cd->dst_telno[x] = '\0';
541 msg = capimsg_getu8(msg, &x); /* Calling party struct len */
543 msg = capimsg_getu8(msg, &y); /* Numbering plan */
544 msg = capimsg_getu8(msg, &y); /* Screening/Presentation */
545 if ((y & 0x80) == 0) { /* screening used */
546 cd->scr_ind = (y & 3) + SCR_USR_NOSC;
547 cd->prs_ind = ((y >> 5) & 3) + PRS_ALLOWED;
550 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
551 strncpy(cd->src_telno, msg, z);
555 cd->src_telno[x] = '\0';
557 i4b_l4_connect_ind(cd);
560 void capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
566 int dlen = strlen(cd->dst_telno);
568 m = i4b_Dgetmbuf(8 + 21 + dlen);
570 printf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
574 msgid = (u_int16_t) cd->event;
575 PLCI = (u_int32_t) cd->Q931state;
577 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
578 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
579 msg = capimsg_setu16(msg, CAPI_CONNECT_RESP);
580 msg = capimsg_setu16(msg, msgid);
582 msg = capimsg_setu32(msg, PLCI);
584 switch (cd->response) {
585 case SETUP_RESP_ACCEPT:
586 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
587 sc->sc_bchan[cd->channelid].ncci = PLCI;
588 sc->sc_bchan[cd->channelid].state = B_CONNECT_ACTIVE_IND;
589 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_USED;
590 msg = capimsg_setu16(msg, 0); /* Accept the call */
593 case SETUP_RESP_REJECT:
594 sc->sc_bchan[cd->channelid].state = B_FREE;
595 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
596 msg = capimsg_setu16(msg, 2); /* Reject, normal call clearing */
599 case SETUP_RESP_DNTCRE:
600 sc->sc_bchan[cd->channelid].state = B_FREE;
601 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
602 if (sc->sc_nbch == 30) {
603 /* With PRI, we can't really ignore calls -- normal clearing */
604 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_NCCLR));
606 msg = capimsg_setu16(msg, 1); /* Ignore */
611 sc->sc_bchan[cd->channelid].state = B_FREE;
612 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
613 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_CALLREJ));
616 msg = capimsg_setu8(msg, 15); /* B protocol */
617 if (cd->bprot == BPROT_NONE)
618 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
620 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
621 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
622 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
623 msg = capimsg_setu8(msg, 0); /* B1 parameters */
624 msg = capimsg_setu8(msg, 0); /* B2 parameters */
625 msg = capimsg_setu8(msg, 0); /* B3 parameters */
627 msg = capimsg_setu8(msg, 1 + dlen);
628 msg = capimsg_setu8(msg, 0x80); /* Numbering plan */
629 strncpy(msg, cd->dst_telno, dlen);
630 msg = capimsg_setu8(msg + dlen, 0); /* Connected subaddress */
631 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
632 msg = capimsg_setu8(msg, 0); /* Additional Info */
637 void capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
639 struct mbuf *m = i4b_Dgetmbuf(8 + 7);
640 u_int8_t *msg = mtod(m_in, u_int8_t*);
641 u_int16_t applid, msgid;
646 printf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
650 msg = capimsg_getu16(msg + 2, &applid);
651 msg = capimsg_getu16(msg + 2, &msgid);
652 msg = capimsg_getu32(msg, &NCCI);
654 for (bch = 0; bch < sc->sc_nbch; bch++)
655 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_IND) &&
656 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
659 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
660 msg = capimsg_setu16(msg, applid);
661 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_RESP);
662 msg = capimsg_setu16(msg, msgid);
664 msg = capimsg_setu32(msg, NCCI);
666 if (bch == sc->sc_nbch) {
667 printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
669 msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
672 sc->sc_bchan[bch].ncci = NCCI;
673 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
674 msg = capimsg_setu16(msg, 0); /* Accept */
677 msg = capimsg_setu8(msg, 0); /* NCPI */
687 void capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
689 struct mbuf *m = i4b_Dgetmbuf(8 + 14);
694 printf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
698 msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
699 sc->sc_bchan[chan].busy = 1;
701 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
702 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
703 msg = capimsg_setu16(msg, CAPI_DATA_B3_REQ);
704 msg = capimsg_setu16(msg, msgid);
706 msg = capimsg_setu32(msg, sc->sc_bchan[chan].ncci);
707 msg = capimsg_setu32(msg, (u_int32_t) m_b3->m_data); /* Pointer */
708 msg = capimsg_setu16(msg, m_b3->m_len);
709 msg = capimsg_setu16(msg, chan);
710 msg = capimsg_setu16(msg, 0); /* Flags */
717 void capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
719 u_int8_t *msg = mtod(m_in, u_int8_t*);
724 msg = capimsg_getu32(msg + 8, &NCCI);
725 msg = capimsg_getu16(msg, &handle);
726 msg = capimsg_getu16(msg, &Info);
729 sc->sc_bchan[handle].busy = 0;
730 capi_start_tx(sc, handle);
733 printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
734 sc->sc_unit, NCCI, handle, Info);
738 void capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
740 struct mbuf *m = i4b_Dgetmbuf(8 + 6);
741 u_int8_t *msg = mtod(m_in, u_int8_t*);
742 u_int16_t applid, msgid;
748 printf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
752 msg = capimsg_getu16(msg + 2, &applid);
753 msg = capimsg_getu16(msg + 2, &msgid);
754 msg = capimsg_getu32(msg, &NCCI);
755 msg = capimsg_getu16(msg + 6, &handle);
757 for (bch = 0; bch < sc->sc_nbch; bch++)
758 if ((sc->sc_bchan[bch].state == B_CONNECTED) &&
759 (sc->sc_bchan[bch].ncci == NCCI))
762 if (bch == sc->sc_nbch) {
763 printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
767 if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
768 /* HDLC drivers use rx_mbuf */
770 sc->sc_bchan[bch].in_mbuf = m_in->m_next;
771 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
772 m_in->m_next = NULL; /* driver frees */
774 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
775 sc->sc_bchan[bch].capi_drvr_linktab->unit);
778 /* Telephony drivers use rx_queue */
780 if (!_IF_QFULL(&sc->sc_bchan[bch].rx_queue)) {
781 _IF_ENQUEUE(&sc->sc_bchan[bch].rx_queue, m_in->m_next);
782 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
783 m_in->m_next = NULL; /* driver frees */
786 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
787 sc->sc_bchan[bch].capi_drvr_linktab->unit);
791 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
792 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
793 msg = capimsg_setu16(msg, CAPI_DATA_B3_RESP);
794 msg = capimsg_setu16(msg, msgid);
796 msg = capimsg_setu32(msg, NCCI);
797 msg = capimsg_setu16(msg, handle);
803 // Connection teardown:
804 // --------------------
807 void capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
809 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
815 printf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
819 sc->sc_bchan[cd->channelid].state = B_DISCONNECT_CONF;
820 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
821 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
822 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
824 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
825 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
826 msg = capimsg_setu16(msg, CAPI_DISCONNECT_REQ);
827 msg = capimsg_setu16(msg, msgid);
829 msg = capimsg_setu32(msg, PLCI);
830 msg = capimsg_setu8(msg, 0); /* Additional Info */
835 void capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
837 u_int8_t *msg = mtod(m_in, u_int8_t*);
842 msg = capimsg_getu32(msg + 8, &PLCI);
844 for (bch = 0; bch < sc->sc_nbch; bch++)
845 if ((sc->sc_bchan[bch].state == B_DISCONNECT_CONF) &&
846 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
849 if (bch == sc->sc_nbch) {
850 printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
855 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
857 printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
860 i4b_l4_disconnect_ind(cd);
864 sc->sc_bchan[bch].state = B_FREE;
865 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
868 void capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
870 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
871 u_int8_t *msg = mtod(m_in, u_int8_t*);
872 u_int16_t applid, msgid;
876 printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
880 msg = capimsg_getu16(msg + 2, &applid);
881 msg = capimsg_getu16(msg + 2, &msgid);
882 msg = capimsg_getu32(msg, &NCCI);
884 /* XXX update bchan state? XXX */
886 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
887 msg = capimsg_setu16(msg, applid);
888 msg = capimsg_setu16(msg, CAPI_DISCONNECT_B3_RESP);
889 msg = capimsg_setu16(msg, msgid);
891 msg = capimsg_setu32(msg, NCCI);
896 void capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
898 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
899 u_int8_t *msg = mtod(m_in, u_int8_t*);
901 u_int16_t applid, msgid;
907 printf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
911 msg = capimsg_getu16(msg + 2, &applid);
912 msg = capimsg_getu16(msg + 2, &msgid);
913 msg = capimsg_getu32(msg, &PLCI);
914 msg = capimsg_getu16(msg, &Reason);
916 for (bch = 0; bch < sc->sc_nbch; bch++)
917 if ((sc->sc_bchan[bch].state != B_FREE) &&
918 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
921 if (bch < sc->sc_nbch) {
922 /* We may not have a bchan assigned if call was ignored. */
924 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
925 sc->sc_bchan[bch].state = B_DISCONNECT_IND;
929 if ((Reason & 0xff00) == 0x3400) {
930 SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
932 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
935 i4b_l4_disconnect_ind(cd);
938 sc->sc_bchan[bch].state = B_FREE;
939 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
942 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
943 msg = capimsg_setu16(msg, applid);
944 msg = capimsg_setu16(msg, CAPI_DISCONNECT_RESP);
945 msg = capimsg_setu16(msg, msgid);
947 msg = capimsg_setu32(msg, PLCI);