1 /** $MirOS: src/sys/netisdn/i4b_capi_llif.c,v 1.2 2005/03/06 21:28:24 tg Exp $ */
2 /* $NetBSD: i4b_capi_llif.c,v 1.2 2003/09/26 15:17:23 pooka Exp $ */
3
4 /*
5 * Copyright (c) 2001 Cubical Solutions Ltd. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * capi/capi_llif.c The i4b CAPI link layer interface.
29 *
30 * $FreeBSD: src/sys/i4b/capi/capi_llif.c,v 1.1 2001/05/25 08:39:31 hm Exp $
31 */
32
33 #include <sys/cdefs.h>
34
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/systm.h>
38 #include <sys/mbuf.h>
39 #include <sys/socket.h>
40 #include <sys/timeout.h>
41 #include <net/if.h>
42
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>
52
53 /*
54 // capi_ll_control
55 // CAPI link layer control routine. Called by a link layer
56 // driver when its state changes.
57 */
58
59 int
capi_ll_control(capi_softc_t * sc,int op,int arg)60 capi_ll_control(capi_softc_t *sc, int op, int arg)
61 {
62 switch (op) {
63 case CAPI_CTRL_READY:
64 if (arg) {
65 sc->sc_state = C_READY;
66
67 /*
68 * Register our CAPI ApplId and send CAPI_LISTEN_REQ
69 * with CIP Mask value 1 (match all).
70 */
71
72 sc->reg_appl(sc, I4BCAPI_APPLID, sc->sc_nbch);
73 capi_listen_req(sc, 0x10007);
74
75 } else {
76 sc->sc_state = C_DOWN;
77 /* XXX go through cds and notify L4 of pdeact? XXX */
78 }
79 break;
80
81 case CAPI_CTRL_PROFILE:
82 bcopy((char*) arg, &sc->sc_profile, sizeof(sc->sc_profile));
83 break;
84
85 case CAPI_CTRL_NEW_NCCI:
86 case CAPI_CTRL_FREE_NCCI:
87 /* We ignore the controller's NCCI notifications. */
88 break;
89
90 default:
91 printf("capi%d: unknown control %d\n", sc->sc_unit, op);
92 }
93
94 return 0;
95 }
96
97 /*
98 // i4b_capi_handlers
99 // Array of message-handler pairs used to dispatch CAPI
100 // messages sent to I4BCAPI_APPLID.
101 */
102
103 static struct capi_cmdtab {
104 u_int16_t cmd;
105 void (*handler)(capi_softc_t *, struct mbuf *);
106 } i4b_capi_handlers[] = {
107 { CAPI_LISTEN_CONF, capi_listen_conf },
108 { CAPI_INFO_IND, capi_info_ind },
109 { CAPI_ALERT_CONF, capi_alert_conf },
110 { CAPI_CONNECT_CONF, capi_connect_conf },
111 { CAPI_CONNECT_IND, capi_connect_ind },
112 { CAPI_CONNECT_ACTIVE_IND, capi_connect_active_ind },
113 { CAPI_CONNECT_B3_CONF, capi_connect_b3_conf },
114 { CAPI_CONNECT_B3_IND, capi_connect_b3_ind },
115 { CAPI_CONNECT_B3_ACTIVE_IND, capi_connect_b3_active_ind },
116 { CAPI_DATA_B3_CONF, capi_data_b3_conf },
117 { CAPI_DATA_B3_IND, capi_data_b3_ind },
118 { CAPI_DISCONNECT_B3_IND, capi_disconnect_b3_ind },
119 { CAPI_DISCONNECT_CONF, capi_disconnect_conf },
120 { CAPI_DISCONNECT_IND, capi_disconnect_ind },
121 { 0, 0 }
122 };
123
124 /*
125 // capi_ll_receive
126 // CAPI link layer receive upcall. Called by a link layer
127 // driver to dispatch incoming CAPI messages.
128 */
129
130 int
capi_ll_receive(capi_softc_t * sc,struct mbuf * m)131 capi_ll_receive(capi_softc_t *sc, struct mbuf *m)
132 {
133 u_int8_t *p = mtod(m, u_int8_t*);
134 u_int16_t len, applid, msgid, cmd;
135
136 capimsg_getu16(p + 0, &len);
137 capimsg_getu16(p + 2, &applid);
138 capimsg_getu16(p + 4, &cmd);
139 capimsg_getu16(p + 6, &msgid);
140
141 #if 0
142 printf("capi%d: ll_receive hdr %04x %04x %04x %04x\n", sc->sc_unit,
143 len, applid, cmd, msgid);
144 #endif
145
146 if (applid == I4BCAPI_APPLID) {
147 struct capi_cmdtab *e;
148 for (e = i4b_capi_handlers; e->cmd && e->cmd != cmd; e++);
149 if (e->cmd) (*e->handler)(sc, m);
150 else printf("capi%d: unknown message %04x\n", sc->sc_unit, cmd);
151
152 } else {
153 /* XXX we could handle arbitrary ApplIds here XXX */
154 printf("capi%d: message %04x for unknown applid %d\n", sc->sc_unit,
155 cmd, applid);
156 }
157
158 if (m->m_next) {
159 i4b_Bfreembuf(m->m_next);
160 m->m_next = NULL;
161 }
162 i4b_Dfreembuf(m);
163 return(0);
164 }
165