Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / uni / sscf_uni_lower.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/netatm/uni/sscf_uni_lower.c,v 1.4 1999/08/28 00:48:56 peter Exp $
27  *
28  */
29
30 /*
31  * ATM Forum UNI Support
32  * ---------------------
33  *
34  * SSCF UNI - SSCF_UNI SAP interface processing
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include <netatm/uni/uni.h>
41 #include <netatm/uni/sscop.h>
42 #include <netatm/uni/sscf_uni.h>
43 #include <netatm/uni/sscf_uni_var.h>
44
45 #ifndef lint
46 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/sscf_uni_lower.c,v 1.4 1999/08/28 00:48:56 peter Exp $");
47 #endif
48
49
50 /*
51  * Local variables
52  */
53 static struct sscop_parms       sscf_uni_sscop_parms = {
54         4096,                           /* sp_maxinfo */
55         4096,                           /* sp_maxuu */
56         4,                              /* sp_maxcc */
57         25,                             /* sp_maxpd */
58         1 * ATM_HZ,                     /* sp_timecc */
59         2 * ATM_HZ,                     /* sp_timekeep */
60         7 * ATM_HZ,                     /* sp_timeresp */
61         1 * ATM_HZ,                     /* sp_timepoll */
62         15 * ATM_HZ,                    /* sp_timeidle */
63         80                              /* sp_rcvwin */
64 };
65
66
67 /*
68  * SSCF_UNI Lower Stack Command Handler
69  * 
70  * This function will receive all of the stack commands issued from the 
71  * layer above SSCF UNI (ie. Q.2931).
72  *
73  * Arguments:
74  *      cmd     stack command code
75  *      tok     session token
76  *      arg1    command specific argument
77  *      arg2    command specific argument
78  *
79  * Returns:
80  *      none
81  *
82  */
83 void
84 sscf_uni_lower(cmd, tok, arg1, arg2)
85         int     cmd;
86         void    *tok;
87         int     arg1;
88         int     arg2;
89 {
90         struct univcc   *uvp = (struct univcc *)tok;
91         Atm_connvc      *cvp = uvp->uv_connvc;
92         enum sscop_vers vers;
93         int             err;
94
95         ATM_DEBUG5("sscf_uni_lower: cmd=0x%x, uvp=%p, ustate=%d, arg1=0x%x, arg2=0x%x\n",
96                 cmd, uvp, uvp->uv_ustate, arg1, arg2);
97
98         switch (cmd) {
99
100         case SSCF_UNI_INIT:
101                 /*
102                  * Validate state
103                  */
104                 if (uvp->uv_ustate != UVU_INST) {
105                         log(LOG_ERR, "sscf_uni_lower: SSCF_INIT in ustate=%d\n",
106                                 uvp->uv_ustate);
107                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
108                         break;
109                 }
110
111                 /*
112                  * Validate UNI version
113                  */
114                 if ((enum uni_vers)arg1 == UNI_VERS_3_0)
115                         vers = SSCOP_VERS_QSAAL;
116                 else if ((enum uni_vers)arg1 == UNI_VERS_3_1)
117                         vers = SSCOP_VERS_Q2110;
118                 else {
119                         sscf_uni_abort(uvp, "sscf_uni: bad version\n");
120                         break;
121                 }
122                 uvp->uv_vers = (enum uni_vers)arg1;
123
124                 /*
125                  * Make ourselves ready and pass on the INIT
126                  */
127                 uvp->uv_ustate = UVU_RELEASED;
128                 uvp->uv_lstate = UVL_IDLE;
129
130                 STACK_CALL(SSCOP_INIT, uvp->uv_lower, uvp->uv_tokl, cvp, 
131                         (int)vers, (int)&sscf_uni_sscop_parms, err);
132                 if (err) {
133                         /*
134                          * Should never happen
135                          */
136                         sscf_uni_abort(uvp, "sscf_uni: INIT failure\n");
137                 }
138                 break;
139
140         case SSCF_UNI_TERM:
141                 /*
142                  * Set termination states
143                  */
144                 uvp->uv_ustate = UVU_TERM;
145                 uvp->uv_lstate = UVL_TERM;
146
147                 /*
148                  * Pass the TERM down the stack
149                  */
150                 STACK_CALL(SSCOP_TERM, uvp->uv_lower, uvp->uv_tokl, cvp,
151                         0, 0, err);
152                 if (err) {
153                         /*
154                          * Should never happen
155                          */
156                         sscf_uni_abort(uvp, "sscf_uni: TERM failure\n");
157                         return;
158                 }
159                 atm_free((caddr_t)uvp);
160                 sscf_uni_vccnt--;
161                 break;
162
163         case SSCF_UNI_ESTABLISH_REQ:
164                 /*
165                  * Validation based on user state
166                  */
167                 switch (uvp->uv_ustate) {
168
169                 case UVU_RELEASED:
170                 case UVU_PRELEASE:
171                         /*
172                          * Establishing a new connection
173                          */
174                         uvp->uv_ustate = UVU_PACTIVE;
175                         uvp->uv_lstate = UVL_OUTCONN;
176                         STACK_CALL(SSCOP_ESTABLISH_REQ, uvp->uv_lower, 
177                                 uvp->uv_tokl, cvp, 
178                                 SSCOP_UU_NULL, SSCOP_BR_YES, err);
179                         if (err) {
180                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
181                                 return;
182                         }
183                         break;
184
185                 case UVU_ACTIVE:
186                         /*
187                          * Resynchronizing a connection
188                          */
189                         uvp->uv_ustate = UVU_PACTIVE;
190                         if (uvp->uv_vers == UNI_VERS_3_0) {
191                                 uvp->uv_lstate = UVL_OUTCONN;
192                                 STACK_CALL(SSCOP_ESTABLISH_REQ, uvp->uv_lower, 
193                                         uvp->uv_tokl, cvp, 
194                                         SSCOP_UU_NULL, SSCOP_BR_YES, err);
195                         } else {
196                                 uvp->uv_lstate = UVL_OUTRESYN;
197                                 STACK_CALL(SSCOP_RESYNC_REQ, uvp->uv_lower, 
198                                         uvp->uv_tokl, cvp, 
199                                         SSCOP_UU_NULL, 0, err);
200                         }
201                         if (err) {
202                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
203                                 return;
204                         }
205                         break;
206
207                 case UVU_TERM:
208                         /* Ignore */
209                         break;
210
211                 case UVU_INST:
212                 case UVU_PACTIVE:
213                 default:
214                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
215                                 cmd, uvp->uv_ustate);
216                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
217                 }
218                 break;
219
220         case SSCF_UNI_RELEASE_REQ:
221                 /*
222                  * Validate re-establishment parameter
223                  */
224                 switch (arg1) {
225
226                 case SSCF_UNI_ESTIND_YES:
227                         uvp->uv_flags &= ~UVF_NOESTIND;
228                         break;
229
230                 case SSCF_UNI_ESTIND_NO:
231                         uvp->uv_flags |= UVF_NOESTIND;
232                         break;
233
234                 default:
235                         sscf_uni_abort(uvp, "sscf_uni: bad estind value\n");
236                         return;
237                 }
238
239                 /*
240                  * Validation based on user state
241                  */
242                 switch (uvp->uv_ustate) {
243
244                 case UVU_RELEASED:
245                         /*
246                          * Releasing a non-existant connection
247                          */
248                         STACK_CALL(SSCF_UNI_RELEASE_CNF, uvp->uv_upper, 
249                                 uvp->uv_toku, cvp, 
250                                 0, 0, err);
251                         if (err) {
252                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
253                                 return;
254                         }
255                         break;
256
257                 case UVU_PACTIVE:
258                 case UVU_ACTIVE:
259                         /*
260                          * Releasing a connection
261                          */
262                         uvp->uv_ustate = UVU_PRELEASE;
263                         uvp->uv_lstate = UVL_OUTDISC;
264                         STACK_CALL(SSCOP_RELEASE_REQ, uvp->uv_lower, 
265                                 uvp->uv_tokl, cvp, 
266                                 SSCOP_UU_NULL, 0, err);
267                         if (err) {
268                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
269                                 return;
270                         }
271                         break;
272
273                 case UVU_TERM:
274                         /* Ignore */
275                         break;
276
277                 case UVU_INST:
278                 case UVU_PRELEASE:
279                 default:
280                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
281                                 cmd, uvp->uv_ustate);
282                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
283                 }
284                 break;
285
286         case SSCF_UNI_DATA_REQ:
287 #ifdef notdef
288                 sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "DATA_REQ");
289 #endif
290
291                 /*
292                  * Validation based on user state
293                  */
294                 switch (uvp->uv_ustate) {
295
296                 case UVU_ACTIVE:
297                         /*
298                          * Send assured data on connection
299                          */
300                         STACK_CALL(SSCOP_DATA_REQ, uvp->uv_lower, 
301                                 uvp->uv_tokl, cvp, 
302                                 arg1, 0, err);
303                         if (err) {
304                                 KB_FREEALL((KBuffer *)arg1);
305                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
306                                 return;
307                         }
308                         break;
309
310                 case UVU_RELEASED:
311                 case UVU_TERM:
312                         /*
313                          * Release supplied buffers and ignore
314                          */
315                         KB_FREEALL((KBuffer *)arg1);
316                         break;
317
318                 case UVU_INST:
319                 case UVU_PACTIVE:
320                 case UVU_PRELEASE:
321                 default:
322                         KB_FREEALL((KBuffer *)arg1);
323                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
324                                 cmd, uvp->uv_ustate);
325                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
326                 }
327                 break;
328
329         case SSCF_UNI_UNITDATA_REQ:
330 #ifdef notdef
331                 sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "UNITDATA_REQ");
332 #endif
333
334                 /*
335                  * Validation based on user state
336                  */
337                 switch (uvp->uv_ustate) {
338
339                 case UVU_RELEASED:
340                 case UVU_PACTIVE:
341                 case UVU_PRELEASE:
342                 case UVU_ACTIVE:
343                         /*
344                          * Send unassured data on connection
345                          */
346                         STACK_CALL(SSCOP_UNITDATA_REQ, uvp->uv_lower, 
347                                 uvp->uv_tokl, cvp, 
348                                 arg1, 0, err);
349                         if (err) {
350                                 KB_FREEALL((KBuffer *)arg1);
351                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
352                                 return;
353                         }
354                         break;
355
356                 case UVU_TERM:
357                         /*
358                          * Release supplied buffers and ignore
359                          */
360                         KB_FREEALL((KBuffer *)arg1);
361                         break;
362
363                 case UVU_INST:
364                 default:
365                         KB_FREEALL((KBuffer *)arg1);
366                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
367                                 cmd, uvp->uv_ustate);
368                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
369                 }
370                 break;
371
372         default:
373                 log(LOG_ERR, "sscf_uni_lower: unknown cmd 0x%x, uvp=%p\n",
374                         cmd, uvp);
375         }
376
377         return;
378 }
379