1 /* $NetBSD: i4b_capi_msgs.c,v 1.5.4.4 2005/03/04 16:53:44 skrll Exp $ */
4 * Copyright (c) 2001-2003 Cubical Solutions Ltd. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * capi/capi_msgs.c The CAPI i4b message handlers.
29 * $FreeBSD: src/sys/i4b/capi/capi_msgs.c,v 1.2 2001/10/21 08:51:54 hm Exp $
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: i4b_capi_msgs.c,v 1.5.4.4 2005/03/04 16:53:44 skrll Exp $");
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/systm.h>
39 #include <sys/socket.h>
40 #include <sys/callout.h>
43 #include <netisdn/i4b_debug.h>
44 #include <netisdn/i4b_ioctl.h>
45 #include <netisdn/i4b_cause.h>
46 #include <netisdn/i4b_l3l4.h>
47 #include <netisdn/i4b_mbuf.h>
48 #include <netisdn/i4b_global.h>
49 #include <netisdn/i4b_l4.h>
50 #include <netisdn/i4b_capi.h>
51 #include <netisdn/i4b_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
, sc
->sc_unit
+ 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 struct isdn_l3_driver
*l3drv
;
89 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
92 capimsg_getu16(msg
+ 12, &Info
);
95 /* We are now listening. */
98 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
99 l3drv
->dl_est
= DL_UP
;
101 i4b_l4_l12stat(l3drv
, 1, 1);
102 i4b_l4_l12stat(l3drv
, 2, 1);
105 /* XXX sc->sc_state = C_DOWN ? XXX */
106 printf("capi%d: can't listen, info=%04x\n", sc
->sc_unit
, Info
);
110 void capi_info_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
112 struct mbuf
*m
= i4b_Dgetmbuf(8 + 4);
113 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
114 u_int16_t applid
, msgid
;
118 printf("capi%d: can't get mbuf for info_resp\n", sc
->sc_unit
);
122 msg
= capimsg_getu16(msg
+ 2, &applid
);
123 msg
= capimsg_getu16(msg
+ 2, &msgid
);
124 msg
= capimsg_getu32(msg
, &PLCI
);
126 /* i4b_l4_info_ind() */
128 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
129 msg
= capimsg_setu16(msg
, applid
);
130 msg
= capimsg_setu16(msg
, CAPI_INFO_RESP
);
131 msg
= capimsg_setu16(msg
, msgid
);
133 msg
= capimsg_setu32(msg
, PLCI
);
138 void capi_alert_req(capi_softc_t
*sc
, call_desc_t
*cd
)
140 struct mbuf
*m
= i4b_Dgetmbuf(8 + 5);
146 printf("capi%d: can't get mbuf for alert_req\n", sc
->sc_unit
);
150 msgid
= sc
->sc_bchan
[cd
->channelid
].msgid
= sc
->sc_msgid
++;
151 PLCI
= (sc
->sc_bchan
[cd
->channelid
].ncci
& CAPI_PLCI_MASK
);
153 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
154 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
155 msg
= capimsg_setu16(msg
, CAPI_ALERT_REQ
);
156 msg
= capimsg_setu16(msg
, msgid
);
158 msg
= capimsg_setu32(msg
, PLCI
);
159 msg
= capimsg_setu8(msg
, 0);
164 void capi_alert_conf(capi_softc_t
*sc
, struct mbuf
*m_in
)
166 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
169 msg
= capimsg_getu16(msg
+ 12, &Info
);
172 printf("capi%d: can't alert, info=%04x\n", sc
->sc_unit
, Info
);
177 // Outgoing call setup:
178 // --------------------
180 // CAPI_CONNECT_REQ -->
181 // <-- CAPI_CONNECT_CONF
183 // <-- CAPI_CONNECT_ACTIVE_IND
184 // CAPI_CONNECT_ACTIVE_RESP -->
185 // CAPI_CONNECT_B3_REQ -->
186 // <-- CAPI_CONNECT_B3_CONF
187 // <-- CAPI_CONNECT_B3_ACTIVE_IND
188 // CAPI_CONNECT_B3_ACTIVE_RESP -->
192 void capi_connect_req(capi_softc_t
*sc
, call_desc_t
*cd
)
194 struct isdn_l3_driver
*l3drv
;
198 int slen
= strlen(cd
->src_telno
);
199 int dlen
= strlen(cd
->dst_telno
);
201 m
= i4b_Dgetmbuf(8 + 27 + slen
+ dlen
);
203 printf("capi%d: can't get mbuf for connect_req\n", sc
->sc_unit
);
207 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
209 cd
->crflag
= CRF_ORIG
;
211 sc
->sc_bchan
[cd
->channelid
].cdid
= cd
->cdid
;
212 sc
->sc_bchan
[cd
->channelid
].bprot
= cd
->bprot
;
213 sc
->sc_bchan
[cd
->channelid
].state
= B_CONNECT_CONF
;
214 msgid
= sc
->sc_bchan
[cd
->channelid
].msgid
= sc
->sc_msgid
++;
215 l3drv
->bch_state
[cd
->channelid
] = BCH_ST_RSVD
;
217 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
218 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
219 msg
= capimsg_setu16(msg
, CAPI_CONNECT_REQ
);
220 msg
= capimsg_setu16(msg
, msgid
);
222 msg
= capimsg_setu32(msg
, sc
->sc_unit
+ 1); /* Controller */
226 msg
= capimsg_setu16(msg
, 0x0010); /* Telephony */
230 msg
= capimsg_setu16(msg
, 0x0002); /* Unrestricted digital */
234 msg
= capimsg_setu16(msg
, 0x0002); /* Unrestricted digital */
237 msg
= capimsg_setu8(msg
, 1 + dlen
);
238 msg
= capimsg_setu8(msg
, 0x80);
239 strncpy(msg
, cd
->dst_telno
, dlen
);
241 msg
= capimsg_setu8(msg
+ dlen
, 2 + slen
);
242 msg
= capimsg_setu8(msg
, 0x00);
243 msg
= capimsg_setu8(msg
, 0x80); /* Presentation and screening indicator */
244 strncpy(msg
, cd
->src_telno
, slen
);
246 msg
= capimsg_setu8(msg
+ slen
, 0); /* Called & */
247 msg
= capimsg_setu8(msg
, 0); /* Calling party subaddress */
249 msg
= capimsg_setu8(msg
, 15); /* B protocol */
250 if (cd
->bprot
== BPROT_NONE
)
251 msg
= capimsg_setu16(msg
, 1); /* B1 protocol = transparent */
253 msg
= capimsg_setu16(msg
, 0); /* B1 protocol = HDLC */
254 msg
= capimsg_setu16(msg
, 1); /* B2 protocol = transparent */
255 msg
= capimsg_setu16(msg
, 0); /* B3 protocol = transparent */
256 msg
= capimsg_setu8(msg
, 0); /* B1 parameters */
257 msg
= capimsg_setu8(msg
, 0); /* B2 parameters */
258 msg
= capimsg_setu8(msg
, 0); /* B3 parameters */
260 msg
= capimsg_setu8(msg
, 0); /* Bearer Capability */
261 msg
= capimsg_setu8(msg
, 0); /* Low Layer Compatibility */
262 msg
= capimsg_setu8(msg
, 0); /* High Layer Compatibility */
263 msg
= capimsg_setu8(msg
, 0); /* Additional Info */
268 void capi_connect_conf(capi_softc_t
*sc
, struct mbuf
*m_in
)
270 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
277 msg
= capimsg_getu16(msg
+ 6, &msgid
);
278 msg
= capimsg_getu32(msg
, &PLCI
);
279 msg
= capimsg_getu16(msg
, &Info
);
281 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
282 if ((sc
->sc_bchan
[bch
].state
== B_CONNECT_CONF
) &&
283 (sc
->sc_bchan
[bch
].msgid
== msgid
))
286 if ((bch
== sc
->sc_nbch
) ||
287 (cd
= cd_by_cdid(sc
->sc_bchan
[bch
].cdid
)) == NULL
) {
288 printf("capi%d: can't find channel for connect_conf PLCI %x\n",
294 sc
->sc_bchan
[bch
].state
= B_CONNECT_ACTIVE_IND
;
295 sc
->sc_bchan
[bch
].ncci
= PLCI
;
297 i4b_l4_proceeding_ind(cd
);
300 struct isdn_l3_driver
*l3drv
;
302 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
303 SET_CAUSE_TV(cd
->cause_out
, CAUSET_I4B
, CAUSE_I4B_L1ERROR
);
304 i4b_l4_disconnect_ind(cd
);
307 sc
->sc_bchan
[bch
].state
= B_FREE
;
309 l3drv
->bch_state
[bch
] = BCH_ST_FREE
;
311 printf("capi%d: can't connect out, info=%04x\n", sc
->sc_unit
, Info
);
315 void capi_connect_active_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
317 struct mbuf
*m
= i4b_Dgetmbuf(8 + 4);
318 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
320 u_int16_t applid
, msgid
;
325 printf("capi%d: can't get mbuf for active_ind\n", sc
->sc_unit
);
329 msg
= capimsg_getu16(msg
+ 2, &applid
);
330 msg
= capimsg_getu16(msg
+ 2, &msgid
);
331 msg
= capimsg_getu32(msg
, &PLCI
);
333 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
334 if ((sc
->sc_bchan
[bch
].state
== B_CONNECT_ACTIVE_IND
) &&
335 (sc
->sc_bchan
[bch
].ncci
== PLCI
))
338 if ((bch
== sc
->sc_nbch
) ||
339 (cd
= cd_by_cdid(sc
->sc_bchan
[bch
].cdid
)) == NULL
) {
340 printf("capi%d: can't find channel for active_resp, PLCI %x\n",
345 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
346 msg
= capimsg_setu16(msg
, applid
);
347 msg
= capimsg_setu16(msg
, CAPI_CONNECT_ACTIVE_RESP
);
348 msg
= capimsg_setu16(msg
, msgid
);
350 msg
= capimsg_setu32(msg
, PLCI
);
354 if (cd
->crflag
== CRF_ORIG
) {
355 capi_connect_b3_req(sc
, cd
);
358 sc
->sc_bchan
[bch
].state
= B_CONNECT_B3_IND
;
362 void capi_connect_b3_req(capi_softc_t
*sc
, call_desc_t
*cd
)
364 struct mbuf
*m
= i4b_Dgetmbuf(8 + 5);
370 printf("capi%d: can't get mbuf for connect_b3_req\n", sc
->sc_unit
);
374 sc
->sc_bchan
[cd
->channelid
].state
= B_CONNECT_B3_CONF
;
375 msgid
= sc
->sc_bchan
[cd
->channelid
].msgid
= sc
->sc_msgid
++;
376 PLCI
= (sc
->sc_bchan
[cd
->channelid
].ncci
& CAPI_PLCI_MASK
);
378 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
379 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
380 msg
= capimsg_setu16(msg
, CAPI_CONNECT_B3_REQ
);
381 msg
= capimsg_setu16(msg
, msgid
);
383 msg
= capimsg_setu32(msg
, PLCI
);
384 msg
= capimsg_setu8(msg
, 0); /* NCPI */
389 void capi_connect_b3_conf(capi_softc_t
*sc
, struct mbuf
*m_in
)
391 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
398 msg
= capimsg_getu16(msg
+ 6, &msgid
);
399 msg
= capimsg_getu32(msg
, &NCCI
);
400 msg
= capimsg_getu16(msg
, &Info
);
402 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
403 if ((sc
->sc_bchan
[bch
].state
== B_CONNECT_B3_CONF
) &&
404 (sc
->sc_bchan
[bch
].ncci
== (NCCI
& CAPI_PLCI_MASK
)))
407 if ((bch
== sc
->sc_nbch
) ||
408 (cd
= cd_by_cdid(sc
->sc_bchan
[bch
].cdid
)) == NULL
) {
409 printf("capi%d: can't find channel for connect_b3_conf NCCI %x\n",
415 sc
->sc_bchan
[bch
].ncci
= NCCI
;
416 sc
->sc_bchan
[bch
].state
= B_CONNECT_B3_ACTIVE_IND
;
419 struct isdn_l3_driver
*l3drv
;
421 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
423 SET_CAUSE_TV(cd
->cause_in
, CAUSET_I4B
, CAUSE_I4B_OOO
); /* XXX */
424 i4b_l4_disconnect_ind(cd
);
427 l3drv
->bch_state
[bch
] = BCH_ST_RSVD
;
429 printf("capi%d: can't connect_b3 out, info=%04x\n", sc
->sc_unit
, Info
);
431 capi_disconnect_req(sc
, cd
);
435 void capi_connect_b3_active_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
437 struct mbuf
*m
= i4b_Dgetmbuf(8 + 4);
438 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
440 u_int16_t applid
, msgid
;
445 printf("capi%d: can't get mbuf for b3_active_ind\n", sc
->sc_unit
);
449 msg
= capimsg_getu16(msg
+ 2, &applid
);
450 msg
= capimsg_getu16(msg
+ 2, &msgid
);
451 msg
= capimsg_getu32(msg
, &NCCI
);
453 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
454 if ((sc
->sc_bchan
[bch
].state
== B_CONNECT_B3_ACTIVE_IND
) &&
455 (sc
->sc_bchan
[bch
].ncci
== NCCI
))
458 if ((bch
== sc
->sc_nbch
) ||
459 (cd
= cd_by_cdid(sc
->sc_bchan
[bch
].cdid
)) == NULL
) {
460 printf("capi%d: can't find channel for b3_active_resp NCCI %x\n",
465 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
466 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
467 msg
= capimsg_setu16(msg
, CAPI_CONNECT_B3_ACTIVE_RESP
);
468 msg
= capimsg_setu16(msg
, msgid
);
470 msg
= capimsg_setu32(msg
, NCCI
);
474 sc
->sc_bchan
[bch
].state
= B_CONNECTED
;
476 i4b_l4_connect_active_ind(cd
);
480 // Incoming call setup:
481 // --------------------
483 // <-- CAPI_CONNECT_IND
485 // CAPI_CONNECT_RESP -->
486 // <-- CAPI_CONNECT_ACTIVE_IND
487 // CAPI_CONNECT_ACTIVE_RESP -->
488 // <-- CAPI_CONNECT_B3_IND
489 // CAPI_CONNECT_B3_RESP -->
490 // <-- CAPI_CONNECT_B3_ACTIVE_IND
491 // CAPI_CONNECT_B3_ACTIVE_RESP -->
495 void capi_connect_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
497 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
499 u_int16_t applid
, msgid
;
505 if ((cd
= reserve_cd()) == NULL
) {
506 printf("capi%d: can't get cd for connect_ind\n", sc
->sc_unit
);
510 cd
->isdnif
= sc
->capi_isdnif
;
512 cd
->l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
514 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
515 if (sc
->sc_bchan
[bch
].state
== B_FREE
)
518 sc
->sc_bchan
[bch
].state
= B_CONNECT_IND
;
519 cd
->channelid
= bch
; /* XXX CHAN_ANY XXX */
521 cd
->crflag
= CRF_DEST
;
522 cd
->cr
= get_rand_cr(sc
->sc_unit
);
523 cd
->scr_ind
= SCR_NONE
;
524 cd
->prs_ind
= PRS_NONE
;
525 cd
->bprot
= BPROT_NONE
;
527 cd
->display
[0] = '\0';
528 cd
->datetime
[0] = '\0';
530 msg
= capimsg_getu16(msg
+ 2, &applid
);
531 msg
= capimsg_getu16(msg
+ 2, &msgid
);
532 msg
= capimsg_getu32(msg
, &PLCI
);
533 msg
= capimsg_getu16(msg
, &CIP
);
535 cd
->event
= (int) msgid
; /* XXX overload */
536 cd
->Q931state
= (int) PLCI
; /* XXX overload */
540 case 0x0001: cd
->bprot
= BPROT_NONE
; break;
541 case 0x0002: cd
->bprot
= BPROT_RHDLC
; break;
544 NDBGL4(L4_CAPIDBG
, "capi%d: unknown CIP = %d", sc
->sc_unit
, CIP
);
546 cd
->bprot
= BPROT_NONE
;
549 msg
= capimsg_getu8(msg
, &x
); /* Called party struct len */
551 msg
= capimsg_getu8(msg
, &y
); /* Numbering plan */
553 if (z
>= TELNO_MAX
) z
= (TELNO_MAX
-1);
554 strncpy(cd
->dst_telno
, msg
, z
);
558 cd
->dst_telno
[x
] = '\0';
560 msg
= capimsg_getu8(msg
, &x
); /* Calling party struct len */
562 msg
= capimsg_getu8(msg
, &y
); /* Numbering plan */
563 msg
= capimsg_getu8(msg
, &y
); /* Screening/Presentation */
564 if ((y
& 0x80) == 0) { /* screening used */
565 cd
->scr_ind
= (y
& 3) + SCR_USR_NOSC
;
566 cd
->prs_ind
= ((y
>> 5) & 3) + PRS_ALLOWED
;
569 if (z
>= TELNO_MAX
) z
= (TELNO_MAX
-1);
570 strncpy(cd
->src_telno
, msg
, z
);
574 cd
->src_telno
[x
] = '\0';
576 i4b_l4_connect_ind(cd
);
579 void capi_connect_resp(capi_softc_t
*sc
, call_desc_t
*cd
)
581 struct isdn_l3_driver
*l3drv
;
586 int dlen
= strlen(cd
->dst_telno
);
588 m
= i4b_Dgetmbuf(8 + 21 + dlen
);
590 printf("capi%d: can't get mbuf for connect_resp\n", sc
->sc_unit
);
594 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
596 msgid
= (u_int16_t
) cd
->event
;
597 PLCI
= (u_int32_t
) cd
->Q931state
;
599 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
600 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
601 msg
= capimsg_setu16(msg
, CAPI_CONNECT_RESP
);
602 msg
= capimsg_setu16(msg
, msgid
);
604 msg
= capimsg_setu32(msg
, PLCI
);
606 switch (cd
->response
) {
607 case SETUP_RESP_ACCEPT
:
608 sc
->sc_bchan
[cd
->channelid
].cdid
= cd
->cdid
;
609 sc
->sc_bchan
[cd
->channelid
].ncci
= PLCI
;
610 sc
->sc_bchan
[cd
->channelid
].state
= B_CONNECT_ACTIVE_IND
;
611 l3drv
->bch_state
[cd
->channelid
] = BCH_ST_USED
;
612 msg
= capimsg_setu16(msg
, 0); /* Accept the call */
615 case SETUP_RESP_REJECT
:
616 sc
->sc_bchan
[cd
->channelid
].state
= B_FREE
;
617 l3drv
->bch_state
[cd
->channelid
] = BCH_ST_FREE
;
618 msg
= capimsg_setu16(msg
, 2); /* Reject, normal call clearing */
621 case SETUP_RESP_DNTCRE
:
622 sc
->sc_bchan
[cd
->channelid
].state
= B_FREE
;
623 l3drv
->bch_state
[cd
->channelid
] = BCH_ST_FREE
;
624 if (sc
->sc_nbch
== 30) {
625 /* With PRI, we can't really ignore calls -- normal clearing */
626 msg
= capimsg_setu16(msg
, (0x3480|CAUSE_Q850_NCCLR
));
628 msg
= capimsg_setu16(msg
, 1); /* Ignore */
633 sc
->sc_bchan
[cd
->channelid
].state
= B_FREE
;
634 l3drv
->bch_state
[cd
->channelid
] = BCH_ST_FREE
;
635 msg
= capimsg_setu16(msg
, (0x3480|CAUSE_Q850_CALLREJ
));
638 msg
= capimsg_setu8(msg
, 15); /* B protocol */
639 if (cd
->bprot
== BPROT_NONE
)
640 msg
= capimsg_setu16(msg
, 1); /* B1 protocol = transparent */
642 msg
= capimsg_setu16(msg
, 0); /* B1 protocol = HDLC */
643 msg
= capimsg_setu16(msg
, 1); /* B2 protocol = transparent */
644 msg
= capimsg_setu16(msg
, 0); /* B3 protocol = transparent */
645 msg
= capimsg_setu8(msg
, 0); /* B1 parameters */
646 msg
= capimsg_setu8(msg
, 0); /* B2 parameters */
647 msg
= capimsg_setu8(msg
, 0); /* B3 parameters */
649 msg
= capimsg_setu8(msg
, 1 + dlen
);
650 msg
= capimsg_setu8(msg
, 0x80); /* Numbering plan */
651 strncpy(msg
, cd
->dst_telno
, dlen
);
652 msg
= capimsg_setu8(msg
+ dlen
, 0); /* Connected subaddress */
653 msg
= capimsg_setu8(msg
, 0); /* Low Layer Compatibility */
654 msg
= capimsg_setu8(msg
, 0); /* Additional Info */
659 void capi_connect_b3_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
661 struct mbuf
*m
= i4b_Dgetmbuf(8 + 7);
662 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
663 u_int16_t applid
, msgid
;
668 printf("capi%d: can't get mbuf for connect_b3_resp\n", sc
->sc_unit
);
672 msg
= capimsg_getu16(msg
+ 2, &applid
);
673 msg
= capimsg_getu16(msg
+ 2, &msgid
);
674 msg
= capimsg_getu32(msg
, &NCCI
);
676 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
677 if ((sc
->sc_bchan
[bch
].state
== B_CONNECT_B3_IND
) &&
678 (sc
->sc_bchan
[bch
].ncci
== (NCCI
& CAPI_PLCI_MASK
)))
681 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
682 msg
= capimsg_setu16(msg
, applid
);
683 msg
= capimsg_setu16(msg
, CAPI_CONNECT_B3_RESP
);
684 msg
= capimsg_setu16(msg
, msgid
);
686 msg
= capimsg_setu32(msg
, NCCI
);
688 if (bch
== sc
->sc_nbch
) {
689 printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
691 msg
= capimsg_setu16(msg
, 8); /* Reject, destination OOO */
694 sc
->sc_bchan
[bch
].ncci
= NCCI
;
695 sc
->sc_bchan
[bch
].state
= B_CONNECT_B3_ACTIVE_IND
;
696 msg
= capimsg_setu16(msg
, 0); /* Accept */
699 msg
= capimsg_setu8(msg
, 0); /* NCPI */
709 void capi_data_b3_req(capi_softc_t
*sc
, int chan
, struct mbuf
*m_b3
)
711 struct mbuf
*m
= i4b_Dgetmbuf(8 + 14);
716 printf("capi%d: can't get mbuf for data_b3_req\n", sc
->sc_unit
);
720 msgid
= sc
->sc_bchan
[chan
].msgid
= sc
->sc_msgid
++;
721 sc
->sc_bchan
[chan
].busy
= 1;
723 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
724 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
725 msg
= capimsg_setu16(msg
, CAPI_DATA_B3_REQ
);
726 msg
= capimsg_setu16(msg
, msgid
);
728 msg
= capimsg_setu32(msg
, sc
->sc_bchan
[chan
].ncci
);
729 msg
= capimsg_setu32(msg
, (u_int32_t
) m_b3
->m_data
); /* Pointer */
730 msg
= capimsg_setu16(msg
, m_b3
->m_len
);
731 msg
= capimsg_setu16(msg
, chan
);
732 msg
= capimsg_setu16(msg
, 0); /* Flags */
739 void capi_data_b3_conf(capi_softc_t
*sc
, struct mbuf
*m_in
)
741 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
746 msg
= capimsg_getu32(msg
+ 8, &NCCI
);
747 msg
= capimsg_getu16(msg
, &handle
);
748 msg
= capimsg_getu16(msg
, &Info
);
751 sc
->sc_bchan
[handle
].busy
= 0;
752 capi_start_tx(sc
, handle
);
755 printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
756 sc
->sc_unit
, NCCI
, handle
, Info
);
760 void capi_data_b3_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
762 struct mbuf
*m
= i4b_Dgetmbuf(8 + 6);
763 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
764 u_int16_t applid
, msgid
;
770 printf("capi%d: can't get mbuf for data_b3_resp\n", sc
->sc_unit
);
774 msg
= capimsg_getu16(msg
+ 2, &applid
);
775 msg
= capimsg_getu16(msg
+ 2, &msgid
);
776 msg
= capimsg_getu32(msg
, &NCCI
);
777 msg
= capimsg_getu16(msg
+ 6, &handle
);
779 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
780 if ((sc
->sc_bchan
[bch
].state
== B_CONNECTED
) &&
781 (sc
->sc_bchan
[bch
].ncci
== NCCI
))
784 if (bch
== sc
->sc_nbch
) {
785 printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
789 if (sc
->sc_bchan
[bch
].bprot
== BPROT_RHDLC
) {
790 /* HDLC drivers use rx_mbuf */
792 sc
->sc_bchan
[bch
].in_mbuf
= m_in
->m_next
;
793 sc
->sc_bchan
[bch
].rxcount
+= m_in
->m_next
->m_len
;
794 m_in
->m_next
= NULL
; /* driver frees */
796 (*sc
->sc_bchan
[bch
].l4_driver
->bch_rx_data_ready
)(
797 sc
->sc_bchan
[bch
].l4_driver_softc
);
800 /* Telephony drivers use rx_queue */
802 if (!IF_QFULL(&sc
->sc_bchan
[bch
].rx_queue
)) {
803 IF_ENQUEUE(&sc
->sc_bchan
[bch
].rx_queue
, m_in
->m_next
);
804 sc
->sc_bchan
[bch
].rxcount
+= m_in
->m_next
->m_len
;
805 m_in
->m_next
= NULL
; /* driver frees */
808 (*sc
->sc_bchan
[bch
].l4_driver
->bch_rx_data_ready
)(
809 sc
->sc_bchan
[bch
].l4_driver_softc
);
813 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
814 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
815 msg
= capimsg_setu16(msg
, CAPI_DATA_B3_RESP
);
816 msg
= capimsg_setu16(msg
, msgid
);
818 msg
= capimsg_setu32(msg
, NCCI
);
819 msg
= capimsg_setu16(msg
, handle
);
825 // Connection teardown:
826 // --------------------
829 void capi_disconnect_req(capi_softc_t
*sc
, call_desc_t
*cd
)
831 struct isdn_l3_driver
*l3drv
;
832 struct mbuf
*m
= i4b_Dgetmbuf(8 + 5);
838 printf("capi%d: can't get mbuf for disconnect_req\n", sc
->sc_unit
);
842 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
844 sc
->sc_bchan
[cd
->channelid
].state
= B_DISCONNECT_CONF
;
845 l3drv
->bch_state
[cd
->channelid
] = BCH_ST_RSVD
;
846 msgid
= sc
->sc_bchan
[cd
->channelid
].msgid
= sc
->sc_msgid
++;
847 PLCI
= (sc
->sc_bchan
[cd
->channelid
].ncci
& CAPI_PLCI_MASK
);
849 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
850 msg
= capimsg_setu16(msg
, I4BCAPI_APPLID
);
851 msg
= capimsg_setu16(msg
, CAPI_DISCONNECT_REQ
);
852 msg
= capimsg_setu16(msg
, msgid
);
854 msg
= capimsg_setu32(msg
, PLCI
);
855 msg
= capimsg_setu8(msg
, 0); /* Additional Info */
860 void capi_disconnect_conf(capi_softc_t
*sc
, struct mbuf
*m_in
)
862 struct isdn_l3_driver
*l3drv
;
863 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
868 msg
= capimsg_getu32(msg
+ 8, &PLCI
);
870 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
871 if ((sc
->sc_bchan
[bch
].state
== B_DISCONNECT_CONF
) &&
872 ((sc
->sc_bchan
[bch
].ncci
& CAPI_PLCI_MASK
) == PLCI
))
875 if (bch
== sc
->sc_nbch
) {
876 printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
881 cd
= cd_by_cdid(sc
->sc_bchan
[bch
].cdid
);
883 printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
886 i4b_l4_disconnect_ind(cd
);
890 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
892 sc
->sc_bchan
[bch
].state
= B_FREE
;
893 l3drv
->bch_state
[bch
] = BCH_ST_FREE
;
896 void capi_disconnect_b3_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
*);
900 u_int16_t applid
, msgid
;
904 printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc
->sc_unit
);
908 msg
= capimsg_getu16(msg
+ 2, &applid
);
909 msg
= capimsg_getu16(msg
+ 2, &msgid
);
910 msg
= capimsg_getu32(msg
, &NCCI
);
912 /* XXX update bchan state? XXX */
914 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
915 msg
= capimsg_setu16(msg
, applid
);
916 msg
= capimsg_setu16(msg
, CAPI_DISCONNECT_B3_RESP
);
917 msg
= capimsg_setu16(msg
, msgid
);
919 msg
= capimsg_setu32(msg
, NCCI
);
924 void capi_disconnect_ind(capi_softc_t
*sc
, struct mbuf
*m_in
)
926 struct isdn_l3_driver
*l3drv
;
927 struct mbuf
*m
= i4b_Dgetmbuf(8 + 4);
928 u_int8_t
*msg
= mtod(m_in
, u_int8_t
*);
930 u_int16_t applid
, msgid
;
936 printf("capi%d: can't get mbuf for disconnect_resp\n", sc
->sc_unit
);
940 msg
= capimsg_getu16(msg
+ 2, &applid
);
941 msg
= capimsg_getu16(msg
+ 2, &msgid
);
942 msg
= capimsg_getu32(msg
, &PLCI
);
943 msg
= capimsg_getu16(msg
, &Reason
);
945 for (bch
= 0; bch
< sc
->sc_nbch
; bch
++)
946 if ((sc
->sc_bchan
[bch
].state
!= B_FREE
) &&
947 ((sc
->sc_bchan
[bch
].ncci
& CAPI_PLCI_MASK
) == PLCI
))
950 if (bch
< sc
->sc_nbch
) {
951 /* We may not have a bchan assigned if call was ignored. */
953 cd
= cd_by_cdid(sc
->sc_bchan
[bch
].cdid
);
954 sc
->sc_bchan
[bch
].state
= B_DISCONNECT_IND
;
959 if ((Reason
& 0xff00) == 0x3400) {
960 SET_CAUSE_TV(cd
->cause_in
, CAUSET_Q850
, (Reason
& 0x7f));
962 SET_CAUSE_TV(cd
->cause_in
, CAUSET_I4B
, CAUSE_I4B_NORMAL
);
965 i4b_l4_disconnect_ind(cd
);
968 sc
->sc_bchan
[bch
].state
= B_FREE
;
969 l3drv
= isdn_find_l3_by_isdnif(sc
->capi_isdnif
);
970 l3drv
->bch_state
[bch
] = BCH_ST_FREE
;
973 msg
= capimsg_setu16(mtod(m
, u_int8_t
*), m
->m_len
);
974 msg
= capimsg_setu16(msg
, applid
);
975 msg
= capimsg_setu16(msg
, CAPI_DISCONNECT_RESP
);
976 msg
= capimsg_setu16(msg
, msgid
);
978 msg
= capimsg_setu32(msg
, PLCI
);