2 * Copyright (c) 1997, 1999 Hellmuth Michaelis. 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 *---------------------------------------------------------------------------
27 * i4b_tei.c - tei handling procedures
28 * -----------------------------------
30 * $Id: i4b_tei.c,v 1.17 1999/12/13 21:25:27 hm Exp $
34 * last edit-date: [Mon Dec 13 22:04:24 1999]
36 *---------------------------------------------------------------------------*/
45 #include <sys/param.h>
47 #if defined(__FreeBSD__)
48 #include <sys/ioccom.h>
49 #include <sys/random.h>
51 #include <sys/ioctl.h>
54 #include <sys/kernel.h>
55 #include <sys/systm.h>
56 #include <sys/syslog.h>
58 #include <sys/socket.h>
62 #include <machine/i4b_debug.h>
63 #include <machine/i4b_ioctl.h>
65 #include <i4b/i4b_debug.h>
66 #include <i4b/i4b_ioctl.h>
69 #include <i4b/include/i4b_global.h>
70 #include <i4b/include/i4b_l1l2.h>
71 #include <i4b/include/i4b_l2l3.h>
72 #include <i4b/include/i4b_isdnq931.h>
73 #include <i4b/include/i4b_mbuf.h>
75 #include <i4b/layer2/i4b_l2.h>
76 #include <i4b/layer2/i4b_l2fsm.h>
78 /*---------------------------------------------------------------------------*
79 * handle a received TEI management frame
80 *---------------------------------------------------------------------------*/
82 i4b_tei_rxframe(int unit, struct mbuf *m)
84 l2_softc_t *l2sc = &l2_softc[unit];
85 u_char *ptr = m->m_data;
87 switch(*(ptr + OFF_MT))
90 if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
91 (*(ptr + OFF_RIH) == l2sc->last_rih))
93 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
94 l2sc->tei_valid = TEI_VALID;
96 if(l2sc->T202 == TIMER_ACTIVE)
99 MDL_Status_Ind(l2sc->unit, STI_TEIASG, l2sc->tei);
101 log(LOG_INFO, "i4b: unit %d, assigned TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
103 DBGL2(L2_TEI_MSG, "i4b_tei_rx_frame", ("TEI ID Assign - TEI = %d\n", l2sc->tei));
105 i4b_next_l2state(l2sc, EV_MDASGRQ);
110 if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
111 (*(ptr + OFF_RIH) == l2sc->last_rih))
113 l2sc->tei_valid = TEI_INVALID;
114 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
116 if(l2sc->tei == GROUP_TEI)
118 log(LOG_WARNING, "i4b: unit %d, denied TEI, no TEI values available from exchange!\n", l2sc->unit);
119 DBGL2(L2_TEI_ERR, "i4b_tei_rx_frame", ("TEI ID Denied, No TEI values available from exchange!\n"));
123 log(LOG_WARNING, "i4b: unit %d, denied TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
124 DBGL2(L2_TEI_ERR, "i4b_tei_rx_frame", ("TEI ID Denied - TEI = %d\n", l2sc->tei));
126 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
127 i4b_next_l2state(l2sc, EV_MDERRRS);
132 if( (l2sc->tei_valid == TEI_VALID) &&
133 ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
134 (GROUP_TEI == GET_TEIFROMAI(*(ptr+OFF_AI))) ))
136 static int lasttei = -1;
138 if(l2sc->tei != lasttei)
140 DBGL2(L2_TEI_MSG, "i4b_tei_rx_frame", ("TEI ID Check Req - TEI = %d\n", l2sc->tei));
144 if(l2sc->T202 == TIMER_ACTIVE)
146 i4b_tei_chkresp(l2sc);
151 if( (l2sc->tei_valid == TEI_VALID) &&
152 ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
153 (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI)))))
155 l2sc->tei_valid = TEI_INVALID;
156 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
158 log(LOG_INFO, "i4b: unit %d, removed TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
159 DBGL2(L2_TEI_MSG, "i4b_tei_rx_frame", ("TEI ID Remove - TEI = %d\n", l2sc->tei));
160 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
161 i4b_next_l2state(l2sc, EV_MDREMRQ);
166 DBGL2(L2_TEI_ERR, "i4b_tei_rx_frame", ("UNKNOWN TEI MGMT Frame, type = 0x%x\n", *(ptr + OFF_MT)));
167 i4b_print_frame(m->m_len, m->m_data);
173 /*---------------------------------------------------------------------------*
174 * allocate and fill up a TEI management frame for sending
175 *---------------------------------------------------------------------------*/
177 build_tei_mgmt_frame(l2_softc_t *l2sc, unsigned char type)
181 if((m = i4b_Dgetmbuf(TEI_MGMT_FRM_LEN)) == NULL)
184 m->m_data[TEIM_SAPIO] = 0xfc; /* SAPI = 63, CR = 0, EA = 0 */
185 m->m_data[TEIM_TEIO] = 0xff; /* TEI = 127, EA = 1 */
186 m->m_data[TEIM_UIO] = UI; /* UI */
187 m->m_data[TEIM_MEIO] = MEI; /* MEI */
188 m->m_data[TEIM_MTO] = type; /* message type */
193 i4b_make_rand_ri(l2sc);
194 m->m_data[TEIM_RILO] = l2sc->last_ril;
195 m->m_data[TEIM_RIHO] = l2sc->last_rih;
196 m->m_data[TEIM_AIO] = (GROUP_TEI << 1) | 0x01;
200 i4b_make_rand_ri(l2sc);
201 m->m_data[TEIM_RILO] = l2sc->last_ril;
202 m->m_data[TEIM_RIHO] = l2sc->last_rih;
203 m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
207 m->m_data[TEIM_RILO] = 0;
208 m->m_data[TEIM_RIHO] = 0;
209 m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
214 panic("build_tei_mgmt_frame: invalid type");
221 /*---------------------------------------------------------------------------*
222 * i4b_tei_assign - TEI assignment procedure (Q.921, 5.3.2, pp 24)
223 * T202func and N202 _MUST_ be set prior to calling this function !
224 *---------------------------------------------------------------------------*/
226 i4b_tei_assign(l2_softc_t *l2sc)
230 DBGL2(L2_TEI_MSG, "i4b_tei_assign", ("tx TEI ID_Request\n"));
232 m = build_tei_mgmt_frame(l2sc, MT_ID_REQEST);
235 panic("i4b_tei_assign: no mbuf");
237 i4b_T202_start(l2sc);
239 PH_Data_Req(l2sc->unit, m, MBUF_FREE);
242 /*---------------------------------------------------------------------------*
243 * i4b_tei_assign - TEI verify procedure (Q.921, 5.3.5, pp 29)
244 * T202func and N202 _MUST_ be set prior to calling this function !
245 *---------------------------------------------------------------------------*/
247 i4b_tei_verify(l2_softc_t *l2sc)
251 DBGL2(L2_TEI_MSG, "i4b_tei_verify", ("tx TEI ID_Verify\n"));
253 m = build_tei_mgmt_frame(l2sc, MT_ID_VERIFY);
256 panic("i4b_tei_verify: no mbuf");
258 i4b_T202_start(l2sc);
260 PH_Data_Req(l2sc->unit, m, MBUF_FREE);
263 /*---------------------------------------------------------------------------*
264 * i4b_tei_chkresp - TEI check response procedure (Q.921, 5.3.5, pp 29)
265 *---------------------------------------------------------------------------*/
267 i4b_tei_chkresp(l2_softc_t *l2sc)
270 static int lasttei = 0;
272 if(l2sc->tei != lasttei)
275 DBGL2(L2_TEI_MSG, "i4b_tei_chkresp", ("tx TEI ID_Check_Response\n"));
278 m = build_tei_mgmt_frame(l2sc, MT_ID_CHK_RSP);
281 panic("i4b_tei_chkresp: no mbuf");
283 PH_Data_Req(l2sc->unit, m, MBUF_FREE);
286 /*---------------------------------------------------------------------------*
287 * generate some 16 bit "random" number used for TEI mgmt Ri field
288 *---------------------------------------------------------------------------*/
290 i4b_make_rand_ri(l2_softc_t *l2sc)
293 #if defined(__FreeBSD__)
296 read_random((char *)&val, sizeof(val));
300 register u_short val;
302 static int called = 42;
304 val = (l2sc->last_rih << 8) | l2sc->last_ril;
308 for(i=0; i < 50 ; i++, val++)
312 val ^= (time.tv_sec >> 16) ^ time.tv_usec;
314 val ^= time.tv_sec ^ (time.tv_usec >> 16);
316 if(val != 0 && val != 0xffff)
320 l2sc->last_rih = (val >> 8) & 0x00ff;
321 l2sc->last_ril = val & 0x00ff;
324 #endif /* NI4BQ921 > 0 */