]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/i4b/layer2/i4b_tei.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / i4b / layer2 / i4b_tei.c
1 /*-
2  * Copyright (c) 1997, 2002 Hellmuth Michaelis. 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
26 /*---------------------------------------------------------------------------
27  *
28  *      i4b_tei.c - tei handling procedures
29  *      -----------------------------------
30  *      last edit-date: [Sat Mar  9 17:53:27 2002]
31  *
32  *---------------------------------------------------------------------------*/
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/syslog.h>
40 #include <sys/mbuf.h>
41 #include <sys/socket.h>
42 #include <net/if.h>
43
44 #include <i4b/include/i4b_debug.h>
45
46 #include <i4b/include/i4b_global.h>
47 #include <i4b/include/i4b_l1l2.h>
48 #include <i4b/include/i4b_l2l3.h>
49 #include <i4b/include/i4b_mbuf.h>
50
51 #include <i4b/layer2/i4b_l2.h>
52 #include <i4b/layer2/i4b_l2fsm.h>
53
54 /*---------------------------------------------------------------------------*
55  *      handle a received TEI management frame
56  *---------------------------------------------------------------------------*/
57 void
58 i4b_tei_rxframe(int unit, struct mbuf *m)
59 {
60         l2_softc_t *l2sc = &l2_softc[unit];
61         u_char *ptr = m->m_data;
62         
63         switch(*(ptr + OFF_MT))
64         {
65                 case MT_ID_ASSIGN:
66                         if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
67                             (*(ptr + OFF_RIH) == l2sc->last_rih))
68                         {
69                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
70                                 l2sc->tei_valid = TEI_VALID;
71
72                                 if(l2sc->T202 == TIMER_ACTIVE)
73                                         i4b_T202_stop(l2sc);
74
75                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, l2sc->tei);
76
77                                 log(LOG_INFO, "i4b: unit %d, assigned TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
78
79                                 NDBGL2(L2_TEI_MSG, "TEI ID Assign - TEI = %d", l2sc->tei);
80
81                                 i4b_next_l2state(l2sc, EV_MDASGRQ);
82                         }
83                         break;
84                         
85                 case MT_ID_DENY:
86                         if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
87                             (*(ptr + OFF_RIH) == l2sc->last_rih))
88                         {
89                                 l2sc->tei_valid = TEI_INVALID;
90                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
91
92                                 if(l2sc->tei == GROUP_TEI)
93                                 {
94                                         log(LOG_WARNING, "i4b: unit %d, denied TEI, no TEI values available from exchange!\n", l2sc->unit);
95                                         NDBGL2(L2_TEI_ERR, "TEI ID Denied, No TEI values available from exchange!");
96                                 }
97                                 else
98                                 {
99                                         log(LOG_WARNING, "i4b: unit %d, denied TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
100                                         NDBGL2(L2_TEI_ERR, "TEI ID Denied - TEI = %d", l2sc->tei);
101                                 }                                       
102                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
103                                 i4b_next_l2state(l2sc, EV_MDERRRS);
104                         }
105                         break;
106                         
107                 case MT_ID_CHK_REQ:
108                         if( (l2sc->tei_valid == TEI_VALID) &&
109                             ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
110                               (GROUP_TEI == GET_TEIFROMAI(*(ptr+OFF_AI))) ))
111                         {
112                                 static int lasttei = -1;
113
114                                 if(l2sc->tei != lasttei)
115                                 {
116                                         NDBGL2(L2_TEI_MSG, "TEI ID Check Req - TEI = %d", l2sc->tei);
117                                         lasttei = l2sc->tei;
118                                 }
119                                 
120                                 if(l2sc->T202 == TIMER_ACTIVE)
121                                         i4b_T202_stop(l2sc);
122                                 i4b_tei_chkresp(l2sc);
123                         }
124                         break;
125                         
126                 case MT_ID_REMOVE:
127                         if( (l2sc->tei_valid == TEI_VALID) &&
128                             ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
129                               (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI)))))
130                         {
131                                 l2sc->tei_valid = TEI_INVALID;
132                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
133
134                                 log(LOG_INFO, "i4b: unit %d, removed TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
135                                 NDBGL2(L2_TEI_MSG, "TEI ID Remove - TEI = %d", l2sc->tei);
136                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
137                                 i4b_next_l2state(l2sc, EV_MDREMRQ);
138                         }
139                         break;
140                         
141                 default:
142                         NDBGL2(L2_TEI_ERR, "UNKNOWN TEI MGMT Frame, type = 0x%x", *(ptr + OFF_MT));
143                         i4b_print_frame(m->m_len, m->m_data);
144                         break;
145         }
146         i4b_Dfreembuf(m);
147 }
148
149 /*---------------------------------------------------------------------------*
150  *      allocate and fill up a TEI management frame for sending
151  *---------------------------------------------------------------------------*/
152 static struct mbuf *
153 build_tei_mgmt_frame(l2_softc_t *l2sc, unsigned char type)
154 {
155         struct mbuf *m;
156         
157         if((m = i4b_Dgetmbuf(TEI_MGMT_FRM_LEN)) == NULL)
158                 return(NULL);
159
160         m->m_data[TEIM_SAPIO] = 0xfc;   /* SAPI = 63, CR = 0, EA = 0 */
161         m->m_data[TEIM_TEIO]  = 0xff;   /* TEI = 127, EA = 1 */
162         m->m_data[TEIM_UIO]   = UI;     /* UI */
163         m->m_data[TEIM_MEIO]  = MEI;    /* MEI */
164         m->m_data[TEIM_MTO]   = type;   /* message type */
165         
166         switch(type)
167         {
168                 case MT_ID_REQEST:
169                         i4b_make_rand_ri(l2sc);
170                         m->m_data[TEIM_RILO] = l2sc->last_ril;
171                         m->m_data[TEIM_RIHO] = l2sc->last_rih;
172                         m->m_data[TEIM_AIO] = (GROUP_TEI << 1) | 0x01;
173                         break;
174
175                 case MT_ID_CHK_RSP:
176                         i4b_make_rand_ri(l2sc);
177                         m->m_data[TEIM_RILO] = l2sc->last_ril;
178                         m->m_data[TEIM_RIHO] = l2sc->last_rih;
179                         m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
180                         break;
181                         
182                 case MT_ID_VERIFY:
183                         m->m_data[TEIM_RILO] = 0;
184                         m->m_data[TEIM_RIHO] = 0;
185                         m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
186                         break;
187
188                 default:
189                         i4b_Dfreembuf(m);
190                         panic("build_tei_mgmt_frame: invalid type");
191                         break;
192         }
193         l2sc->stat.tx_tei++;
194         return(m);
195 }
196
197 /*---------------------------------------------------------------------------*
198  *      i4b_tei_assign - TEI assignment procedure (Q.921, 5.3.2, pp 24)
199  *      T202func and N202 _MUST_ be set prior to calling this function !
200  *---------------------------------------------------------------------------*/
201 void
202 i4b_tei_assign(l2_softc_t *l2sc)
203 {
204         struct mbuf *m;
205
206         NDBGL2(L2_TEI_MSG, "tx TEI ID_Request");
207         
208         m = build_tei_mgmt_frame(l2sc, MT_ID_REQEST);
209
210         if(m == NULL)
211                 panic("i4b_tei_assign: no mbuf");               
212
213         i4b_T202_start(l2sc);
214         
215         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
216 }
217
218 /*---------------------------------------------------------------------------*
219  *      i4b_tei_assign - TEI verify procedure (Q.921, 5.3.5, pp 29)
220  *      T202func and N202 _MUST_ be set prior to calling this function !
221  *---------------------------------------------------------------------------*/
222 void
223 i4b_tei_verify(l2_softc_t *l2sc)
224 {
225         struct mbuf *m;
226
227         NDBGL2(L2_TEI_MSG, "tx TEI ID_Verify");
228
229         m = build_tei_mgmt_frame(l2sc, MT_ID_VERIFY);
230
231         if(m == NULL)
232                 panic("i4b_tei_verify: no mbuf");               
233
234         i4b_T202_start(l2sc);
235         
236         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
237 }
238
239 /*---------------------------------------------------------------------------*
240  *      i4b_tei_chkresp - TEI check response procedure (Q.921, 5.3.5, pp 29)
241  *---------------------------------------------------------------------------*/
242 void
243 i4b_tei_chkresp(l2_softc_t *l2sc)
244 {
245         struct mbuf *m;
246         static int lasttei = 0;
247
248         if(l2sc->tei != lasttei)
249         {
250                 lasttei = l2sc->tei;
251                 NDBGL2(L2_TEI_MSG, "tx TEI ID_Check_Response");
252         }
253
254         m = build_tei_mgmt_frame(l2sc, MT_ID_CHK_RSP);
255
256         if(m == NULL)
257                 panic("i4b_tei_chkresp: no mbuf");              
258
259         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
260 }
261
262 /*---------------------------------------------------------------------------*
263  *      generate some 16 bit "random" number used for TEI mgmt Ri field
264  *---------------------------------------------------------------------------*/
265 void
266 i4b_make_rand_ri(l2_softc_t *l2sc)
267 {
268         u_short val;
269
270 #ifdef RANDOMDEV
271         read_random((char *)&val, sizeof(val));
272 #else
273         val = (u_short)random();
274 #endif /* RANDOMDEV */ 
275
276         l2sc->last_rih = (val >> 8) & 0x00ff;
277         l2sc->last_ril = val & 0x00ff;
278 }