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.4 2003/08/07 21:54:30 dillon Exp $
31 #include "use_i4bcapi.h"
34 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/systm.h>
38 #include <sys/socket.h>
41 #include <net/i4b/include/machine/i4b_debug.h>
42 #include <net/i4b/include/machine/i4b_ioctl.h>
43 #include <net/i4b/include/machine/i4b_cause.h>
45 #include "../include/i4b_l3l4.h"
46 #include "../include/i4b_mbuf.h"
47 #include "../include/i4b_global.h"
48 #include "../layer4/i4b_l4.h"
51 #include "capi_msgs.h"
54 // Administrative messages:
55 // ------------------------
58 void capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
60 struct mbuf *m = i4b_Dgetmbuf(8 + 18);
65 printf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
69 msgid = sc->sc_msgid++;
71 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
72 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
73 msg = capimsg_setu16(msg, CAPI_LISTEN_REQ);
74 msg = capimsg_setu16(msg, msgid);
76 msg = capimsg_setu32(msg, 1); /* Controller */
77 msg = capimsg_setu32(msg, 0); /* Info mask */
78 msg = capimsg_setu32(msg, CIP);
79 msg = capimsg_setu32(msg, 0);
80 msg = capimsg_setu8(msg, 0);
81 msg = capimsg_setu8(msg, 0);
86 void capi_listen_conf(capi_softc_t *sc, struct mbuf *m_in)
88 u_int8_t *msg = mtod(m_in, u_int8_t*);
91 capimsg_getu16(msg + 12, &Info);
94 /* We are now listening. */
97 ctrl_desc[sc->ctrl_unit].dl_est = DL_UP;
99 i4b_l4_l12stat(sc->ctrl_unit, 1, 1);
100 i4b_l4_l12stat(sc->ctrl_unit, 2, 1);
103 /* XXX sc->sc_state = C_DOWN ? XXX */
104 printf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
108 void 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 printf("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);
136 void capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
138 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
144 printf("capi%d: can't get mbuf for alert_req\n", sc->sc_unit);
148 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
149 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
151 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
152 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
153 msg = capimsg_setu16(msg, CAPI_ALERT_REQ);
154 msg = capimsg_setu16(msg, msgid);
156 msg = capimsg_setu32(msg, PLCI);
157 msg = capimsg_setu8(msg, 0);
162 void capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
164 u_int8_t *msg = mtod(m_in, u_int8_t*);
167 msg = capimsg_getu16(msg + 12, &Info);
170 printf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
175 // Outgoing call setup:
176 // --------------------
178 // CAPI_CONNECT_REQ -->
179 // <-- CAPI_CONNECT_CONF
181 // <-- CAPI_CONNECT_ACTIVE_IND
182 // CAPI_CONNECT_ACTIVE_RESP -->
183 // CAPI_CONNECT_B3_REQ -->
184 // <-- CAPI_CONNECT_B3_CONF
185 // <-- CAPI_CONNECT_B3_ACTIVE_IND
186 // CAPI_CONNECT_B3_ACTIVE_RESP -->
190 void capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
195 int slen = strlen(cd->src_telno);
196 int dlen = strlen(cd->dst_telno);
198 m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
200 printf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
204 cd->crflag = CRF_ORIG;
206 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
207 sc->sc_bchan[cd->channelid].bprot = cd->bprot;
208 sc->sc_bchan[cd->channelid].state = B_CONNECT_CONF;
209 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
210 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
212 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
213 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
214 msg = capimsg_setu16(msg, CAPI_CONNECT_REQ);
215 msg = capimsg_setu16(msg, msgid);
217 msg = capimsg_setu32(msg, 1); /* Controller */
221 msg = capimsg_setu16(msg, 0x0010); /* Telephony */
225 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
229 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
232 msg = capimsg_setu8(msg, 1 + dlen);
233 msg = capimsg_setu8(msg, 0x80);
234 strncpy(msg, cd->dst_telno, dlen);
236 msg = capimsg_setu8(msg + dlen, 2 + slen);
237 msg = capimsg_setu8(msg, 0x00);
238 msg = capimsg_setu8(msg, 0x80); /* Presentation and screening indicator */
239 strncpy(msg, cd->src_telno, slen);
241 msg = capimsg_setu8(msg + slen, 0); /* Called & */
242 msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
244 msg = capimsg_setu8(msg, 15); /* B protocol */
245 if (cd->bprot == BPROT_NONE)
246 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
248 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
249 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
250 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
251 msg = capimsg_setu8(msg, 0); /* B1 parameters */
252 msg = capimsg_setu8(msg, 0); /* B2 parameters */
253 msg = capimsg_setu8(msg, 0); /* B3 parameters */
255 msg = capimsg_setu8(msg, 0); /* Bearer Capability */
256 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
257 msg = capimsg_setu8(msg, 0); /* High Layer Compatibility */
258 msg = capimsg_setu8(msg, 0); /* Additional Info */
263 void capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
265 u_int8_t *msg = mtod(m_in, u_int8_t*);
272 msg = capimsg_getu16(msg + 6, &msgid);
273 msg = capimsg_getu32(msg, &PLCI);
274 msg = capimsg_getu16(msg, &Info);
276 for (bch = 0; bch < sc->sc_nbch; bch++)
277 if ((sc->sc_bchan[bch].state == B_CONNECT_CONF) &&
278 (sc->sc_bchan[bch].msgid == msgid))
281 if ((bch == sc->sc_nbch) ||
282 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
283 printf("capi%d: can't find channel for connect_conf PLCI %x\n",
289 sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
290 sc->sc_bchan[bch].ncci = PLCI;
292 i4b_l4_proceeding_ind(cd);
295 SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
296 i4b_l4_disconnect_ind(cd);
299 sc->sc_bchan[bch].state = B_FREE;
300 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
302 printf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
306 void capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
308 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
309 u_int8_t *msg = mtod(m_in, u_int8_t*);
311 u_int16_t applid, msgid;
316 printf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
320 msg = capimsg_getu16(msg + 2, &applid);
321 msg = capimsg_getu16(msg + 2, &msgid);
322 msg = capimsg_getu32(msg, &PLCI);
324 for (bch = 0; bch < sc->sc_nbch; bch++)
325 if ((sc->sc_bchan[bch].state == B_CONNECT_ACTIVE_IND) &&
326 (sc->sc_bchan[bch].ncci == PLCI))
329 if ((bch == sc->sc_nbch) ||
330 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
331 printf("capi%d: can't find channel for active_resp, PLCI %x\n",
336 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
337 msg = capimsg_setu16(msg, applid);
338 msg = capimsg_setu16(msg, CAPI_CONNECT_ACTIVE_RESP);
339 msg = capimsg_setu16(msg, msgid);
341 msg = capimsg_setu32(msg, PLCI);
345 if (cd->crflag == CRF_ORIG) {
346 capi_connect_b3_req(sc, cd);
349 sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
353 void capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
355 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
361 printf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
365 sc->sc_bchan[cd->channelid].state = B_CONNECT_B3_CONF;
366 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
367 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
369 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
370 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
371 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_REQ);
372 msg = capimsg_setu16(msg, msgid);
374 msg = capimsg_setu32(msg, PLCI);
375 msg = capimsg_setu8(msg, 0); /* NCPI */
380 void capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
382 u_int8_t *msg = mtod(m_in, u_int8_t*);
389 msg = capimsg_getu16(msg + 6, &msgid);
390 msg = capimsg_getu32(msg, &NCCI);
391 msg = capimsg_getu16(msg, &Info);
393 for (bch = 0; bch < sc->sc_nbch; bch++)
394 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_CONF) &&
395 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
398 if ((bch == sc->sc_nbch) ||
399 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
400 printf("capi%d: can't find channel for connect_b3_conf NCCI %x\n",
406 sc->sc_bchan[bch].ncci = NCCI;
407 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
410 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
411 i4b_l4_disconnect_ind(cd);
414 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_RSVD;
416 printf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
418 capi_disconnect_req(sc, cd);
422 void capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
424 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
425 u_int8_t *msg = mtod(m_in, u_int8_t*);
427 u_int16_t applid, msgid;
432 printf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
436 msg = capimsg_getu16(msg + 2, &applid);
437 msg = capimsg_getu16(msg + 2, &msgid);
438 msg = capimsg_getu32(msg, &NCCI);
440 for (bch = 0; bch < sc->sc_nbch; bch++)
441 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_ACTIVE_IND) &&
442 (sc->sc_bchan[bch].ncci == NCCI))
445 if ((bch == sc->sc_nbch) ||
446 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
447 printf("capi%d: can't find channel for b3_active_resp NCCI %x\n",
452 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
453 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
454 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_ACTIVE_RESP);
455 msg = capimsg_setu16(msg, msgid);
457 msg = capimsg_setu32(msg, NCCI);
461 sc->sc_bchan[bch].state = B_CONNECTED;
462 i4b_l4_connect_active_ind(cd);
466 // Incoming call setup:
467 // --------------------
469 // <-- CAPI_CONNECT_IND
471 // CAPI_CONNECT_RESP -->
472 // <-- CAPI_CONNECT_ACTIVE_IND
473 // CAPI_CONNECT_ACTIVE_RESP -->
474 // <-- CAPI_CONNECT_B3_IND
475 // CAPI_CONNECT_B3_RESP -->
476 // <-- CAPI_CONNECT_B3_ACTIVE_IND
477 // CAPI_CONNECT_B3_ACTIVE_RESP -->
481 void capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
483 u_int8_t *msg = mtod(m_in, u_int8_t*);
485 u_int16_t applid, msgid;
491 if ((cd = reserve_cd()) == NULL) {
492 printf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
496 cd->controller = sc->ctrl_unit;
497 cd->channelexcl = FALSE;
499 for (bch = 0; bch < sc->sc_nbch; bch++)
500 if (sc->sc_bchan[bch].state == B_FREE) break;
501 sc->sc_bchan[bch].state = B_CONNECT_IND;
502 cd->channelid = bch; /* XXX CHAN_ANY XXX */
504 cd->crflag = CRF_DEST;
505 cd->cr = get_rand_cr(sc->sc_unit);
506 cd->scr_ind = SCR_NONE;
507 cd->prs_ind = PRS_NONE;
508 cd->bprot = BPROT_NONE;
511 cd->display[0] = '\0';
512 cd->datetime[0] = '\0';
514 msg = capimsg_getu16(msg + 2, &applid);
515 msg = capimsg_getu16(msg + 2, &msgid);
516 msg = capimsg_getu32(msg, &PLCI);
517 msg = capimsg_getu16(msg, &CIP);
519 cd->event = (int) msgid; /* XXX overload */
520 cd->Q931state = (int) PLCI; /* XXX overload */
524 case 0x0001: cd->bprot = BPROT_NONE; break;
525 case 0x0002: cd->bprot = BPROT_RHDLC; break;
527 NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
528 cd->bprot = BPROT_NONE;
531 msg = capimsg_getu8(msg, &x); /* Called party struct len */
533 msg = capimsg_getu8(msg, &y); /* Numbering plan */
535 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
536 strncpy(cd->dst_telno, msg, z);
540 cd->dst_telno[x] = '\0';
542 msg = capimsg_getu8(msg, &x); /* Calling party struct len */
544 msg = capimsg_getu8(msg, &y); /* Numbering plan */
545 msg = capimsg_getu8(msg, &y); /* Screening/Presentation */
546 if ((y & 0x80) == 0) { /* screening used */
547 cd->scr_ind = (y & 3) + SCR_USR_NOSC;
548 cd->prs_ind = ((y >> 5) & 3) + PRS_ALLOWED;
551 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
552 strncpy(cd->src_telno, msg, z);
556 cd->src_telno[x] = '\0';
558 i4b_l4_connect_ind(cd);
561 void capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
567 int dlen = strlen(cd->dst_telno);
569 m = i4b_Dgetmbuf(8 + 21 + dlen);
571 printf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
575 msgid = (u_int16_t) cd->event;
576 PLCI = (u_int32_t) cd->Q931state;
578 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
579 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
580 msg = capimsg_setu16(msg, CAPI_CONNECT_RESP);
581 msg = capimsg_setu16(msg, msgid);
583 msg = capimsg_setu32(msg, PLCI);
585 switch (cd->response) {
586 case SETUP_RESP_ACCEPT:
587 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
588 sc->sc_bchan[cd->channelid].ncci = PLCI;
589 sc->sc_bchan[cd->channelid].state = B_CONNECT_ACTIVE_IND;
590 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_USED;
591 msg = capimsg_setu16(msg, 0); /* Accept the call */
594 case SETUP_RESP_REJECT:
595 sc->sc_bchan[cd->channelid].state = B_FREE;
596 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
597 msg = capimsg_setu16(msg, 2); /* Reject, normal call clearing */
600 case SETUP_RESP_DNTCRE:
601 sc->sc_bchan[cd->channelid].state = B_FREE;
602 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
603 if (sc->sc_nbch == 30) {
604 /* With PRI, we can't really ignore calls -- normal clearing */
605 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_NCCLR));
607 msg = capimsg_setu16(msg, 1); /* Ignore */
612 sc->sc_bchan[cd->channelid].state = B_FREE;
613 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
614 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_CALLREJ));
617 msg = capimsg_setu8(msg, 15); /* B protocol */
618 if (cd->bprot == BPROT_NONE)
619 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
621 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
622 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
623 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
624 msg = capimsg_setu8(msg, 0); /* B1 parameters */
625 msg = capimsg_setu8(msg, 0); /* B2 parameters */
626 msg = capimsg_setu8(msg, 0); /* B3 parameters */
628 msg = capimsg_setu8(msg, 1 + dlen);
629 msg = capimsg_setu8(msg, 0x80); /* Numbering plan */
630 strncpy(msg, cd->dst_telno, dlen);
631 msg = capimsg_setu8(msg + dlen, 0); /* Connected subaddress */
632 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
633 msg = capimsg_setu8(msg, 0); /* Additional Info */
638 void capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
640 struct mbuf *m = i4b_Dgetmbuf(8 + 7);
641 u_int8_t *msg = mtod(m_in, u_int8_t*);
642 u_int16_t applid, msgid;
647 printf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
651 msg = capimsg_getu16(msg + 2, &applid);
652 msg = capimsg_getu16(msg + 2, &msgid);
653 msg = capimsg_getu32(msg, &NCCI);
655 for (bch = 0; bch < sc->sc_nbch; bch++)
656 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_IND) &&
657 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
660 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
661 msg = capimsg_setu16(msg, applid);
662 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_RESP);
663 msg = capimsg_setu16(msg, msgid);
665 msg = capimsg_setu32(msg, NCCI);
667 if (bch == sc->sc_nbch) {
668 printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
670 msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
673 sc->sc_bchan[bch].ncci = NCCI;
674 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
675 msg = capimsg_setu16(msg, 0); /* Accept */
678 msg = capimsg_setu8(msg, 0); /* NCPI */
688 void capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
690 struct mbuf *m = i4b_Dgetmbuf(8 + 14);
695 printf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
699 msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
700 sc->sc_bchan[chan].busy = 1;
702 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
703 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
704 msg = capimsg_setu16(msg, CAPI_DATA_B3_REQ);
705 msg = capimsg_setu16(msg, msgid);
707 msg = capimsg_setu32(msg, sc->sc_bchan[chan].ncci);
708 msg = capimsg_setu32(msg, (u_int32_t) m_b3->m_data); /* Pointer */
709 msg = capimsg_setu16(msg, m_b3->m_len);
710 msg = capimsg_setu16(msg, chan);
711 msg = capimsg_setu16(msg, 0); /* Flags */
718 void capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
720 u_int8_t *msg = mtod(m_in, u_int8_t*);
725 msg = capimsg_getu32(msg + 8, &NCCI);
726 msg = capimsg_getu16(msg, &handle);
727 msg = capimsg_getu16(msg, &Info);
730 sc->sc_bchan[handle].busy = 0;
731 capi_start_tx(sc, handle);
734 printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
735 sc->sc_unit, NCCI, handle, Info);
739 void capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
741 struct mbuf *m = i4b_Dgetmbuf(8 + 6);
742 u_int8_t *msg = mtod(m_in, u_int8_t*);
743 u_int16_t applid, msgid;
749 printf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
753 msg = capimsg_getu16(msg + 2, &applid);
754 msg = capimsg_getu16(msg + 2, &msgid);
755 msg = capimsg_getu32(msg, &NCCI);
756 msg = capimsg_getu16(msg + 6, &handle);
758 for (bch = 0; bch < sc->sc_nbch; bch++)
759 if ((sc->sc_bchan[bch].state == B_CONNECTED) &&
760 (sc->sc_bchan[bch].ncci == NCCI))
763 if (bch == sc->sc_nbch) {
764 printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
768 if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
769 /* HDLC drivers use rx_mbuf */
771 sc->sc_bchan[bch].in_mbuf = m_in->m_next;
772 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
773 m_in->m_next = NULL; /* driver frees */
775 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
776 sc->sc_bchan[bch].capi_drvr_linktab->unit);
779 /* Telephony drivers use rx_queue */
781 if (!_IF_QFULL(&sc->sc_bchan[bch].rx_queue)) {
782 _IF_ENQUEUE(&sc->sc_bchan[bch].rx_queue, m_in->m_next);
783 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
784 m_in->m_next = NULL; /* driver frees */
787 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
788 sc->sc_bchan[bch].capi_drvr_linktab->unit);
792 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
793 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
794 msg = capimsg_setu16(msg, CAPI_DATA_B3_RESP);
795 msg = capimsg_setu16(msg, msgid);
797 msg = capimsg_setu32(msg, NCCI);
798 msg = capimsg_setu16(msg, handle);
804 // Connection teardown:
805 // --------------------
808 void capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
810 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
816 printf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
820 sc->sc_bchan[cd->channelid].state = B_DISCONNECT_CONF;
821 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
822 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
823 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
825 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
826 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
827 msg = capimsg_setu16(msg, CAPI_DISCONNECT_REQ);
828 msg = capimsg_setu16(msg, msgid);
830 msg = capimsg_setu32(msg, PLCI);
831 msg = capimsg_setu8(msg, 0); /* Additional Info */
836 void capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
838 u_int8_t *msg = mtod(m_in, u_int8_t*);
843 msg = capimsg_getu32(msg + 8, &PLCI);
845 for (bch = 0; bch < sc->sc_nbch; bch++)
846 if ((sc->sc_bchan[bch].state == B_DISCONNECT_CONF) &&
847 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
850 if (bch == sc->sc_nbch) {
851 printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
856 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
858 printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
861 i4b_l4_disconnect_ind(cd);
865 sc->sc_bchan[bch].state = B_FREE;
866 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
869 void capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
871 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
872 u_int8_t *msg = mtod(m_in, u_int8_t*);
873 u_int16_t applid, msgid;
877 printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
881 msg = capimsg_getu16(msg + 2, &applid);
882 msg = capimsg_getu16(msg + 2, &msgid);
883 msg = capimsg_getu32(msg, &NCCI);
885 /* XXX update bchan state? XXX */
887 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
888 msg = capimsg_setu16(msg, applid);
889 msg = capimsg_setu16(msg, CAPI_DISCONNECT_B3_RESP);
890 msg = capimsg_setu16(msg, msgid);
892 msg = capimsg_setu32(msg, NCCI);
897 void capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
899 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
900 u_int8_t *msg = mtod(m_in, u_int8_t*);
902 u_int16_t applid, msgid;
908 printf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
912 msg = capimsg_getu16(msg + 2, &applid);
913 msg = capimsg_getu16(msg + 2, &msgid);
914 msg = capimsg_getu32(msg, &PLCI);
915 msg = capimsg_getu16(msg, &Reason);
917 for (bch = 0; bch < sc->sc_nbch; bch++)
918 if ((sc->sc_bchan[bch].state != B_FREE) &&
919 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
922 if (bch < sc->sc_nbch) {
923 /* We may not have a bchan assigned if call was ignored. */
925 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
926 sc->sc_bchan[bch].state = B_DISCONNECT_IND;
930 if ((Reason & 0xff00) == 0x3400) {
931 SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
933 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
936 i4b_l4_disconnect_ind(cd);
939 sc->sc_bchan[bch].state = B_FREE;
940 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
943 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
944 msg = capimsg_setu16(msg, applid);
945 msg = capimsg_setu16(msg, CAPI_DISCONNECT_RESP);
946 msg = capimsg_setu16(msg, msgid);
948 msg = capimsg_setu32(msg, PLCI);
953 #endif /* NI4BCAPI > 0 */