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.2 2003/06/17 04:28:39 dillon Exp $
34 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/systm.h>
38 #include <sys/socket.h>
41 #include <machine/i4b_debug.h>
42 #include <machine/i4b_ioctl.h>
43 #include <machine/i4b_cause.h>
45 #include <i4b/include/i4b_l3l4.h>
46 #include <i4b/include/i4b_mbuf.h>
47 #include <i4b/include/i4b_global.h>
49 #include <i4b/layer4/i4b_l4.h>
51 #include <i4b/capi/capi.h>
52 #include <i4b/capi/capi_msgs.h>
55 // Administrative messages:
56 // ------------------------
59 void capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
61 struct mbuf *m = i4b_Dgetmbuf(8 + 18);
66 printf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
70 msgid = sc->sc_msgid++;
72 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
73 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
74 msg = capimsg_setu16(msg, CAPI_LISTEN_REQ);
75 msg = capimsg_setu16(msg, msgid);
77 msg = capimsg_setu32(msg, 1); /* Controller */
78 msg = capimsg_setu32(msg, 0); /* Info mask */
79 msg = capimsg_setu32(msg, CIP);
80 msg = capimsg_setu32(msg, 0);
81 msg = capimsg_setu8(msg, 0);
82 msg = capimsg_setu8(msg, 0);
87 void capi_listen_conf(capi_softc_t *sc, struct mbuf *m_in)
89 u_int8_t *msg = mtod(m_in, u_int8_t*);
92 capimsg_getu16(msg + 12, &Info);
95 /* We are now listening. */
98 ctrl_desc[sc->ctrl_unit].dl_est = DL_UP;
100 i4b_l4_l12stat(sc->ctrl_unit, 1, 1);
101 i4b_l4_l12stat(sc->ctrl_unit, 2, 1);
104 /* XXX sc->sc_state = C_DOWN ? XXX */
105 printf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
109 void capi_info_ind(capi_softc_t *sc, struct mbuf *m_in)
111 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
112 u_int8_t *msg = mtod(m_in, u_int8_t*);
113 u_int16_t applid, msgid;
117 printf("capi%d: can't get mbuf for info_resp\n", sc->sc_unit);
121 msg = capimsg_getu16(msg + 2, &applid);
122 msg = capimsg_getu16(msg + 2, &msgid);
123 msg = capimsg_getu32(msg, &PLCI);
125 /* i4b_l4_info_ind() */
127 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
128 msg = capimsg_setu16(msg, applid);
129 msg = capimsg_setu16(msg, CAPI_INFO_RESP);
130 msg = capimsg_setu16(msg, msgid);
132 msg = capimsg_setu32(msg, PLCI);
137 void capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
139 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
145 printf("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);
163 void capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
165 u_int8_t *msg = mtod(m_in, u_int8_t*);
168 msg = capimsg_getu16(msg + 12, &Info);
171 printf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
176 // Outgoing call setup:
177 // --------------------
179 // CAPI_CONNECT_REQ -->
180 // <-- CAPI_CONNECT_CONF
182 // <-- CAPI_CONNECT_ACTIVE_IND
183 // CAPI_CONNECT_ACTIVE_RESP -->
184 // CAPI_CONNECT_B3_REQ -->
185 // <-- CAPI_CONNECT_B3_CONF
186 // <-- CAPI_CONNECT_B3_ACTIVE_IND
187 // CAPI_CONNECT_B3_ACTIVE_RESP -->
191 void capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
196 int slen = strlen(cd->src_telno);
197 int dlen = strlen(cd->dst_telno);
199 m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
201 printf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
205 cd->crflag = CRF_ORIG;
207 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
208 sc->sc_bchan[cd->channelid].bprot = cd->bprot;
209 sc->sc_bchan[cd->channelid].state = B_CONNECT_CONF;
210 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
211 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
213 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
214 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
215 msg = capimsg_setu16(msg, CAPI_CONNECT_REQ);
216 msg = capimsg_setu16(msg, msgid);
218 msg = capimsg_setu32(msg, 1); /* Controller */
222 msg = capimsg_setu16(msg, 0x0010); /* Telephony */
226 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
230 msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
233 msg = capimsg_setu8(msg, 1 + dlen);
234 msg = capimsg_setu8(msg, 0x80);
235 strncpy(msg, cd->dst_telno, dlen);
237 msg = capimsg_setu8(msg + dlen, 2 + slen);
238 msg = capimsg_setu8(msg, 0x00);
239 msg = capimsg_setu8(msg, 0x80); /* Presentation and screening indicator */
240 strncpy(msg, cd->src_telno, slen);
242 msg = capimsg_setu8(msg + slen, 0); /* Called & */
243 msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
245 msg = capimsg_setu8(msg, 15); /* B protocol */
246 if (cd->bprot == BPROT_NONE)
247 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
249 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
250 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
251 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
252 msg = capimsg_setu8(msg, 0); /* B1 parameters */
253 msg = capimsg_setu8(msg, 0); /* B2 parameters */
254 msg = capimsg_setu8(msg, 0); /* B3 parameters */
256 msg = capimsg_setu8(msg, 0); /* Bearer Capability */
257 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
258 msg = capimsg_setu8(msg, 0); /* High Layer Compatibility */
259 msg = capimsg_setu8(msg, 0); /* Additional Info */
264 void capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
266 u_int8_t *msg = mtod(m_in, u_int8_t*);
273 msg = capimsg_getu16(msg + 6, &msgid);
274 msg = capimsg_getu32(msg, &PLCI);
275 msg = capimsg_getu16(msg, &Info);
277 for (bch = 0; bch < sc->sc_nbch; bch++)
278 if ((sc->sc_bchan[bch].state == B_CONNECT_CONF) &&
279 (sc->sc_bchan[bch].msgid == msgid))
282 if ((bch == sc->sc_nbch) ||
283 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
284 printf("capi%d: can't find channel for connect_conf PLCI %x\n",
290 sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
291 sc->sc_bchan[bch].ncci = PLCI;
293 i4b_l4_proceeding_ind(cd);
296 SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
297 i4b_l4_disconnect_ind(cd);
300 sc->sc_bchan[bch].state = B_FREE;
301 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
303 printf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
307 void capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
309 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
310 u_int8_t *msg = mtod(m_in, u_int8_t*);
312 u_int16_t applid, msgid;
317 printf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
321 msg = capimsg_getu16(msg + 2, &applid);
322 msg = capimsg_getu16(msg + 2, &msgid);
323 msg = capimsg_getu32(msg, &PLCI);
325 for (bch = 0; bch < sc->sc_nbch; bch++)
326 if ((sc->sc_bchan[bch].state == B_CONNECT_ACTIVE_IND) &&
327 (sc->sc_bchan[bch].ncci == PLCI))
330 if ((bch == sc->sc_nbch) ||
331 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
332 printf("capi%d: can't find channel for active_resp, PLCI %x\n",
337 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
338 msg = capimsg_setu16(msg, applid);
339 msg = capimsg_setu16(msg, CAPI_CONNECT_ACTIVE_RESP);
340 msg = capimsg_setu16(msg, msgid);
342 msg = capimsg_setu32(msg, PLCI);
346 if (cd->crflag == CRF_ORIG) {
347 capi_connect_b3_req(sc, cd);
350 sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
354 void capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
356 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
362 printf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
366 sc->sc_bchan[cd->channelid].state = B_CONNECT_B3_CONF;
367 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
368 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
370 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
371 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
372 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_REQ);
373 msg = capimsg_setu16(msg, msgid);
375 msg = capimsg_setu32(msg, PLCI);
376 msg = capimsg_setu8(msg, 0); /* NCPI */
381 void capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
383 u_int8_t *msg = mtod(m_in, u_int8_t*);
390 msg = capimsg_getu16(msg + 6, &msgid);
391 msg = capimsg_getu32(msg, &NCCI);
392 msg = capimsg_getu16(msg, &Info);
394 for (bch = 0; bch < sc->sc_nbch; bch++)
395 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_CONF) &&
396 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
399 if ((bch == sc->sc_nbch) ||
400 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
401 printf("capi%d: can't find channel for connect_b3_conf NCCI %x\n",
407 sc->sc_bchan[bch].ncci = NCCI;
408 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
411 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
412 i4b_l4_disconnect_ind(cd);
415 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_RSVD;
417 printf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
419 capi_disconnect_req(sc, cd);
423 void capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
425 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
426 u_int8_t *msg = mtod(m_in, u_int8_t*);
428 u_int16_t applid, msgid;
433 printf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
437 msg = capimsg_getu16(msg + 2, &applid);
438 msg = capimsg_getu16(msg + 2, &msgid);
439 msg = capimsg_getu32(msg, &NCCI);
441 for (bch = 0; bch < sc->sc_nbch; bch++)
442 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_ACTIVE_IND) &&
443 (sc->sc_bchan[bch].ncci == NCCI))
446 if ((bch == sc->sc_nbch) ||
447 (cd = cd_by_cdid(sc->sc_bchan[bch].cdid)) == NULL) {
448 printf("capi%d: can't find channel for b3_active_resp NCCI %x\n",
453 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
454 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
455 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_ACTIVE_RESP);
456 msg = capimsg_setu16(msg, msgid);
458 msg = capimsg_setu32(msg, NCCI);
462 sc->sc_bchan[bch].state = B_CONNECTED;
463 i4b_l4_connect_active_ind(cd);
467 // Incoming call setup:
468 // --------------------
470 // <-- CAPI_CONNECT_IND
472 // CAPI_CONNECT_RESP -->
473 // <-- CAPI_CONNECT_ACTIVE_IND
474 // CAPI_CONNECT_ACTIVE_RESP -->
475 // <-- CAPI_CONNECT_B3_IND
476 // CAPI_CONNECT_B3_RESP -->
477 // <-- CAPI_CONNECT_B3_ACTIVE_IND
478 // CAPI_CONNECT_B3_ACTIVE_RESP -->
482 void capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
484 u_int8_t *msg = mtod(m_in, u_int8_t*);
486 u_int16_t applid, msgid;
492 if ((cd = reserve_cd()) == NULL) {
493 printf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
497 cd->controller = sc->ctrl_unit;
498 cd->channelexcl = FALSE;
500 for (bch = 0; bch < sc->sc_nbch; bch++)
501 if (sc->sc_bchan[bch].state == B_FREE) break;
502 sc->sc_bchan[bch].state = B_CONNECT_IND;
503 cd->channelid = bch; /* XXX CHAN_ANY XXX */
505 cd->crflag = CRF_DEST;
506 cd->cr = get_rand_cr(sc->sc_unit);
507 cd->scr_ind = SCR_NONE;
508 cd->prs_ind = PRS_NONE;
509 cd->bprot = BPROT_NONE;
512 cd->display[0] = '\0';
513 cd->datetime[0] = '\0';
515 msg = capimsg_getu16(msg + 2, &applid);
516 msg = capimsg_getu16(msg + 2, &msgid);
517 msg = capimsg_getu32(msg, &PLCI);
518 msg = capimsg_getu16(msg, &CIP);
520 cd->event = (int) msgid; /* XXX overload */
521 cd->Q931state = (int) PLCI; /* XXX overload */
525 case 0x0001: cd->bprot = BPROT_NONE; break;
526 case 0x0002: cd->bprot = BPROT_RHDLC; break;
528 NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
529 cd->bprot = BPROT_NONE;
532 msg = capimsg_getu8(msg, &x); /* Called party struct len */
534 msg = capimsg_getu8(msg, &y); /* Numbering plan */
536 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
537 strncpy(cd->dst_telno, msg, z);
541 cd->dst_telno[x] = '\0';
543 msg = capimsg_getu8(msg, &x); /* Calling party struct len */
545 msg = capimsg_getu8(msg, &y); /* Numbering plan */
546 msg = capimsg_getu8(msg, &y); /* Screening/Presentation */
547 if ((y & 0x80) == 0) { /* screening used */
548 cd->scr_ind = (y & 3) + SCR_USR_NOSC;
549 cd->prs_ind = ((y >> 5) & 3) + PRS_ALLOWED;
552 if (z >= TELNO_MAX) z = (TELNO_MAX-1);
553 strncpy(cd->src_telno, msg, z);
557 cd->src_telno[x] = '\0';
559 i4b_l4_connect_ind(cd);
562 void capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
568 int dlen = strlen(cd->dst_telno);
570 m = i4b_Dgetmbuf(8 + 21 + dlen);
572 printf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
576 msgid = (u_int16_t) cd->event;
577 PLCI = (u_int32_t) cd->Q931state;
579 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
580 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
581 msg = capimsg_setu16(msg, CAPI_CONNECT_RESP);
582 msg = capimsg_setu16(msg, msgid);
584 msg = capimsg_setu32(msg, PLCI);
586 switch (cd->response) {
587 case SETUP_RESP_ACCEPT:
588 sc->sc_bchan[cd->channelid].cdid = cd->cdid;
589 sc->sc_bchan[cd->channelid].ncci = PLCI;
590 sc->sc_bchan[cd->channelid].state = B_CONNECT_ACTIVE_IND;
591 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_USED;
592 msg = capimsg_setu16(msg, 0); /* Accept the call */
595 case SETUP_RESP_REJECT:
596 sc->sc_bchan[cd->channelid].state = B_FREE;
597 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
598 msg = capimsg_setu16(msg, 2); /* Reject, normal call clearing */
601 case SETUP_RESP_DNTCRE:
602 sc->sc_bchan[cd->channelid].state = B_FREE;
603 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
604 if (sc->sc_nbch == 30) {
605 /* With PRI, we can't really ignore calls -- normal clearing */
606 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_NCCLR));
608 msg = capimsg_setu16(msg, 1); /* Ignore */
613 sc->sc_bchan[cd->channelid].state = B_FREE;
614 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_FREE;
615 msg = capimsg_setu16(msg, (0x3480|CAUSE_Q850_CALLREJ));
618 msg = capimsg_setu8(msg, 15); /* B protocol */
619 if (cd->bprot == BPROT_NONE)
620 msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
622 msg = capimsg_setu16(msg, 0); /* B1 protocol = HDLC */
623 msg = capimsg_setu16(msg, 1); /* B2 protocol = transparent */
624 msg = capimsg_setu16(msg, 0); /* B3 protocol = transparent */
625 msg = capimsg_setu8(msg, 0); /* B1 parameters */
626 msg = capimsg_setu8(msg, 0); /* B2 parameters */
627 msg = capimsg_setu8(msg, 0); /* B3 parameters */
629 msg = capimsg_setu8(msg, 1 + dlen);
630 msg = capimsg_setu8(msg, 0x80); /* Numbering plan */
631 strncpy(msg, cd->dst_telno, dlen);
632 msg = capimsg_setu8(msg + dlen, 0); /* Connected subaddress */
633 msg = capimsg_setu8(msg, 0); /* Low Layer Compatibility */
634 msg = capimsg_setu8(msg, 0); /* Additional Info */
639 void capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
641 struct mbuf *m = i4b_Dgetmbuf(8 + 7);
642 u_int8_t *msg = mtod(m_in, u_int8_t*);
643 u_int16_t applid, msgid;
648 printf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
652 msg = capimsg_getu16(msg + 2, &applid);
653 msg = capimsg_getu16(msg + 2, &msgid);
654 msg = capimsg_getu32(msg, &NCCI);
656 for (bch = 0; bch < sc->sc_nbch; bch++)
657 if ((sc->sc_bchan[bch].state == B_CONNECT_B3_IND) &&
658 (sc->sc_bchan[bch].ncci == (NCCI & CAPI_PLCI_MASK)))
661 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
662 msg = capimsg_setu16(msg, applid);
663 msg = capimsg_setu16(msg, CAPI_CONNECT_B3_RESP);
664 msg = capimsg_setu16(msg, msgid);
666 msg = capimsg_setu32(msg, NCCI);
668 if (bch == sc->sc_nbch) {
669 printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
671 msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
674 sc->sc_bchan[bch].ncci = NCCI;
675 sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
676 msg = capimsg_setu16(msg, 0); /* Accept */
679 msg = capimsg_setu8(msg, 0); /* NCPI */
689 void capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
691 struct mbuf *m = i4b_Dgetmbuf(8 + 14);
696 printf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
700 msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
701 sc->sc_bchan[chan].busy = 1;
703 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
704 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
705 msg = capimsg_setu16(msg, CAPI_DATA_B3_REQ);
706 msg = capimsg_setu16(msg, msgid);
708 msg = capimsg_setu32(msg, sc->sc_bchan[chan].ncci);
709 msg = capimsg_setu32(msg, (u_int32_t) m_b3->m_data); /* Pointer */
710 msg = capimsg_setu16(msg, m_b3->m_len);
711 msg = capimsg_setu16(msg, chan);
712 msg = capimsg_setu16(msg, 0); /* Flags */
719 void capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
721 u_int8_t *msg = mtod(m_in, u_int8_t*);
726 msg = capimsg_getu32(msg + 8, &NCCI);
727 msg = capimsg_getu16(msg, &handle);
728 msg = capimsg_getu16(msg, &Info);
731 sc->sc_bchan[handle].busy = 0;
732 capi_start_tx(sc, handle);
735 printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
736 sc->sc_unit, NCCI, handle, Info);
740 void capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
742 struct mbuf *m = i4b_Dgetmbuf(8 + 6);
743 u_int8_t *msg = mtod(m_in, u_int8_t*);
744 u_int16_t applid, msgid;
750 printf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
754 msg = capimsg_getu16(msg + 2, &applid);
755 msg = capimsg_getu16(msg + 2, &msgid);
756 msg = capimsg_getu32(msg, &NCCI);
757 msg = capimsg_getu16(msg + 6, &handle);
759 for (bch = 0; bch < sc->sc_nbch; bch++)
760 if ((sc->sc_bchan[bch].state == B_CONNECTED) &&
761 (sc->sc_bchan[bch].ncci == NCCI))
764 if (bch == sc->sc_nbch) {
765 printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
769 if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
770 /* HDLC drivers use rx_mbuf */
772 sc->sc_bchan[bch].in_mbuf = m_in->m_next;
773 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
774 m_in->m_next = NULL; /* driver frees */
776 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
777 sc->sc_bchan[bch].capi_drvr_linktab->unit);
780 /* Telephony drivers use rx_queue */
782 if (!_IF_QFULL(&sc->sc_bchan[bch].rx_queue)) {
783 _IF_ENQUEUE(&sc->sc_bchan[bch].rx_queue, m_in->m_next);
784 sc->sc_bchan[bch].rxcount += m_in->m_next->m_len;
785 m_in->m_next = NULL; /* driver frees */
788 (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
789 sc->sc_bchan[bch].capi_drvr_linktab->unit);
793 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
794 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
795 msg = capimsg_setu16(msg, CAPI_DATA_B3_RESP);
796 msg = capimsg_setu16(msg, msgid);
798 msg = capimsg_setu32(msg, NCCI);
799 msg = capimsg_setu16(msg, handle);
805 // Connection teardown:
806 // --------------------
809 void capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
811 struct mbuf *m = i4b_Dgetmbuf(8 + 5);
817 printf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
821 sc->sc_bchan[cd->channelid].state = B_DISCONNECT_CONF;
822 ctrl_desc[sc->ctrl_unit].bch_state[cd->channelid] = BCH_ST_RSVD;
823 msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
824 PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
826 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
827 msg = capimsg_setu16(msg, I4BCAPI_APPLID);
828 msg = capimsg_setu16(msg, CAPI_DISCONNECT_REQ);
829 msg = capimsg_setu16(msg, msgid);
831 msg = capimsg_setu32(msg, PLCI);
832 msg = capimsg_setu8(msg, 0); /* Additional Info */
837 void capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
839 u_int8_t *msg = mtod(m_in, u_int8_t*);
844 msg = capimsg_getu32(msg + 8, &PLCI);
846 for (bch = 0; bch < sc->sc_nbch; bch++)
847 if ((sc->sc_bchan[bch].state == B_DISCONNECT_CONF) &&
848 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
851 if (bch == sc->sc_nbch) {
852 printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
857 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
859 printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
862 i4b_l4_disconnect_ind(cd);
866 sc->sc_bchan[bch].state = B_FREE;
867 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
870 void capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
872 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
873 u_int8_t *msg = mtod(m_in, u_int8_t*);
874 u_int16_t applid, msgid;
878 printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
882 msg = capimsg_getu16(msg + 2, &applid);
883 msg = capimsg_getu16(msg + 2, &msgid);
884 msg = capimsg_getu32(msg, &NCCI);
886 /* XXX update bchan state? XXX */
888 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
889 msg = capimsg_setu16(msg, applid);
890 msg = capimsg_setu16(msg, CAPI_DISCONNECT_B3_RESP);
891 msg = capimsg_setu16(msg, msgid);
893 msg = capimsg_setu32(msg, NCCI);
898 void capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
900 struct mbuf *m = i4b_Dgetmbuf(8 + 4);
901 u_int8_t *msg = mtod(m_in, u_int8_t*);
903 u_int16_t applid, msgid;
909 printf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
913 msg = capimsg_getu16(msg + 2, &applid);
914 msg = capimsg_getu16(msg + 2, &msgid);
915 msg = capimsg_getu32(msg, &PLCI);
916 msg = capimsg_getu16(msg, &Reason);
918 for (bch = 0; bch < sc->sc_nbch; bch++)
919 if ((sc->sc_bchan[bch].state != B_FREE) &&
920 ((sc->sc_bchan[bch].ncci & CAPI_PLCI_MASK) == PLCI))
923 if (bch < sc->sc_nbch) {
924 /* We may not have a bchan assigned if call was ignored. */
926 cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
927 sc->sc_bchan[bch].state = B_DISCONNECT_IND;
931 if ((Reason & 0xff00) == 0x3400) {
932 SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
934 SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
937 i4b_l4_disconnect_ind(cd);
940 sc->sc_bchan[bch].state = B_FREE;
941 ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
944 msg = capimsg_setu16(mtod(m, u_int8_t*), m->m_len);
945 msg = capimsg_setu16(msg, applid);
946 msg = capimsg_setu16(msg, CAPI_DISCONNECT_RESP);
947 msg = capimsg_setu16(msg, msgid);
949 msg = capimsg_setu32(msg, PLCI);
954 #endif /* NI4BCAPI > 0 */