]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/i4b/layer2/i4b_uframe.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / i4b / layer2 / i4b_uframe.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_uframe.c - routines for handling U-frames
29  *      -----------------------------------------------
30  *      last edit-date: [Sat Mar  9 17:54:08 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/mbuf.h>
40 #include <sys/socket.h>
41 #include <net/if.h>
42
43 #include <i4b/include/i4b_debug.h>
44
45 #include <i4b/include/i4b_l1l2.h>
46 #include <i4b/include/i4b_l2l3.h>
47 #include <i4b/include/i4b_mbuf.h>
48
49 #include <i4b/layer2/i4b_l2.h>
50 #include <i4b/layer2/i4b_l2fsm.h>
51
52 /*---------------------------------------------------------------------------*
53  *      process a received U-frame
54  *---------------------------------------------------------------------------*/
55 void
56 i4b_rxd_u_frame(int unit, struct mbuf *m)
57 {
58         l2_softc_t *l2sc = &l2_softc[unit];
59         u_char *ptr = m->m_data;
60
61         int sapi = GETSAPI(*(ptr + OFF_SAPI));
62         int tei = GETTEI(*(ptr + OFF_TEI));     
63         int pfbit = GETUPF(*(ptr + OFF_CNTL));
64         
65         switch(*(ptr + OFF_CNTL) & ~UPFBIT)
66         {
67                 /* commands */
68
69                 case SABME:
70                         if((l2sc->tei_valid == TEI_VALID) &&
71                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
72                         {
73                                 l2sc->stat.rx_sabme++;
74                                 NDBGL2(L2_U_MSG, "SABME, sapi = %d, tei = %d", sapi, tei);
75                                 l2sc->rxd_PF = pfbit;
76                                 i4b_next_l2state(l2sc, EV_RXSABME);
77                         }
78                         i4b_Dfreembuf(m);
79                         break;
80
81                 case UI:
82                         if(sapi == SAPI_L2M &&
83                            tei == GROUP_TEI &&
84                            *(ptr + OFF_MEI) == MEI)
85                         {
86                                 /* layer 2 management (SAPI = 63) */
87                                 l2sc->stat.rx_tei++;
88                                 i4b_tei_rxframe(unit, m);
89                         }
90                         else if(sapi == SAPI_CCP && tei == GROUP_TEI)
91                         {
92                                 /* call control (SAPI = 0) */
93                                 l2sc->stat.rx_ui++;
94                                 /* strip ui header */
95                                 m_adj(m, UI_HDR_LEN);
96                                 /* to upper layer */
97                                 DL_Unit_Data_Ind(unit, m);
98                         }
99                         else
100                         {
101                                 l2sc->stat.err_rx_badui++;
102                                 NDBGL2(L2_U_ERR, "unknown UI frame!");
103                                 i4b_Dfreembuf(m);                               
104                         }
105                         break;
106                         
107                 case DISC:
108                         if((l2sc->tei_valid == TEI_VALID) &&
109                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
110                         {               
111                                 l2sc->stat.rx_disc++;
112                                 NDBGL2(L2_U_MSG, "DISC, sapi = %d, tei = %d", sapi, tei);
113                                 l2sc->rxd_PF = pfbit;
114                                 i4b_next_l2state(l2sc, EV_RXDISC);
115                         }
116                         i4b_Dfreembuf(m);
117                         break;
118
119                 case XID:
120                         if((l2sc->tei_valid == TEI_VALID) &&
121                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
122                         {               
123                                 l2sc->stat.rx_xid++;
124                                 NDBGL2(L2_U_MSG, "XID, sapi = %d, tei = %d", sapi, tei);
125                         }
126                         i4b_Dfreembuf(m);                       
127                         break;
128                         
129                 /* responses */
130
131                 case DM:
132                         if((l2sc->tei_valid == TEI_VALID) &&
133                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
134                         {               
135                                 l2sc->stat.rx_dm++;
136                                 NDBGL2(L2_U_MSG, "DM, sapi = %d, tei = %d", sapi, tei);
137                                 i4b_print_frame(m->m_len, m->m_data);
138                                 l2sc->rxd_PF = pfbit;
139                                 i4b_next_l2state(l2sc, EV_RXDM);
140                         }
141                         i4b_Dfreembuf(m);
142                         break;
143                         
144                 case UA:
145                         if((l2sc->tei_valid == TEI_VALID) &&
146                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
147                         {               
148                                 l2sc->stat.rx_ua++;
149                                 NDBGL2(L2_U_MSG, "UA, sapi = %d, tei = %d", sapi, tei);
150                                 l2sc->rxd_PF = pfbit;
151                                 i4b_next_l2state(l2sc, EV_RXUA);
152                         }
153                         i4b_Dfreembuf(m);                       
154                         break;                  
155
156                 case FRMR:
157                         if((l2sc->tei_valid == TEI_VALID) &&
158                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
159                         {
160                                 l2sc->stat.rx_frmr++;
161                                 NDBGL2(L2_U_MSG, "FRMR, sapi = %d, tei = %d", sapi, tei);
162                                 l2sc->rxd_PF = pfbit;
163                                 i4b_next_l2state(l2sc, EV_RXFRMR);
164                         }
165                         i4b_Dfreembuf(m);                       
166                         break;
167
168                 default:
169                         if((l2sc->tei_valid == TEI_VALID) &&
170                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
171                         {               
172                                 NDBGL2(L2_U_ERR, "UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei);
173                                 i4b_print_frame(m->m_len, m->m_data);
174                         }
175                         else
176                         {               
177                                 NDBGL2(L2_U_ERR, "not mine -  UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei);
178                                 i4b_print_frame(m->m_len, m->m_data);
179                         }
180                         l2sc->stat.err_rx_badui++;                      
181                         i4b_Dfreembuf(m);                       
182                         break;
183         }
184 }
185
186 /*---------------------------------------------------------------------------*
187  *      build U-frame for sending
188  *---------------------------------------------------------------------------*/
189 struct mbuf *
190 i4b_build_u_frame(l2_softc_t *l2sc, crbit_to_nt_t crbit, pbit_t pbit, u_char type)
191 {
192         struct mbuf *m;
193         
194         if((m = i4b_Dgetmbuf(U_FRAME_LEN)) == NULL)
195                 return(NULL);
196
197         PUTSAPI(SAPI_CCP, crbit, m->m_data[OFF_SAPI]);
198                 
199         PUTTEI(l2sc->tei, m->m_data[OFF_TEI]);
200
201         if(pbit)
202                 m->m_data[OFF_CNTL] = type | UPBITSET;
203         else
204                 m->m_data[OFF_CNTL] = type & ~UPBITSET;
205
206         return(m);
207 }
208
209 /*---------------------------------------------------------------------------*
210  *      transmit SABME command
211  *---------------------------------------------------------------------------*/
212 void
213 i4b_tx_sabme(l2_softc_t *l2sc, pbit_t pbit)
214 {
215         struct mbuf *m;
216
217         l2sc->stat.tx_sabme++;
218         NDBGL2(L2_U_MSG, "tx SABME, tei = %d", l2sc->tei);
219         m = i4b_build_u_frame(l2sc, CR_CMD_TO_NT, pbit, SABME);
220         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
221 }
222
223 /*---------------------------------------------------------------------------*
224  *      transmit DM response
225  *---------------------------------------------------------------------------*/
226 void
227 i4b_tx_dm(l2_softc_t *l2sc, fbit_t fbit)
228 {
229         struct mbuf *m;
230
231         l2sc->stat.tx_dm++;     
232         NDBGL2(L2_U_MSG, "tx DM, tei = %d", l2sc->tei);
233         m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, DM);
234         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
235 }
236
237 /*---------------------------------------------------------------------------*
238  *      transmit DISC command
239  *---------------------------------------------------------------------------*/
240 void
241 i4b_tx_disc(l2_softc_t *l2sc, pbit_t pbit)
242 {
243         struct mbuf *m;
244         
245         l2sc->stat.tx_disc++;
246         NDBGL2(L2_U_MSG, "tx DISC, tei = %d", l2sc->tei);
247         m = i4b_build_u_frame(l2sc, CR_CMD_TO_NT, pbit, DISC);
248         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
249 }
250
251 /*---------------------------------------------------------------------------*
252  *      transmit UA response
253  *---------------------------------------------------------------------------*/
254 void
255 i4b_tx_ua(l2_softc_t *l2sc, fbit_t fbit)
256 {
257         struct mbuf *m;
258         
259         l2sc->stat.tx_ua++;
260         NDBGL2(L2_U_MSG, "tx UA, tei = %d", l2sc->tei);
261         m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, UA);
262         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
263 }
264
265 /*---------------------------------------------------------------------------*
266  *      transmit FRMR response
267  *---------------------------------------------------------------------------*/
268 void
269 i4b_tx_frmr(l2_softc_t *l2sc, fbit_t fbit)
270 {
271         struct mbuf *m;
272         
273         l2sc->stat.tx_frmr++;
274         NDBGL2(L2_U_MSG, "tx FRMR, tei = %d", l2sc->tei);
275         m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, FRMR);
276         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
277 }