File:
[DragonFly] /
src /
sys /
net /
i4b /
capi /
capi_msgs.c
Revision
1.4:
download - view:
text,
annotated -
select for diffs
Thu Aug 7 21:54:30 2003 UTC (9 years, 9 months ago) by
dillon
Branches:
MAIN
CVS tags:
HEAD
kernel tree reorganization stage 1: Major cvs repository work (not logged as
commits) plus a major reworking of the #include's to accomodate the
relocations.
* CVS repository files manually moved. Old directories left intact
and empty (temporary).
* Reorganize all filesystems into vfs/, most devices into dev/,
sub-divide devices by function.
* Begin to move device-specific architecture files to the device
subdirs rather then throwing them all into, e.g. i386/include
* Reorganize files related to system busses, placing the related code
in a new bus/ directory. Also move cam to bus/cam though this may
not have been the best idea in retrospect.
* Reorganize emulation code and place it in a new emulation/ directory.
* Remove the -I- compiler option in order to allow #include file
localization, rename all config generated X.h files to use_X.h to
clean up the conflicts.
* Remove /usr/src/include (or /usr/include) dependancies during the
kernel build, beyond what is normally needed to compile helper
programs.
* Make config create 'machine' softlinks for architecture specific
directories outside of the standard <arch>/include.
* Bump the config rev.
WARNING! after this commit /usr/include and /usr/src/sys/compile/*
should be regenerated from scratch.
1: /*
2: * Copyright (c) 2001 Cubical Solutions Ltd. All rights reserved.
3: *
4: * Redistribution and use in source and binary forms, with or without
5: * modification, are permitted provided that the following conditions
6: * are met:
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.
12: *
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
23: * SUCH DAMAGE.
24: *
25: * capi/capi_msgs.c The CAPI i4b message handlers.
26: *
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 $
29: */
30:
31: #include "use_i4bcapi.h"
32: #if NI4BCAPI > 0
33:
34: #include <sys/param.h>
35: #include <sys/kernel.h>
36: #include <sys/systm.h>
37: #include <sys/mbuf.h>
38: #include <sys/socket.h>
39: #include <net/if.h>
40:
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>
44:
45: #include "../include/i4b_l3l4.h"
46: #include "../include/i4b_mbuf.h"
47: #include "../include/i4b_global.h"
48: #include "../layer4/i4b_l4.h"
49:
50: #include "capi.h"
51: #include "capi_msgs.h"
52:
53: /*
54: // Administrative messages:
55: // ------------------------
56: */
57:
58: void capi_listen_req(capi_softc_t *sc, u_int32_t CIP)
59: {
60: struct mbuf *m = i4b_Dgetmbuf(8 + 18);
61: u_int8_t *msg;
62: u_int16_t msgid;
63:
64: if (!m) {
65: printf("capi%d: can't get mbuf for listen_req\n", sc->sc_unit);
66: return;
67: }
68:
69: msgid = sc->sc_msgid++;
70:
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);
75:
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);
82:
83: sc->send(sc, m);
84: }
85:
86: void capi_listen_conf(capi_softc_t *sc, struct mbuf *m_in)
87: {
88: u_int8_t *msg = mtod(m_in, u_int8_t*);
89: u_int16_t Info;
90:
91: capimsg_getu16(msg + 12, &Info);
92:
93: if (Info == 0) {
94: /* We are now listening. */
95:
96: sc->sc_state = C_UP;
97: ctrl_desc[sc->ctrl_unit].dl_est = DL_UP;
98:
99: i4b_l4_l12stat(sc->ctrl_unit, 1, 1);
100: i4b_l4_l12stat(sc->ctrl_unit, 2, 1);
101:
102: } else {
103: /* XXX sc->sc_state = C_DOWN ? XXX */
104: printf("capi%d: can't listen, info=%04x\n", sc->sc_unit, Info);
105: }
106: }
107:
108: void capi_info_ind(capi_softc_t *sc, struct mbuf *m_in)
109: {
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;
113: u_int32_t PLCI;
114:
115: if (!m) {
116: printf("capi%d: can't get mbuf for info_resp\n", sc->sc_unit);
117: return;
118: }
119:
120: msg = capimsg_getu16(msg + 2, &applid);
121: msg = capimsg_getu16(msg + 2, &msgid);
122: msg = capimsg_getu32(msg, &PLCI);
123:
124: /* i4b_l4_info_ind() */
125:
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);
130:
131: msg = capimsg_setu32(msg, PLCI);
132:
133: sc->send(sc, m);
134: }
135:
136: void capi_alert_req(capi_softc_t *sc, call_desc_t *cd)
137: {
138: struct mbuf *m = i4b_Dgetmbuf(8 + 5);
139: u_int8_t *msg;
140: u_int16_t msgid;
141: u_int32_t PLCI;
142:
143: if (!m) {
144: printf("capi%d: can't get mbuf for alert_req\n", sc->sc_unit);
145: return;
146: }
147:
148: msgid = sc->sc_bchan[cd->channelid].msgid = sc->sc_msgid++;
149: PLCI = (sc->sc_bchan[cd->channelid].ncci & CAPI_PLCI_MASK);
150:
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);
155:
156: msg = capimsg_setu32(msg, PLCI);
157: msg = capimsg_setu8(msg, 0);
158:
159: sc->send(sc, m);
160: }
161:
162: void capi_alert_conf(capi_softc_t *sc, struct mbuf *m_in)
163: {
164: u_int8_t *msg = mtod(m_in, u_int8_t*);
165: u_int16_t Info;
166:
167: msg = capimsg_getu16(msg + 12, &Info);
168:
169: if (Info) {
170: printf("capi%d: can't alert, info=%04x\n", sc->sc_unit, Info);
171: }
172: }
173:
174: /*
175: // Outgoing call setup:
176: // --------------------
177: //
178: // CAPI_CONNECT_REQ -->
179: // <-- CAPI_CONNECT_CONF
180: // (notify Layer 4)
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 -->
187: // (notify Layer 4)
188: */
189:
190: void capi_connect_req(capi_softc_t *sc, call_desc_t *cd)
191: {
192: struct mbuf *m;
193: u_int8_t *msg;
194: u_int16_t msgid;
195: int slen = strlen(cd->src_telno);
196: int dlen = strlen(cd->dst_telno);
197:
198: m = i4b_Dgetmbuf(8 + 27 + slen + dlen);
199: if (!m) {
200: printf("capi%d: can't get mbuf for connect_req\n", sc->sc_unit);
201: return;
202: }
203:
204: cd->crflag = CRF_ORIG;
205:
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;
211:
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);
216:
217: msg = capimsg_setu32(msg, 1); /* Controller */
218:
219: switch (cd->bprot) {
220: case BPROT_NONE:
221: msg = capimsg_setu16(msg, 0x0010); /* Telephony */
222: break;
223:
224: case BPROT_RHDLC:
225: msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
226: break;
227:
228: default:
229: msg = capimsg_setu16(msg, 0x0002); /* Unrestricted digital */
230: }
231:
232: msg = capimsg_setu8(msg, 1 + dlen);
233: msg = capimsg_setu8(msg, 0x80);
234: strncpy(msg, cd->dst_telno, dlen);
235:
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);
240:
241: msg = capimsg_setu8(msg + slen, 0); /* Called & */
242: msg = capimsg_setu8(msg, 0); /* Calling party subaddress */
243:
244: msg = capimsg_setu8(msg, 15); /* B protocol */
245: if (cd->bprot == BPROT_NONE)
246: msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
247: else
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 */
254:
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 */
259:
260: sc->send(sc, m);
261: }
262:
263: void capi_connect_conf(capi_softc_t *sc, struct mbuf *m_in)
264: {
265: u_int8_t *msg = mtod(m_in, u_int8_t*);
266: call_desc_t *cd;
267: u_int16_t msgid;
268: u_int32_t PLCI;
269: u_int16_t Info;
270: int bch;
271:
272: msg = capimsg_getu16(msg + 6, &msgid);
273: msg = capimsg_getu32(msg, &PLCI);
274: msg = capimsg_getu16(msg, &Info);
275:
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))
279: break;
280:
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",
284: sc->sc_unit, PLCI);
285: return;
286: }
287:
288: if (Info == 0) {
289: sc->sc_bchan[bch].state = B_CONNECT_ACTIVE_IND;
290: sc->sc_bchan[bch].ncci = PLCI;
291:
292: i4b_l4_proceeding_ind(cd);
293:
294: } else {
295: SET_CAUSE_TV(cd->cause_out, CAUSET_I4B, CAUSE_I4B_L1ERROR);
296: i4b_l4_disconnect_ind(cd);
297: freecd_by_cd(cd);
298:
299: sc->sc_bchan[bch].state = B_FREE;
300: ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
301:
302: printf("capi%d: can't connect out, info=%04x\n", sc->sc_unit, Info);
303: }
304: }
305:
306: void capi_connect_active_ind(capi_softc_t *sc, struct mbuf *m_in)
307: {
308: struct mbuf *m = i4b_Dgetmbuf(8 + 4);
309: u_int8_t *msg = mtod(m_in, u_int8_t*);
310: call_desc_t *cd;
311: u_int16_t applid, msgid;
312: u_int32_t PLCI;
313: int bch;
314:
315: if (!m) {
316: printf("capi%d: can't get mbuf for active_ind\n", sc->sc_unit);
317: return;
318: }
319:
320: msg = capimsg_getu16(msg + 2, &applid);
321: msg = capimsg_getu16(msg + 2, &msgid);
322: msg = capimsg_getu32(msg, &PLCI);
323:
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))
327: break;
328:
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",
332: sc->sc_unit, PLCI);
333: return;
334: }
335:
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);
340:
341: msg = capimsg_setu32(msg, PLCI);
342:
343: sc->send(sc, m);
344:
345: if (cd->crflag == CRF_ORIG) {
346: capi_connect_b3_req(sc, cd);
347:
348: } else {
349: sc->sc_bchan[bch].state = B_CONNECT_B3_IND;
350: }
351: }
352:
353: void capi_connect_b3_req(capi_softc_t *sc, call_desc_t *cd)
354: {
355: struct mbuf *m = i4b_Dgetmbuf(8 + 5);
356: u_int8_t *msg;
357: u_int16_t msgid;
358: u_int32_t PLCI;
359:
360: if (!m) {
361: printf("capi%d: can't get mbuf for connect_b3_req\n", sc->sc_unit);
362: return;
363: }
364:
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);
368:
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);
373:
374: msg = capimsg_setu32(msg, PLCI);
375: msg = capimsg_setu8(msg, 0); /* NCPI */
376:
377: sc->send(sc, m);
378: }
379:
380: void capi_connect_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
381: {
382: u_int8_t *msg = mtod(m_in, u_int8_t*);
383: call_desc_t *cd;
384: u_int16_t msgid;
385: u_int32_t NCCI;
386: u_int16_t Info;
387: int bch;
388:
389: msg = capimsg_getu16(msg + 6, &msgid);
390: msg = capimsg_getu32(msg, &NCCI);
391: msg = capimsg_getu16(msg, &Info);
392:
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)))
396: break;
397:
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",
401: sc->sc_unit, NCCI);
402: return;
403: }
404:
405: if (Info == 0) {
406: sc->sc_bchan[bch].ncci = NCCI;
407: sc->sc_bchan[bch].state = B_CONNECT_B3_ACTIVE_IND;
408:
409: } else {
410: SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_OOO); /* XXX */
411: i4b_l4_disconnect_ind(cd);
412: freecd_by_cd(cd);
413:
414: ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_RSVD;
415:
416: printf("capi%d: can't connect_b3 out, info=%04x\n", sc->sc_unit, Info);
417:
418: capi_disconnect_req(sc, cd);
419: }
420: }
421:
422: void capi_connect_b3_active_ind(capi_softc_t *sc, struct mbuf *m_in)
423: {
424: struct mbuf *m = i4b_Dgetmbuf(8 + 4);
425: u_int8_t *msg = mtod(m_in, u_int8_t*);
426: call_desc_t *cd;
427: u_int16_t applid, msgid;
428: u_int32_t NCCI;
429: int bch;
430:
431: if (!m) {
432: printf("capi%d: can't get mbuf for b3_active_ind\n", sc->sc_unit);
433: return;
434: }
435:
436: msg = capimsg_getu16(msg + 2, &applid);
437: msg = capimsg_getu16(msg + 2, &msgid);
438: msg = capimsg_getu32(msg, &NCCI);
439:
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))
443: break;
444:
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",
448: sc->sc_unit, NCCI);
449: return;
450: }
451:
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);
456:
457: msg = capimsg_setu32(msg, NCCI);
458:
459: sc->send(sc, m);
460:
461: sc->sc_bchan[bch].state = B_CONNECTED;
462: i4b_l4_connect_active_ind(cd);
463: }
464:
465: /*
466: // Incoming call setup:
467: // --------------------
468: //
469: // <-- CAPI_CONNECT_IND
470: // (consult Layer 4)
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 -->
478: // (notify Layer 4)
479: */
480:
481: void capi_connect_ind(capi_softc_t *sc, struct mbuf *m_in)
482: {
483: u_int8_t *msg = mtod(m_in, u_int8_t*);
484: call_desc_t *cd;
485: u_int16_t applid, msgid;
486: u_int32_t PLCI;
487: u_int16_t CIP;
488: u_int8_t x, y, z;
489: int bch;
490:
491: if ((cd = reserve_cd()) == NULL) {
492: printf("capi%d: can't get cd for connect_ind\n", sc->sc_unit);
493: return;
494: }
495:
496: cd->controller = sc->ctrl_unit;
497: cd->channelexcl = FALSE;
498:
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 */
503:
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;
509: cd->ilt = NULL;
510: cd->dlt = NULL;
511: cd->display[0] = '\0';
512: cd->datetime[0] = '\0';
513:
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);
518:
519: cd->event = (int) msgid; /* XXX overload */
520: cd->Q931state = (int) PLCI; /* XXX overload */
521:
522: switch (CIP) {
523: case 0x0010:
524: case 0x0001: cd->bprot = BPROT_NONE; break;
525: case 0x0002: cd->bprot = BPROT_RHDLC; break;
526: default:
527: NDBGL4(L4_CAPIDBG, "capi%d: unknown CIP = %d", sc->sc_unit, CIP);
528: cd->bprot = BPROT_NONE;
529: }
530:
531: msg = capimsg_getu8(msg, &x); /* Called party struct len */
532: if (x) {
533: msg = capimsg_getu8(msg, &y); /* Numbering plan */
534: z = x - 1;
535: if (z >= TELNO_MAX) z = (TELNO_MAX-1);
536: strncpy(cd->dst_telno, msg, z);
537: msg += x;
538: x = z;
539: }
540: cd->dst_telno[x] = '\0';
541:
542: msg = capimsg_getu8(msg, &x); /* Calling party struct len */
543: if (x) {
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;
549: }
550: z = x - 2;
551: if (z >= TELNO_MAX) z = (TELNO_MAX-1);
552: strncpy(cd->src_telno, msg, z);
553: msg += x;
554: x = z;
555: }
556: cd->src_telno[x] = '\0';
557:
558: i4b_l4_connect_ind(cd);
559: }
560:
561: void capi_connect_resp(capi_softc_t *sc, call_desc_t *cd)
562: {
563: struct mbuf *m;
564: u_int8_t *msg;
565: u_int16_t msgid;
566: u_int32_t PLCI;
567: int dlen = strlen(cd->dst_telno);
568:
569: m = i4b_Dgetmbuf(8 + 21 + dlen);
570: if (!m) {
571: printf("capi%d: can't get mbuf for connect_resp\n", sc->sc_unit);
572: return;
573: }
574:
575: msgid = (u_int16_t) cd->event;
576: PLCI = (u_int32_t) cd->Q931state;
577:
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);
582:
583: msg = capimsg_setu32(msg, PLCI);
584:
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 */
592: break;
593:
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 */
598: break;
599:
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));
606: } else {
607: msg = capimsg_setu16(msg, 1); /* Ignore */
608: }
609: break;
610:
611: default:
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));
615: }
616:
617: msg = capimsg_setu8(msg, 15); /* B protocol */
618: if (cd->bprot == BPROT_NONE)
619: msg = capimsg_setu16(msg, 1); /* B1 protocol = transparent */
620: else
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 */
627:
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 */
634:
635: sc->send(sc, m);
636: }
637:
638: void capi_connect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
639: {
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;
643: u_int32_t NCCI;
644: int bch;
645:
646: if (!m) {
647: printf("capi%d: can't get mbuf for connect_b3_resp\n", sc->sc_unit);
648: return;
649: }
650:
651: msg = capimsg_getu16(msg + 2, &applid);
652: msg = capimsg_getu16(msg + 2, &msgid);
653: msg = capimsg_getu32(msg, &NCCI);
654:
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)))
658: break;
659:
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);
664:
665: msg = capimsg_setu32(msg, NCCI);
666:
667: if (bch == sc->sc_nbch) {
668: printf("capi%d: can't get cd for connect_b3_resp NCCI %x\n",
669: sc->sc_unit, NCCI);
670: msg = capimsg_setu16(msg, 8); /* Reject, destination OOO */
671:
672: } else {
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 */
676: }
677:
678: msg = capimsg_setu8(msg, 0); /* NCPI */
679:
680: sc->send(sc, m);
681: }
682:
683: /*
684: // Data transfer:
685: // --------------
686: */
687:
688: void capi_data_b3_req(capi_softc_t *sc, int chan, struct mbuf *m_b3)
689: {
690: struct mbuf *m = i4b_Dgetmbuf(8 + 14);
691: u_int8_t *msg;
692: u_int16_t msgid;
693:
694: if (!m) {
695: printf("capi%d: can't get mbuf for data_b3_req\n", sc->sc_unit);
696: return;
697: }
698:
699: msgid = sc->sc_bchan[chan].msgid = sc->sc_msgid++;
700: sc->sc_bchan[chan].busy = 1;
701:
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);
706:
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 */
712:
713: m->m_next = m_b3;
714:
715: sc->send(sc, m);
716: }
717:
718: void capi_data_b3_conf(capi_softc_t *sc, struct mbuf *m_in)
719: {
720: u_int8_t *msg = mtod(m_in, u_int8_t*);
721: u_int32_t NCCI;
722: u_int16_t handle;
723: u_int16_t Info;
724:
725: msg = capimsg_getu32(msg + 8, &NCCI);
726: msg = capimsg_getu16(msg, &handle);
727: msg = capimsg_getu16(msg, &Info);
728:
729: if (Info == 0) {
730: sc->sc_bchan[handle].busy = 0;
731: capi_start_tx(sc, handle);
732:
733: } else {
734: printf("capi%d: data_b3_conf NCCI %x handle %x info=%04x\n",
735: sc->sc_unit, NCCI, handle, Info);
736: }
737: }
738:
739: void capi_data_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
740: {
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;
744: u_int32_t NCCI;
745: u_int16_t handle;
746: int bch;
747:
748: if (!m) {
749: printf("capi%d: can't get mbuf for data_b3_resp\n", sc->sc_unit);
750: return;
751: }
752:
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);
757:
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))
761: break;
762:
763: if (bch == sc->sc_nbch) {
764: printf("capi%d: can't find channel for data_b3_ind NCCI %x\n",
765: sc->sc_unit, NCCI);
766:
767: } else {
768: if (sc->sc_bchan[bch].bprot == BPROT_RHDLC) {
769: /* HDLC drivers use rx_mbuf */
770:
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 */
774:
775: (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
776: sc->sc_bchan[bch].capi_drvr_linktab->unit);
777:
778: } else {
779: /* Telephony drivers use rx_queue */
780:
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 */
785: }
786:
787: (*sc->sc_bchan[bch].capi_drvr_linktab->bch_rx_data_ready)(
788: sc->sc_bchan[bch].capi_drvr_linktab->unit);
789: }
790: }
791:
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);
796:
797: msg = capimsg_setu32(msg, NCCI);
798: msg = capimsg_setu16(msg, handle);
799:
800: sc->send(sc, m);
801: }
802:
803: /*
804: // Connection teardown:
805: // --------------------
806: */
807:
808: void capi_disconnect_req(capi_softc_t *sc, call_desc_t *cd)
809: {
810: struct mbuf *m = i4b_Dgetmbuf(8 + 5);
811: u_int8_t *msg;
812: u_int16_t msgid;
813: u_int32_t PLCI;
814:
815: if (!m) {
816: printf("capi%d: can't get mbuf for disconnect_req\n", sc->sc_unit);
817: return;
818: }
819:
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);
824:
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);
829:
830: msg = capimsg_setu32(msg, PLCI);
831: msg = capimsg_setu8(msg, 0); /* Additional Info */
832:
833: sc->send(sc, m);
834: }
835:
836: void capi_disconnect_conf(capi_softc_t *sc, struct mbuf *m_in)
837: {
838: u_int8_t *msg = mtod(m_in, u_int8_t*);
839: call_desc_t *cd;
840: u_int32_t PLCI;
841: int bch;
842:
843: msg = capimsg_getu32(msg + 8, &PLCI);
844:
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))
848: break;
849:
850: if (bch == sc->sc_nbch) {
851: printf("capi%d: can't find channel for disconnect_conf PLCI %x\n",
852: sc->sc_unit, PLCI);
853: return;
854: }
855:
856: cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
857: if (!cd) {
858: printf("capi%d: can't find cd for disconnect_conf PLCI %x\n",
859: sc->sc_unit, PLCI);
860: } else {
861: i4b_l4_disconnect_ind(cd);
862: freecd_by_cd(cd);
863: }
864:
865: sc->sc_bchan[bch].state = B_FREE;
866: ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
867: }
868:
869: void capi_disconnect_b3_ind(capi_softc_t *sc, struct mbuf *m_in)
870: {
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;
874: u_int32_t NCCI;
875:
876: if (!m) {
877: printf("capi%d: can't get mbuf for disconnect_b3_resp\n", sc->sc_unit);
878: return;
879: }
880:
881: msg = capimsg_getu16(msg + 2, &applid);
882: msg = capimsg_getu16(msg + 2, &msgid);
883: msg = capimsg_getu32(msg, &NCCI);
884:
885: /* XXX update bchan state? XXX */
886:
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);
891:
892: msg = capimsg_setu32(msg, NCCI);
893:
894: sc->send(sc, m);
895: }
896:
897: void capi_disconnect_ind(capi_softc_t *sc, struct mbuf *m_in)
898: {
899: struct mbuf *m = i4b_Dgetmbuf(8 + 4);
900: u_int8_t *msg = mtod(m_in, u_int8_t*);
901: call_desc_t *cd;
902: u_int16_t applid, msgid;
903: u_int32_t PLCI;
904: u_int16_t Reason;
905: int bch;
906:
907: if (!m) {
908: printf("capi%d: can't get mbuf for disconnect_resp\n", sc->sc_unit);
909: return;
910: }
911:
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);
916:
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))
920: break;
921:
922: if (bch < sc->sc_nbch) {
923: /* We may not have a bchan assigned if call was ignored. */
924:
925: cd = cd_by_cdid(sc->sc_bchan[bch].cdid);
926: sc->sc_bchan[bch].state = B_DISCONNECT_IND;
927: } else cd = NULL;
928:
929: if (cd) {
930: if ((Reason & 0xff00) == 0x3400) {
931: SET_CAUSE_TV(cd->cause_in, CAUSET_Q850, (Reason & 0x7f));
932: } else {
933: SET_CAUSE_TV(cd->cause_in, CAUSET_I4B, CAUSE_I4B_NORMAL);
934: }
935:
936: i4b_l4_disconnect_ind(cd);
937: freecd_by_cd(cd);
938:
939: sc->sc_bchan[bch].state = B_FREE;
940: ctrl_desc[sc->ctrl_unit].bch_state[bch] = BCH_ST_FREE;
941: }
942:
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);
947:
948: msg = capimsg_setu32(msg, PLCI);
949:
950: sc->send(sc, m);
951: }
952:
953: #endif /* NI4BCAPI > 0 */