3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
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.
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.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/uni/unisig_decode.c,v 1.5 2000/01/17 20:49:56 mks Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/unisig_decode.c,v 1.2 2003/06/17 04:28:49 dillon Exp $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
34 * Message formatting module
38 #include <netatm/kern_include.h>
40 #include <netatm/uni/unisig_var.h>
41 #include <netatm/uni/unisig_msg.h>
42 #include <netatm/uni/unisig_mbuf.h>
43 #include <netatm/uni/unisig_decode.h>
45 #define ALLOC_IE(ie) \
46 (ie) = (struct ie_generic *) atm_allocate(&unisig_iepool); \
54 static int usf_dec_ie __P((struct usfmt *, struct unisig_msg *, struct ie_generic *));
55 static int usf_dec_ie_hdr __P((struct usfmt *, struct ie_generic *));
56 static int usf_dec_ie_aalp __P((struct usfmt *, struct ie_generic *));
57 static int usf_dec_ie_clrt __P((struct usfmt *, struct ie_generic *));
58 static int usf_dec_ie_bbcp __P((struct usfmt *, struct ie_generic *));
59 static int usf_dec_ie_bhli __P((struct usfmt *, struct ie_generic *));
60 static int usf_dec_ie_blli __P((struct usfmt *, struct ie_generic *));
61 static int usf_dec_ie_clst __P((struct usfmt *, struct ie_generic *));
62 static int usf_dec_ie_cdad __P((struct usfmt *, struct ie_generic *));
63 static int usf_dec_ie_cdsa __P((struct usfmt *, struct ie_generic *));
64 static int usf_dec_ie_cgad __P((struct usfmt *, struct ie_generic *));
65 static int usf_dec_ie_cgsa __P((struct usfmt *, struct ie_generic *));
66 static int usf_dec_ie_caus __P((struct usfmt *, struct ie_generic *));
67 static int usf_dec_ie_cnid __P((struct usfmt *, struct ie_generic *));
68 static int usf_dec_ie_qosp __P((struct usfmt *, struct ie_generic *));
69 static int usf_dec_ie_brpi __P((struct usfmt *, struct ie_generic *));
70 static int usf_dec_ie_rsti __P((struct usfmt *, struct ie_generic *));
71 static int usf_dec_ie_bsdc __P((struct usfmt *, struct ie_generic *));
72 static int usf_dec_ie_trnt __P((struct usfmt *, struct ie_generic *));
73 static int usf_dec_ie_uimp __P((struct usfmt *, struct ie_generic *));
74 static int usf_dec_ie_ident __P((struct usfmt *, struct ie_generic *,
75 struct ie_decode_tbl *));
76 static int usf_dec_atm_addr __P((struct usfmt *, Atm_addr *, int));
80 * Table associating IE type with IE vector index
82 u_char unisig_ie_ident_vec[] = {
108 * Tables specifying which IEs are mandatory, optional, and
109 * not allowed for each Q.2931 message type
111 static u_char uni_calp_ie_tbl[] = {
112 IE_NA, /* ATM AAL Parameters */
113 IE_NA, /* ATM User Cell Rate */
114 IE_NA, /* Broadband Bearer Capability */
115 IE_NA, /* Broadband High Layer Information */
116 IE_NA, /* Broadband Low Layer Information */
117 IE_NA, /* Call State */
118 IE_NA, /* Called Party Number */
119 IE_NA, /* Called Party Subaddress */
120 IE_NA, /* Calling Party Number */
121 IE_NA, /* Calling Party Subaddress */
123 IE_OPT, /* Connection Identifier */
124 IE_NA, /* Quality of Service Parameters */
125 IE_NA, /* Broadband Repeat Indicator */
126 IE_NA, /* Restart Indicator */
127 IE_NA, /* Broadband Locking Shift */
128 IE_NA, /* Broadband Non-locking Shift */
129 IE_NA, /* Broadband Sending Complete */
130 IE_NA, /* Transit Net */
131 IE_OPT, /* Endpoint Reference */
132 IE_NA /* Endpoint State */
135 static u_char uni_conn_ie_tbl[] = {
136 IE_OPT, /* ATM AAL Parameters */
137 IE_NA, /* ATM User Cell Rate */
138 IE_NA, /* Broadband Bearer Capability */
139 IE_NA, /* Broadband High Layer Information */
140 IE_OPT, /* Broadband Low Layer Information */
141 IE_NA, /* Call State */
142 IE_NA, /* Called Party Number */
143 IE_NA, /* Called Party Subaddress */
144 IE_NA, /* Calling Party Number */
145 IE_NA, /* Calling Party Subaddress */
147 IE_OPT, /* Connection Identifier */
148 IE_NA, /* Quality of Service Parameters */
149 IE_NA, /* Broadband Repeat Indicator */
150 IE_NA, /* Restart Indicator */
151 IE_NA, /* Broadband Locking Shift */
152 IE_NA, /* Broadband Non-locking Shift */
153 IE_NA, /* Broadband Sending Complete */
154 IE_NA, /* Transit Net */
155 IE_OPT, /* Endpoint Reference */
156 IE_NA /* Endpoint State */
159 static u_char uni_cack_ie_tbl[] = {
160 IE_NA, /* ATM AAL Parameters */
161 IE_NA, /* ATM User Cell Rate */
162 IE_NA, /* Broadband Bearer Capability */
163 IE_NA, /* Broadband High Layer Information */
164 IE_NA, /* Broadband Low Layer Information */
165 IE_NA, /* Call State */
166 IE_NA, /* Called Party Number */
167 IE_NA, /* Called Party Subaddress */
168 IE_NA, /* Calling Party Number */
169 IE_NA, /* Calling Party Subaddress */
171 IE_NA, /* Connection Identifier */
172 IE_NA, /* Quality of Service Parameters */
173 IE_NA, /* Broadband Repeat Indicator */
174 IE_NA, /* Restart Indicator */
175 IE_NA, /* Broadband Locking Shift */
176 IE_NA, /* Broadband Non-locking Shift */
177 IE_NA, /* Broadband Sending Complete */
178 IE_NA, /* Transit Net */
179 IE_NA, /* Endpoint Reference */
180 IE_NA /* Endpoint State */
183 static u_char uni_setu_ie_tbl[] = {
184 IE_MAND, /* ATM AAL Parameters (not required by
186 IE_MAND, /* ATM User Cell Rate */
187 IE_MAND, /* Broadband Bearer Capability */
188 IE_OPT, /* Broadband High Layer Information */
189 IE_MAND, /* Broadband Low Layer Information (not required by UNI 3.0 */
190 IE_NA, /* Call State */
191 IE_MAND, /* Called Party Number */
192 IE_OPT, /* Called Party Subaddress */
193 IE_OPT, /* Calling Party Number */
194 IE_OPT, /* Calling Party Subaddress */
196 IE_MAND, /* Connection Identifier */
197 IE_MAND, /* Quality of Service Parameters */
198 IE_OPT, /* Broadband Repeat Indicator */
199 IE_NA, /* Restart Indicator */
200 IE_NA, /* Broadband Locking Shift */
201 IE_NA, /* Broadband Non-locking Shift */
202 IE_OPT, /* Broadband Sending Complete */
203 IE_NA, /* Transit Net */
204 IE_OPT, /* Endpoint Reference */
205 IE_NA /* Endpoint State */
208 static u_char uni_rlse_ie_tbl[] = {
209 IE_NA, /* ATM AAL Parameters */
210 IE_NA, /* ATM User Cell Rate */
211 IE_NA, /* Broadband Bearer Capability */
212 IE_NA, /* Broadband High Layer Information */
213 IE_NA, /* Broadband Low Layer Information */
214 IE_NA, /* Call State */
215 IE_NA, /* Called Party Number */
216 IE_NA, /* Called Party Subaddress */
217 IE_NA, /* Calling Party Number */
218 IE_NA, /* Calling Party Subaddress */
220 IE_NA, /* Connection Identifier */
221 IE_NA, /* Quality of Service Parameters */
222 IE_NA, /* Broadband Repeat Indicator */
223 IE_NA, /* Restart Indicator */
224 IE_NA, /* Broadband Locking Shift */
225 IE_NA, /* Broadband Non-locking Shift */
226 IE_NA, /* Broadband Sending Complete */
227 IE_NA, /* Transit Net */
228 IE_NA, /* Endpoint Reference */
229 IE_NA /* Endpoint State */
232 static u_char uni_rlsc_ie_tbl[] = {
233 IE_NA, /* ATM AAL Parameters */
234 IE_NA, /* ATM User Cell Rate */
235 IE_NA, /* Broadband Bearer Capability */
236 IE_NA, /* Broadband High Layer Information */
237 IE_NA, /* Broadband Low Layer Information */
238 IE_NA, /* Call State */
239 IE_NA, /* Called Party Number */
240 IE_NA, /* Called Party Subaddress */
241 IE_NA, /* Calling Party Number */
242 IE_NA, /* Calling Party Subaddress */
244 IE_NA, /* Connection Identifier */
245 IE_NA, /* Quality of Service Parameters */
246 IE_NA, /* Broadband Repeat Indicator */
247 IE_NA, /* Restart Indicator */
248 IE_NA, /* Broadband Locking Shift */
249 IE_NA, /* Broadband Non-locking Shift */
250 IE_NA, /* Broadband Sending Complete */
251 IE_NA, /* Transit Net */
252 IE_NA, /* Endpoint Reference */
253 IE_NA /* Endpoint State */
256 static u_char uni_rstr_ie_tbl[] = {
257 IE_NA, /* ATM AAL Parameters */
258 IE_NA, /* ATM User Cell Rate */
259 IE_NA, /* Broadband Bearer Capability */
260 IE_NA, /* Broadband High Layer Information */
261 IE_NA, /* Broadband Low Layer Information */
262 IE_NA, /* Call State */
263 IE_NA, /* Called Party Number */
264 IE_NA, /* Called Party Subaddress */
265 IE_NA, /* Calling Party Number */
266 IE_NA, /* Calling Party Subaddress */
268 IE_OPT, /* Connection Identifier */
269 IE_NA, /* Quality of Service Parameters */
270 IE_NA, /* Broadband Repeat Indicator */
271 IE_MAND, /* Restart Indicator */
272 IE_NA, /* Broadband Locking Shift */
273 IE_NA, /* Broadband Non-locking Shift */
274 IE_NA, /* Broadband Sending Complete */
275 IE_NA, /* Transit Net */
276 IE_NA, /* Endpoint Reference */
277 IE_NA /* Endpoint State */
280 static u_char uni_rsta_ie_tbl[] = {
281 IE_NA, /* ATM AAL Parameters */
282 IE_NA, /* ATM User Cell Rate */
283 IE_NA, /* Broadband Bearer Capability */
284 IE_NA, /* Broadband High Layer Information */
285 IE_NA, /* Broadband Low Layer Information */
286 IE_NA, /* Call State */
287 IE_NA, /* Called Party Number */
288 IE_NA, /* Called Party Subaddress */
289 IE_NA, /* Calling Party Number */
290 IE_NA, /* Calling Party Subaddress */
292 IE_OPT, /* Connection Identifier */
293 IE_NA, /* Quality of Service Parameters */
294 IE_NA, /* Broadband Repeat Indicator */
295 IE_MAND, /* Restart Indicator */
296 IE_NA, /* Broadband Locking Shift */
297 IE_NA, /* Broadband Non-locking Shift */
298 IE_NA, /* Broadband Sending Complete */
299 IE_NA, /* Transit Net */
300 IE_NA, /* Endpoint Reference */
301 IE_NA /* Endpoint State */
304 static u_char uni_stat_ie_tbl[] = {
305 IE_NA, /* ATM AAL Parameters */
306 IE_NA, /* ATM User Cell Rate */
307 IE_NA, /* Broadband Bearer Capability */
308 IE_NA, /* Broadband High Layer Information */
309 IE_NA, /* Broadband Low Layer Information */
310 IE_MAND, /* Call State */
311 IE_NA, /* Called Party Number */
312 IE_NA, /* Called Party Subaddress */
313 IE_NA, /* Calling Party Number */
314 IE_NA, /* Calling Party Subaddress */
316 IE_NA, /* Connection Identifier */
317 IE_NA, /* Quality of Service Parameters */
318 IE_NA, /* Broadband Repeat Indicator */
319 IE_NA, /* Restart Indicator */
320 IE_NA, /* Broadband Locking Shift */
321 IE_NA, /* Broadband Non-locking Shift */
322 IE_NA, /* Broadband Sending Complete */
323 IE_NA, /* Transit Net */
324 IE_OPT, /* Endpoint Reference */
325 IE_OPT /* Endpoint State */
328 static u_char uni_senq_ie_tbl[] = {
329 IE_NA, /* ATM AAL Parameters */
330 IE_NA, /* ATM User Cell Rate */
331 IE_NA, /* Broadband Bearer Capability */
332 IE_NA, /* Broadband High Layer Information */
333 IE_NA, /* Broadband Low Layer Information */
334 IE_NA, /* Call State */
335 IE_NA, /* Called Party Number */
336 IE_NA, /* Called Party Subaddress */
337 IE_NA, /* Calling Party Number */
338 IE_NA, /* Calling Party Subaddress */
340 IE_NA, /* Connection Identifier */
341 IE_NA, /* Quality of Service Parameters */
342 IE_NA, /* Broadband Repeat Indicator */
343 IE_NA, /* Restart Indicator */
344 IE_NA, /* Broadband Locking Shift */
345 IE_NA, /* Broadband Non-locking Shift */
346 IE_NA, /* Broadband Sending Complete */
347 IE_NA, /* Transit Net */
348 IE_OPT, /* Endpoint Reference */
349 IE_NA /* Endpoint State */
352 static u_char uni_addp_ie_tbl[] = {
353 IE_OPT, /* ATM AAL Parameters */
354 IE_NA, /* ATM User Cell Rate */
355 IE_NA, /* Broadband Bearer Capability */
356 IE_OPT, /* Broadband High Layer Information */
357 IE_OPT, /* Broadband Low Layer Information */
358 IE_NA, /* Call State */
359 IE_MAND, /* Called Party Number */
360 IE_OPT, /* Called Party Subaddress */
361 IE_OPT, /* Calling Party Number */
362 IE_OPT, /* Calling Party Subaddress */
364 IE_NA, /* Connection Identifier */
365 IE_NA, /* Quality of Service Parameters */
366 IE_NA, /* Broadband Repeat Indicator */
367 IE_NA, /* Restart Indicator */
368 IE_NA, /* Broadband Locking Shift */
369 IE_NA, /* Broadband Non-locking Shift */
370 IE_OPT, /* Broadband Sending Complete */
371 IE_NA, /* Transit Net */
372 IE_MAND, /* Endpoint Reference */
373 IE_NA /* Endpoint State */
376 static u_char uni_adpa_ie_tbl[] = {
377 IE_NA, /* ATM AAL Parameters */
378 IE_NA, /* ATM User Cell Rate */
379 IE_NA, /* Broadband Bearer Capability */
380 IE_NA, /* Broadband High Layer Information */
381 IE_NA, /* Broadband Low Layer Information */
382 IE_NA, /* Call State */
383 IE_NA, /* Called Party Number */
384 IE_NA, /* Called Party Subaddress */
385 IE_NA, /* Calling Party Number */
386 IE_NA, /* Calling Party Subaddress */
388 IE_NA, /* Connection Identifier */
389 IE_NA, /* Quality of Service Parameters */
390 IE_NA, /* Broadband Repeat Indicator */
391 IE_NA, /* Restart Indicator */
392 IE_NA, /* Broadband Locking Shift */
393 IE_NA, /* Broadband Non-locking Shift */
394 IE_NA, /* Broadband Sending Complete */
395 IE_NA, /* Transit Net */
396 IE_MAND, /* Endpoint Reference */
397 IE_NA /* Endpoint State */
400 static u_char uni_adpr_ie_tbl[] = {
401 IE_NA, /* ATM AAL Parameters */
402 IE_NA, /* ATM User Cell Rate */
403 IE_NA, /* Broadband Bearer Capability */
404 IE_NA, /* Broadband High Layer Information */
405 IE_NA, /* Broadband Low Layer Information */
406 IE_NA, /* Call State */
407 IE_NA, /* Called Party Number */
408 IE_NA, /* Called Party Subaddress */
409 IE_NA, /* Calling Party Number */
410 IE_NA, /* Calling Party Subaddress */
412 IE_NA, /* Connection Identifier */
413 IE_NA, /* Quality of Service Parameters */
414 IE_NA, /* Broadband Repeat Indicator */
415 IE_NA, /* Restart Indicator */
416 IE_NA, /* Broadband Locking Shift */
417 IE_NA, /* Broadband Non-locking Shift */
418 IE_NA, /* Broadband Sending Complete */
419 IE_NA, /* Transit Net */
420 IE_MAND, /* Endpoint Reference */
421 IE_NA /* Endpoint State */
424 static u_char uni_drpp_ie_tbl[] = {
425 IE_NA, /* ATM AAL Parameters */
426 IE_NA, /* ATM User Cell Rate */
427 IE_NA, /* Broadband Bearer Capability */
428 IE_NA, /* Broadband High Layer Information */
429 IE_NA, /* Broadband Low Layer Information */
430 IE_NA, /* Call State */
431 IE_NA, /* Called Party Number */
432 IE_NA, /* Called Party Subaddress */
433 IE_NA, /* Calling Party Number */
434 IE_NA, /* Calling Party Subaddress */
436 IE_NA, /* Connection Identifier */
437 IE_NA, /* Quality of Service Parameters */
438 IE_NA, /* Broadband Repeat Indicator */
439 IE_NA, /* Restart Indicator */
440 IE_NA, /* Broadband Locking Shift */
441 IE_NA, /* Broadband Non-locking Shift */
442 IE_NA, /* Broadband Sending Complete */
443 IE_NA, /* Transit Net */
444 IE_MAND, /* Endpoint Reference */
445 IE_NA /* Endpoint State */
448 static u_char uni_drpa_ie_tbl[] = {
449 IE_NA, /* ATM AAL Parameters */
450 IE_NA, /* ATM User Cell Rate */
451 IE_NA, /* Broadband Bearer Capability */
452 IE_NA, /* Broadband High Layer Information */
453 IE_NA, /* Broadband Low Layer Information */
454 IE_NA, /* Call State */
455 IE_NA, /* Called Party Number */
456 IE_NA, /* Called Party Subaddress */
457 IE_NA, /* Calling Party Number */
458 IE_NA, /* Calling Party Subaddress */
460 IE_NA, /* Connection Identifier */
461 IE_NA, /* Quality of Service Parameters */
462 IE_NA, /* Broadband Repeat Indicator */
463 IE_NA, /* Restart Indicator */
464 IE_NA, /* Broadband Locking Shift */
465 IE_NA, /* Broadband Non-locking Shift */
466 IE_NA, /* Broadband Sending Complete */
467 IE_NA, /* Transit Net */
468 IE_MAND, /* Endpoint Reference */
469 IE_NA /* Endpoint State */
473 * Table of Q.2931 message types
478 } uni_msg_types[] = {
479 { UNI_MSG_CALP, uni_calp_ie_tbl },
480 { UNI_MSG_CONN, uni_conn_ie_tbl },
481 { UNI_MSG_CACK, uni_cack_ie_tbl },
482 { UNI_MSG_SETU, uni_setu_ie_tbl },
483 { UNI_MSG_RLSE, uni_rlse_ie_tbl },
484 { UNI_MSG_RLSC, uni_rlsc_ie_tbl },
485 { UNI_MSG_RSTR, uni_rstr_ie_tbl },
486 { UNI_MSG_RSTA, uni_rsta_ie_tbl },
487 { UNI_MSG_STAT, uni_stat_ie_tbl },
488 { UNI_MSG_SENQ, uni_senq_ie_tbl },
489 { UNI_MSG_ADDP, uni_addp_ie_tbl },
490 { UNI_MSG_ADPA, uni_adpa_ie_tbl },
491 { UNI_MSG_ADPR, uni_adpr_ie_tbl },
492 { UNI_MSG_DRPP, uni_drpp_ie_tbl },
493 { UNI_MSG_DRPA, uni_drpa_ie_tbl },
498 * Table of information elements
500 static struct ie_ent ie_table[] = {
501 { UNI_IE_AALP, 5, 16, UNI_MSG_IE_AALP, usf_dec_ie_aalp },
502 { UNI_IE_CLRT, 0, 26, UNI_MSG_IE_CLRT, usf_dec_ie_clrt },
503 { UNI_IE_BBCP, 2, 3, UNI_MSG_IE_BBCP, usf_dec_ie_bbcp },
504 { UNI_IE_BHLI, 1, 9, UNI_MSG_IE_BHLI, usf_dec_ie_bhli },
505 { UNI_IE_BLLI, 0, 13, UNI_MSG_IE_BLLI, usf_dec_ie_blli },
506 { UNI_IE_CLST, 1, 1, UNI_MSG_IE_CLST, usf_dec_ie_clst },
507 { UNI_IE_CDAD, 1, 21, UNI_MSG_IE_CDAD, usf_dec_ie_cdad },
508 { UNI_IE_CDSA, 1, 21, UNI_MSG_IE_CDSA, usf_dec_ie_cdsa },
509 { UNI_IE_CGAD, 1, 22, UNI_MSG_IE_CGAD, usf_dec_ie_cgad },
510 { UNI_IE_CGSA, 1, 21, UNI_MSG_IE_CGSA, usf_dec_ie_cgsa },
511 { UNI_IE_CAUS, 2, 30, UNI_MSG_IE_CAUS, usf_dec_ie_caus },
512 { UNI_IE_CNID, 5, 5, UNI_MSG_IE_CNID, usf_dec_ie_cnid },
513 { UNI_IE_QOSP, 2, 2, UNI_MSG_IE_QOSP, usf_dec_ie_qosp },
514 { UNI_IE_BRPI, 1, 1, UNI_MSG_IE_BRPI, usf_dec_ie_brpi },
515 { UNI_IE_RSTI, 1, 1, UNI_MSG_IE_RSTI, usf_dec_ie_rsti },
516 { UNI_IE_BLSH, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
517 { UNI_IE_BNSH, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
518 { UNI_IE_BSDC, 1, 1, UNI_MSG_IE_BSDC, usf_dec_ie_bsdc },
519 { UNI_IE_TRNT, 1, 5, UNI_MSG_IE_TRNT, usf_dec_ie_trnt },
520 { UNI_IE_EPRF, 3, 3, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
521 { UNI_IE_EPST, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
526 * Decoding table for AAL 1
528 struct ie_decode_tbl ie_aal1_tbl[] = {
529 { 133, 1, IE_OFF_SIZE(ie_aalp_1_subtype) },
530 { 134, 1, IE_OFF_SIZE(ie_aalp_1_cbr_rate) },
531 { 135, 2, IE_OFF_SIZE(ie_aalp_1_multiplier) },
532 { 136, 1, IE_OFF_SIZE(ie_aalp_1_clock_recovery) },
533 { 137, 1, IE_OFF_SIZE(ie_aalp_1_error_correction) },
534 { 138, 1, IE_OFF_SIZE(ie_aalp_1_struct_data_tran) },
535 { 139, 1, IE_OFF_SIZE(ie_aalp_1_partial_cells) },
540 * Decoding table for AAL 3/4
542 struct ie_decode_tbl ie_aal4_tbl_30[] = {
543 { 140, 2, IE_OFF_SIZE(ie_aalp_4_fwd_max_sdu) },
544 { 129, 2, IE_OFF_SIZE(ie_aalp_4_bkwd_max_sdu) },
545 { 130, 2, IE_OFF_SIZE(ie_aalp_4_mid_range) },
546 { 131, 1, IE_OFF_SIZE(ie_aalp_4_mode) },
547 { 132, 1, IE_OFF_SIZE(ie_aalp_4_sscs_type) },
550 struct ie_decode_tbl ie_aal4_tbl_31[] = {
551 { 140, 2, IE_OFF_SIZE(ie_aalp_4_fwd_max_sdu) },
552 { 129, 2, IE_OFF_SIZE(ie_aalp_4_bkwd_max_sdu) },
553 { 130, 4, IE_OFF_SIZE(ie_aalp_4_mid_range) },
554 { 132, 1, IE_OFF_SIZE(ie_aalp_4_sscs_type) },
559 * Decoding table for AAL 5
561 struct ie_decode_tbl ie_aal5_tbl_30[] = {
562 { 140, 2, IE_OFF_SIZE(ie_aalp_5_fwd_max_sdu) },
563 { 129, 2, IE_OFF_SIZE(ie_aalp_5_bkwd_max_sdu) },
564 { 131, 1, IE_OFF_SIZE(ie_aalp_5_mode) },
565 { 132, 1, IE_OFF_SIZE(ie_aalp_5_sscs_type) },
568 struct ie_decode_tbl ie_aal5_tbl_31[] = {
569 { 140, 2, IE_OFF_SIZE(ie_aalp_5_fwd_max_sdu) },
570 { 129, 2, IE_OFF_SIZE(ie_aalp_5_bkwd_max_sdu) },
571 { 132, 1, IE_OFF_SIZE(ie_aalp_5_sscs_type) },
576 * Decoding table for ATM user cell rate
578 struct ie_decode_tbl ie_clrt_tbl[] = {
579 {UNI_IE_CLRT_FWD_PEAK_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_peak)},
580 {UNI_IE_CLRT_BKWD_PEAK_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_peak)},
581 {UNI_IE_CLRT_FWD_PEAK_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_peak_01)},
582 {UNI_IE_CLRT_BKWD_PEAK_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_peak_01)},
583 {UNI_IE_CLRT_FWD_SUST_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_sust)},
584 {UNI_IE_CLRT_BKWD_SUST_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_sust)},
585 {UNI_IE_CLRT_FWD_SUST_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_sust_01)},
586 {UNI_IE_CLRT_BKWD_SUST_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_sust_01)},
587 {UNI_IE_CLRT_FWD_BURST_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_burst)},
588 {UNI_IE_CLRT_BKWD_BURST_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_burst)},
589 {UNI_IE_CLRT_FWD_BURST_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_burst_01)},
590 {UNI_IE_CLRT_BKWD_BURST_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_burst_01)},
591 {UNI_IE_CLRT_BEST_EFFORT_ID, 0, IE_OFF_SIZE(ie_clrt_best_effort)},
592 {UNI_IE_CLRT_TM_OPTIONS_ID, 1, IE_OFF_SIZE(ie_clrt_tm_options)},
597 * IEs initialized to empty values
599 struct ie_aalp ie_aalp_absent = {
603 struct ie_clrt ie_clrt_absent = {
620 struct ie_bbcp ie_bbcp_absent = {
628 struct ie_bhli ie_bhli_absent = {
630 { 0, 0, 0, 0, 0, 0, 0, 0 }
633 struct ie_blli ie_blli_absent = {
651 struct ie_clst ie_clst_absent = {
655 struct ie_cdad ie_cdad_absent = {
661 struct ie_cdsa ie_cdsa_absent = {
665 struct ie_cgad ie_cgad_absent = {
673 struct ie_cgsa ie_cgsa_absent = {
677 struct ie_caus ie_caus_absent = {
683 struct ie_cnid ie_cnid_absent = {
690 struct ie_qosp ie_qosp_absent = {
695 struct ie_brpi ie_brpi_absent = {
699 struct ie_rsti ie_rsti_absent = {
703 struct ie_blsh ie_blsh_absent = {
707 struct ie_bnsh ie_bnsh_absent = {
711 struct ie_bsdc ie_bsdc_absent = {
715 struct ie_trnt ie_trnt_absent = {
721 struct ie_eprf ie_eprf_absent = {
726 struct ie_epst ie_epst_absent = {
732 * Decode a UNI signalling message
735 * usf pointer to a unisig formatting structure
736 * msg pointer to a signalling message structure
740 * errno error encountered
744 usf_dec_msg(usf, msg)
746 struct unisig_msg *msg;
751 struct ie_generic *ie;
753 ATM_DEBUG2("usf_dec_msg: usf=%p, msg=%p\n", usf, msg);
756 * Check the total message length
758 if (usf_count(usf) < UNI_MSG_MIN_LEN) {
763 * Get and check the protocol discriminator
765 rc = usf_byte(usf, &c);
768 if (c != UNI_MSG_DISC_Q93B)
772 * Get and check the call reference length
774 rc = usf_byte(usf, &c);
781 * Get the call reference
783 rc = usf_int3(usf, &msg->msg_call_ref);
788 * Get the message type
790 rc = usf_byte(usf, &msg->msg_type);
795 * Get the message type extension
797 rc = usf_byte(usf, &c);
800 msg->msg_type_flag = (c >> UNI_MSG_TYPE_FLAG_SHIFT) &
801 UNI_MSG_TYPE_FLAG_MASK;
802 msg->msg_type_action = c & UNI_MSG_TYPE_ACT_MASK;
805 * Get the message length and make sure we actually have
806 * enough data for the whole message
808 rc = usf_short(usf, &s);
812 if (usf_count(usf) != msg->msg_length) {
817 * Process information elements
819 len = msg->msg_length;
822 rc = usf_dec_ie(usf, msg, ie);
827 len -= (ie->ie_length + UNI_IE_HDR_LEN);
831 * Make sure that mandatory IEs are included and
832 * unwanted ones aren't
834 for (i=0; msg->msg_type!=uni_msg_types[i].msg_type &&
835 uni_msg_types[i].msg_type!=0; i++) {
837 if (!uni_msg_types[i].msg_ie_tbl)
841 * If the message type is in the table, check the IEs.
842 * If it isn't, the receive routine will catch the error.
844 ie_tbl = uni_msg_types[i].msg_ie_tbl;
845 for (i=0; i<UNI_MSG_IE_CNT-1; i++) {
848 if (!msg->msg_ie_vec[i]) {
850 * Mandatory IE missing
853 ie->ie_ident = unisig_ie_ident_vec[i];
854 ie->ie_err_cause = UNI_IE_CAUS_MISSING;
855 MSG_IE_ADD(msg, ie, UNI_MSG_IE_ERR);
859 if (msg->msg_ie_vec[i]) {
861 * Disallowed IE present
863 ie = msg->msg_ie_vec[i];
865 (struct ie_generic *) 0;
866 MSG_IE_ADD(msg, ie, UNI_MSG_IE_ERR);
885 * Decode an information element
887 * This routine will be called repeatedly as long as there are
888 * information elements left to be decoded. It will decode the
889 * first part of the IE, look its type up in a table, and call
890 * the appropriate routine to decode the rest. After an IE is
891 * successfully decoded, it is linked into the UNI signalling
892 * message structure. If an error is discovered, the IE is linked
893 * into the IE error chain and an error cause is set in the header.
896 * usf pointer to a UNISIG formatting structure
897 * msg pointer to a UNISIG message structure
898 * ie pointer to a generic IE structure
902 * errno error encountered
906 usf_dec_ie(usf, msg, ie)
908 struct unisig_msg *msg;
909 struct ie_generic *ie;
914 * Decode the IE header (identifier, instruction field,
917 rc = usf_dec_ie_hdr(usf, ie);
921 * Ignore the IE if it is of zero length.
923 if (!ie->ie_length) {
929 * Look up the information element in the table
931 for (i=0; (ie->ie_ident != ie_table[i].ident) &&
932 (ie_table[i].decode != NULL); i++) {
934 if (ie_table[i].decode == NULL) {
938 ie_index = UNI_MSG_IE_ERR;
940 ie_index = ie_table[i].p_idx;
944 * Check for unimplemented or unrecognized IEs
946 if (ie_index == UNI_MSG_IE_ERR) {
947 ie->ie_err_cause = UNI_IE_CAUS_IEEXIST;
950 * Skip over the invalid IE
952 rc = usf_dec_ie_uimp(usf, ie);
959 * Check the length against the IE table
961 if (ie->ie_length < ie_table[i].min_len ||
962 ie->ie_length > ie_table[i].max_len) {
963 ie_index = UNI_MSG_IE_ERR;
964 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
967 * Skip over the invalid IE
969 rc = usf_dec_ie_uimp(usf, ie);
976 * Process the IE by calling the function indicated
979 rc = ie_table[i].decode(usf, ie);
984 * Link the IE into the signalling message
987 if (ie->ie_err_cause) {
988 ie_index = UNI_MSG_IE_ERR;
990 MSG_IE_ADD(msg, ie, ie_index);
997 * Decode an information element header
1000 * usf pointer to a UNISIG formatting structure
1001 * ie pointer to a generic IE structure
1005 * errno error encountered
1009 usf_dec_ie_hdr(usf, ie)
1011 struct ie_generic *ie;
1018 * Get the IE identifier
1020 rc = usf_byte(usf, &ie->ie_ident);
1025 * Get the extended type
1027 rc = usf_byte(usf, &c);
1030 ie->ie_coding = (c >> UNI_IE_CODE_SHIFT) & UNI_IE_CODE_MASK;
1031 ie->ie_flag = (c >> UNI_IE_FLAG_SHIFT) & UNI_IE_FLAG_MASK;
1032 ie->ie_action = c & UNI_IE_ACT_MASK;
1037 rc = usf_short(usf, &s);
1047 * Decode an AAL parameters information element
1050 * usf pointer to a unisig formatting structure
1051 * ie pointer to an AAL parms IE structure
1055 * errno error encountered
1059 usf_dec_ie_aalp(usf, ie)
1061 struct ie_generic *ie;
1068 KM_COPY(&ie_aalp_absent, &ie->ie_u.ie_aalp,
1069 sizeof(ie_aalp_absent));
1074 rc = usf_byte(usf, &ie->ie_aalp_aal_type);
1079 * Subtract the length of the AAL type from the total.
1080 * It will be readjusted after usf_dec_ie_ident is finished.
1085 * Process based on AAL type
1087 switch (ie->ie_aalp_aal_type) {
1088 case UNI_IE_AALP_AT_AAL1:
1090 * Clear the AAL 1 subparameters
1092 ie->ie_aalp_1_subtype = T_ATM_ABSENT;
1093 ie->ie_aalp_1_cbr_rate = T_ATM_ABSENT;
1094 ie->ie_aalp_1_multiplier = T_ATM_ABSENT;
1095 ie->ie_aalp_1_clock_recovery = T_ATM_ABSENT;
1096 ie->ie_aalp_1_error_correction = T_ATM_ABSENT;
1097 ie->ie_aalp_1_struct_data_tran = T_ATM_ABSENT;
1098 ie->ie_aalp_1_partial_cells = T_ATM_ABSENT;
1101 * Parse the AAL fields based on their IDs
1103 rc = usf_dec_ie_ident(usf, ie, ie_aal1_tbl);
1105 case UNI_IE_AALP_AT_AAL3:
1107 * Clear the AAL 3/4 subparameters
1109 ie->ie_aalp_4_fwd_max_sdu = T_ATM_ABSENT;
1110 ie->ie_aalp_4_bkwd_max_sdu = T_ATM_ABSENT;
1111 ie->ie_aalp_4_mid_range = T_ATM_ABSENT;
1112 ie->ie_aalp_4_mode = T_ATM_ABSENT;
1113 ie->ie_aalp_4_sscs_type = T_ATM_ABSENT;
1116 * Parse the AAL fields based on their IDs
1118 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
1119 rc = usf_dec_ie_ident(usf, ie, ie_aal4_tbl_30);
1121 rc = usf_dec_ie_ident(usf, ie, ie_aal4_tbl_31);
1124 * If either forward or backward maximum SDU
1125 * size is specified, the other must also be
1128 if ((ie->ie_aalp_4_fwd_max_sdu != T_ATM_ABSENT &&
1129 ie->ie_aalp_4_bkwd_max_sdu == T_ATM_ABSENT) ||
1130 (ie->ie_aalp_4_fwd_max_sdu == T_ATM_ABSENT &&
1131 ie->ie_aalp_4_bkwd_max_sdu != T_ATM_ABSENT)) {
1132 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1135 case UNI_IE_AALP_AT_AAL5:
1137 * Clear the AAL 5 subparameters
1139 ie->ie_aalp_5_fwd_max_sdu = T_ATM_ABSENT;
1140 ie->ie_aalp_5_bkwd_max_sdu = T_ATM_ABSENT;
1141 ie->ie_aalp_5_mode = T_ATM_ABSENT;
1142 ie->ie_aalp_5_sscs_type = T_ATM_ABSENT;
1145 * Parse the AAL fields based on their IDs
1147 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
1148 rc = usf_dec_ie_ident(usf, ie, ie_aal5_tbl_30);
1150 rc = usf_dec_ie_ident(usf, ie, ie_aal5_tbl_31);
1153 * If either forward or backward maximum SDU
1154 * size is specified, the other must also be
1157 if ((ie->ie_aalp_5_fwd_max_sdu != T_ATM_ABSENT &&
1158 ie->ie_aalp_5_bkwd_max_sdu == T_ATM_ABSENT) ||
1159 (ie->ie_aalp_5_fwd_max_sdu == T_ATM_ABSENT &&
1160 ie->ie_aalp_5_bkwd_max_sdu != T_ATM_ABSENT)) {
1161 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1164 case UNI_IE_AALP_AT_AALU:
1166 * Check user parameter length
1169 sizeof(ie->ie_aalp_user_info) +
1171 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1178 while (i < ie->ie_length - 2) {
1179 rc = usf_byte(usf, &ie->ie_aalp_user_info[i]);
1186 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1195 * Decode a user cell rate information element
1198 * usf pointer to a unisig formatting structure
1199 * ie pointer to a cell rate IE structure
1203 * errno error encountered
1207 usf_dec_ie_clrt(usf, ie)
1209 struct ie_generic *ie;
1216 KM_COPY(&ie_clrt_absent, &ie->ie_u.ie_clrt,
1217 sizeof(ie_clrt_absent));
1220 * Parse the IE using field identifiers
1222 rc = usf_dec_ie_ident(usf, ie, ie_clrt_tbl);
1228 * Decode a broadband bearer capability information element
1231 * usf pointer to a unisig formatting structure
1232 * ie pointer to a cell rate IE structure
1236 * errno error encountered
1240 usf_dec_ie_bbcp(usf, ie)
1242 struct ie_generic *ie;
1250 KM_COPY(&ie_bbcp_absent, &ie->ie_u.ie_bbcp,
1251 sizeof(ie_bbcp_absent));
1254 * Get the broadband bearer class
1256 rc = usf_byte(usf, &c);
1259 ie->ie_bbcp_bearer_class = c & UNI_IE_BBCP_BC_MASK;
1262 * If the broadband bearer class was X, the next
1263 * byte has the traffic type and timing requirements
1265 if (ie->ie_bbcp_bearer_class == UNI_IE_BBCP_BC_BCOB_X &&
1266 !(c & UNI_IE_EXT_BIT)) {
1267 rc = usf_byte(usf, &c);
1270 ie->ie_bbcp_traffic_type = (c >> UNI_IE_BBCP_TT_SHIFT) &
1271 UNI_IE_BBCP_TT_MASK;
1272 ie->ie_bbcp_timing_req = c & UNI_IE_BBCP_TR_MASK;
1276 * Get the clipping and user plane connection configuration
1278 if (c & UNI_IE_EXT_BIT) {
1279 rc = usf_byte(usf, &c);
1282 ie->ie_bbcp_clipping = (c >> UNI_IE_BBCP_SC_SHIFT) &
1283 UNI_IE_BBCP_SC_MASK;
1284 ie->ie_bbcp_conn_config = c & UNI_IE_BBCP_CC_MASK;
1292 * Decode a broadband high layer information element
1295 * usf pointer to a unisig formatting structure
1296 * ie pointer to a cell rate IE structure
1300 * errno error encountered
1304 usf_dec_ie_bhli(usf, ie)
1306 struct ie_generic *ie;
1314 KM_COPY(&ie_bhli_absent, &ie->ie_u.ie_bhli,
1315 sizeof(ie_bhli_absent));
1318 * Get the high layer information type
1320 rc = usf_ext(usf, &i);
1321 ie->ie_bhli_type = i & UNI_IE_EXT_MASK;
1326 * What comes next depends on the type
1328 switch (ie->ie_bhli_type) {
1329 case UNI_IE_BHLI_TYPE_ISO:
1330 case UNI_IE_BHLI_TYPE_USER:
1332 * ISO or user-specified parameters -- take the
1333 * length of information from the IE length
1335 for (i=0; i<ie->ie_length-1; i++) {
1336 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
1341 case UNI_IE_BHLI_TYPE_HLP:
1343 * Make sure the IE is long enough for the high
1344 * layer profile information, then get it
1346 if (usf->usf_sig->us_proto != ATM_SIG_UNI30)
1347 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1348 if (ie->ie_length < UNI_IE_BHLI_HLP_LEN+1)
1349 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1350 for (i=0; i<ie->ie_length &&
1351 i<UNI_IE_BHLI_HLP_LEN; i++) {
1352 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
1357 case UNI_IE_BHLI_TYPE_VSA:
1359 * Make sure the IE is long enough for the vendor-
1360 * specific application information, then get it
1362 if (ie->ie_length < UNI_IE_BHLI_VSA_LEN+1)
1363 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1364 for (i=0; i<ie->ie_length &&
1365 i<UNI_IE_BHLI_VSA_LEN; i++) {
1366 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
1372 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1373 for (i=0; i<ie->ie_length; i++) {
1374 rc = usf_byte(usf, &c);
1385 * Decode a broadband low layer information element
1388 * usf pointer to a unisig formatting structure
1389 * ie pointer to a cell rate IE structure
1393 * errno error encountered
1397 usf_dec_ie_blli(usf, ie)
1399 struct ie_generic *ie;
1408 KM_COPY(&ie_blli_absent, &ie->ie_u.ie_blli,
1409 sizeof(ie_blli_absent));
1412 * Get paramteters for the protocol layers as long as
1413 * there is still information left in the IE
1418 * Get the type and process based on what it is
1420 rc = usf_byte(usf, &id);
1423 switch (((id & UNI_IE_EXT_MASK) >>
1424 UNI_IE_BLLI_LID_SHIFT) &
1425 UNI_IE_BLLI_LID_MASK) {
1426 case UNI_IE_BLLI_L1_ID:
1430 ie->ie_blli_l1_id = id & UNI_IE_BLLI_LP_MASK;
1433 case UNI_IE_BLLI_L2_ID:
1435 * Layer 2 info--contents vary based on type
1437 ie->ie_blli_l2_id = id & UNI_IE_BLLI_LP_MASK;
1439 if (id & UNI_IE_EXT_BIT)
1441 switch (ie->ie_blli_l2_id) {
1442 case UNI_IE_BLLI_L2P_X25L:
1443 case UNI_IE_BLLI_L2P_X25M:
1444 case UNI_IE_BLLI_L2P_HDLC1:
1445 case UNI_IE_BLLI_L2P_HDLC2:
1446 case UNI_IE_BLLI_L2P_HDLC3:
1447 case UNI_IE_BLLI_L2P_Q922:
1448 case UNI_IE_BLLI_L2P_ISO7776:
1449 rc = usf_byte(usf, &c);
1453 ie->ie_blli_l2_mode = (c >>
1454 UNI_IE_BLLI_L2MODE_SHIFT) &
1455 UNI_IE_BLLI_L2MODE_MASK;
1456 if (!(c & UNI_IE_EXT_BIT))
1458 rc = usf_byte(usf, &c);
1462 ie->ie_blli_l2_window =
1463 c & UNI_IE_EXT_MASK;
1465 case UNI_IE_BLLI_L2P_USER:
1466 rc = usf_byte(usf, &c);
1470 ie->ie_blli_l2_user_proto =
1471 c & UNI_IE_EXT_MASK;
1475 case UNI_IE_BLLI_L3_ID:
1477 * Layer 3 info--contents vary based on type
1479 ie->ie_blli_l3_id = id & UNI_IE_BLLI_LP_MASK;
1481 switch (ie->ie_blli_l3_id) {
1482 case UNI_IE_BLLI_L3P_X25:
1483 case UNI_IE_BLLI_L3P_ISO8208:
1484 case UNI_IE_BLLI_L3P_ISO8878:
1485 rc = usf_byte(usf, &c);
1489 ie->ie_blli_l3_mode = (c >>
1490 UNI_IE_BLLI_L3MODE_SHIFT) &
1491 UNI_IE_BLLI_L3MODE_MASK;
1492 if (!(c & UNI_IE_EXT_BIT))
1494 rc = usf_byte(usf, &c);
1498 ie->ie_blli_l3_packet_size =
1499 c & UNI_IE_BLLI_L3PS_MASK;
1500 if (!(c & UNI_IE_EXT_BIT))
1502 rc = usf_byte(usf, &c);
1506 ie->ie_blli_l3_window =
1507 c & UNI_IE_EXT_MASK;
1509 case UNI_IE_BLLI_L3P_USER:
1510 rc = usf_byte(usf, &c);
1514 ie->ie_blli_l3_mode =
1515 c & UNI_IE_EXT_MASK;
1517 case UNI_IE_BLLI_L3P_ISO9577:
1518 rc = usf_ext(usf, &ipi);
1522 ie->ie_blli_l3_ipi = ipi >>
1523 UNI_IE_BLLI_L3IPI_SHIFT;
1524 if (ie->ie_blli_l3_ipi !=
1525 UNI_IE_BLLI_L3IPI_SNAP)
1528 rc = usf_byte(usf, &c);
1529 ie->ie_blli_l3_snap_id = c & UNI_IE_EXT_MASK;
1535 &ie->ie_blli_l3_oui[0]);
1539 &ie->ie_blli_l3_oui[1]);
1543 &ie->ie_blli_l3_oui[2]);
1547 &ie->ie_blli_l3_pid[0]);
1551 &ie->ie_blli_l3_pid[1]);
1559 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1560 for (i=0; i<ie->ie_length; i++) {
1561 rc = usf_byte(usf, &c);
1573 * Decode a call state information element
1576 * usf pointer to a unisig formatting structure
1577 * ie pointer to a cell rate IE structure
1581 * errno error encountered
1585 usf_dec_ie_clst(usf, ie)
1587 struct ie_generic *ie;
1595 KM_COPY(&ie_clst_absent, &ie->ie_u.ie_clst,
1596 sizeof(ie_clst_absent));
1598 rc = usf_byte(usf, &c);
1601 ie->ie_clst_state = c & UNI_IE_CLST_STATE_MASK;
1608 * Decode a called party number information element
1611 * usf pointer to a unisig formatting structure
1612 * ie pointer to a cell rate IE structure
1616 * errno error encountered
1620 usf_dec_ie_cdad(usf, ie)
1622 struct ie_generic *ie;
1630 KM_COPY(&ie_cdad_absent, &ie->ie_u.ie_cdad,
1631 sizeof(ie_cdad_absent));
1634 * Get and check the numbering plan
1636 rc = usf_byte(usf, &c);
1639 ie->ie_cdad_plan = c & UNI_IE_CDAD_PLAN_MASK;
1640 len = ie->ie_length - 1;
1641 switch (ie->ie_cdad_plan) {
1642 case UNI_IE_CDAD_PLAN_E164:
1643 ie->ie_cdad_addr.address_format = T_ATM_E164_ADDR;
1645 case UNI_IE_CDAD_PLAN_NSAP:
1646 ie->ie_cdad_addr.address_format = T_ATM_ENDSYS_ADDR;
1650 * Invalid numbering plan
1652 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1654 rc = usf_byte(usf, &c);
1664 * Get the ATM address
1666 rc = usf_dec_atm_addr(usf, &ie->ie_cdad_addr, len);
1668 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1677 * Decode a called party subaddress information element
1680 * usf pointer to a unisig formatting structure
1681 * ie pointer to a cell rate IE structure
1685 * errno error encountered
1689 usf_dec_ie_cdsa(usf, ie)
1691 struct ie_generic *ie;
1699 KM_COPY(&ie_cdsa_absent, &ie->ie_u.ie_cdsa,
1700 sizeof(ie_cdsa_absent));
1703 * Get and check the subaddress type
1705 rc = usf_byte(usf, &c);
1708 len = ie->ie_length - 1;
1709 if (((c >> UNI_IE_CDSA_TYPE_SHIFT) & UNI_IE_CDSA_TYPE_MASK) !=
1710 UNI_IE_CDSA_TYPE_AESA) {
1712 * Invalid subaddress type
1714 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1716 rc = usf_byte(usf, &c);
1726 * Get the ATM address
1728 ie->ie_cdsa_addr.address_format = T_ATM_ENDSYS_ADDR;
1729 rc = usf_dec_atm_addr(usf, &ie->ie_cdsa_addr, len);
1731 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1740 * Decode a calling party number information element
1743 * usf pointer to a unisig formatting structure
1744 * ie pointer to a cell rate IE structure
1748 * errno error encountered
1752 usf_dec_ie_cgad(usf, ie)
1754 struct ie_generic *ie;
1762 KM_COPY(&ie_cgad_absent, &ie->ie_u.ie_cgad,
1763 sizeof(ie_cgad_absent));
1766 * Get and check the numbering plan
1768 len = ie->ie_length;
1769 rc = usf_byte(usf, &c);
1772 ie->ie_cgad_type = (c >> UNI_IE_CGAD_TYPE_SHIFT) &
1773 UNI_IE_CGAD_TYPE_MASK;
1774 ie->ie_cgad_plan = c & UNI_IE_CGAD_PLAN_MASK;
1776 switch (ie->ie_cgad_plan) {
1777 case UNI_IE_CGAD_PLAN_E164:
1778 ie->ie_cgad_addr.address_format = T_ATM_E164_ADDR;
1780 case UNI_IE_CGAD_PLAN_NSAP:
1781 ie->ie_cgad_addr.address_format = T_ATM_ENDSYS_ADDR;
1784 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1786 rc = usf_byte(usf, &c);
1796 * Get the presentation and screening indicators, if present
1798 if (!(c & UNI_IE_EXT_BIT)) {
1799 rc = usf_byte(usf, &c);
1803 ie->ie_cgad_pres_ind = (c >> UNI_IE_CGAD_PRES_SHIFT) &
1804 UNI_IE_CGAD_PRES_MASK;
1805 ie->ie_cgad_screen_ind = c & UNI_IE_CGAD_SCR_MASK;
1807 ie->ie_cgad_pres_ind = 0;
1808 ie->ie_cgad_screen_ind =0;
1812 * Get the ATM address
1814 rc = usf_dec_atm_addr(usf, &ie->ie_cgad_addr, len);
1816 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1825 * Decode a calling party subaddress information element
1828 * usf pointer to a unisig formatting structure
1829 * ie pointer to a cell rate IE structure
1833 * errno error encountered
1837 usf_dec_ie_cgsa(usf, ie)
1839 struct ie_generic *ie;
1847 KM_COPY(&ie_cgsa_absent, &ie->ie_u.ie_cgsa,
1848 sizeof(ie_cgsa_absent));
1851 * Get and check the subaddress type
1853 rc = usf_byte(usf, &c);
1856 len = ie->ie_length - 1;
1857 if (((c >> UNI_IE_CGSA_TYPE_SHIFT) & UNI_IE_CGSA_TYPE_MASK) !=
1858 UNI_IE_CGSA_TYPE_AESA) {
1860 * Invalid subaddress type
1862 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1864 rc = usf_byte(usf, &c);
1874 * Get the ATM address
1876 ie->ie_cgsa_addr.address_format = T_ATM_ENDSYS_ADDR;
1877 rc = usf_dec_atm_addr(usf, &ie->ie_cgsa_addr, len);
1879 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1888 * Decode a cause information element
1891 * usf pointer to a unisig formatting structure
1892 * ie pointer to a cell rate IE structure
1896 * errno error encountered
1900 usf_dec_ie_caus(usf, ie)
1902 struct ie_generic *ie;
1910 KM_COPY(&ie_caus_absent, &ie->ie_u.ie_caus,
1911 sizeof(ie_caus_absent));
1914 * Get the cause location
1916 rc = usf_byte(usf, &c);
1919 ie->ie_caus_loc = c & UNI_IE_CAUS_LOC_MASK;
1922 * Get the cause value
1924 rc = usf_byte(usf, &c);
1927 ie->ie_caus_cause = c & UNI_IE_EXT_MASK;
1930 * Get any included diagnostics
1932 len = ie->ie_length - 2;
1933 for (i = 0, ie->ie_caus_diag_len = 0;
1934 len && i < sizeof(ie->ie_caus_diagnostic);
1935 len--, i++, ie->ie_caus_diag_len++) {
1936 rc = usf_byte(usf, &ie->ie_caus_diagnostic[i]);
1946 * Decode a conection identifier information element
1949 * usf pointer to a unisig formatting structure
1950 * ie pointer to a cell rate IE structure
1954 * errno error encountered
1958 usf_dec_ie_cnid(usf, ie)
1960 struct ie_generic *ie;
1967 KM_COPY(&ie_cnid_absent, &ie->ie_u.ie_cnid,
1968 sizeof(ie_cnid_absent));
1970 rc = usf_ext(usf, &i);
1973 ie->ie_cnid_vp_sig = (i >> UNI_IE_CNID_VPSIG_SHIFT) &
1974 UNI_IE_CNID_VPSIG_MASK;
1975 ie->ie_cnid_pref_excl = i & UNI_IE_CNID_PREX_MASK;
1977 rc = usf_short(usf, &ie->ie_cnid_vpci);
1980 rc = usf_short(usf, &ie->ie_cnid_vci);
1986 * Decode a quality of service parameters information element
1989 * usf pointer to a unisig formatting structure
1990 * ie pointer to a cell rate IE structure
1994 * errno error encountered
1998 usf_dec_ie_qosp(usf, ie)
2000 struct ie_generic *ie;
2007 KM_COPY(&ie_qosp_absent, &ie->ie_u.ie_qosp,
2008 sizeof(ie_qosp_absent));
2011 * Get forward QoS class
2013 rc = usf_byte(usf, &ie->ie_qosp_fwd_class);
2018 * Get backward QoS class
2020 rc = usf_byte(usf, &ie->ie_qosp_bkwd_class);
2027 * Decode a broadband repeat indicator information element
2030 * usf pointer to a unisig formatting structure
2031 * ie pointer to a cell rate IE structure
2035 * errno error encountered
2039 usf_dec_ie_brpi(usf, ie)
2041 struct ie_generic *ie;
2049 KM_COPY(&ie_brpi_absent, &ie->ie_u.ie_brpi,
2050 sizeof(ie_brpi_absent));
2053 * Get the repeat indicator
2055 rc = usf_byte(usf, &c);
2059 ie->ie_brpi_ind = c & UNI_IE_BRPI_IND_MASK;
2066 * Decode a restart indicator information element
2069 * usf pointer to a unisig formatting structure
2070 * ie pointer to a cell rate IE structure
2074 * errno error encountered
2078 usf_dec_ie_rsti(usf, ie)
2080 struct ie_generic *ie;
2088 KM_COPY(&ie_rsti_absent, &ie->ie_u.ie_rsti,
2089 sizeof(ie_rsti_absent));
2092 * Get the restart class
2094 rc = usf_byte(usf, &c);
2098 ie->ie_rsti_class = c & UNI_IE_RSTI_CLASS_MASK;
2105 * Decode a broadband sending complete information element
2108 * usf pointer to a unisig formatting structure
2109 * ie pointer to a broadband sending complete IE structure
2113 * errno error encountered
2117 usf_dec_ie_bsdc(usf, ie)
2119 struct ie_generic *ie;
2127 KM_COPY(&ie_bsdc_absent, &ie->ie_u.ie_bsdc,
2128 sizeof(ie_bsdc_absent));
2131 * Get the sending complete indicator
2133 rc = usf_byte(usf, &c);
2138 * Validate the indicator
2140 c &= UNI_IE_EXT_MASK;
2141 if (c != UNI_IE_BSDC_IND)
2142 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
2143 ie->ie_bsdc_ind = c;
2150 * Decode a transit network selection information element
2153 * usf pointer to a unisig formatting structure
2154 * ie pointer to a transit network selection IE structure
2158 * errno error encountered
2162 usf_dec_ie_trnt(usf, ie)
2164 struct ie_generic *ie;
2172 KM_COPY(&ie_trnt_absent, &ie->ie_u.ie_trnt,
2173 sizeof(ie_trnt_absent));
2176 * Get the network ID type and plan
2178 rc = usf_byte(usf, &c);
2181 ie->ie_trnt_id_type = (c >> UNI_IE_TRNT_IDT_SHIFT) &
2182 UNI_IE_TRNT_IDT_MASK;
2183 ie->ie_trnt_id_plan = c & UNI_IE_TRNT_IDP_MASK;
2186 * Get the length of the network ID
2188 len = ie->ie_length - 1;
2189 ie->ie_trnt_id_len = MIN(len, sizeof(ie->ie_trnt_id));
2192 * Get the network ID
2194 for (i=0; i<len; i++) {
2195 if (i<sizeof(ie->ie_trnt_id))
2196 rc = usf_byte(usf, &ie->ie_trnt_id[i]);
2198 rc = usf_byte(usf, &c);
2208 * Decode an unimplemented information element
2211 * usf pointer to a unisig formatting structure
2212 * ie pointer to a cell rate IE structure
2216 * errno error encountered
2220 usf_dec_ie_uimp(usf, ie)
2222 struct ie_generic *ie;
2228 * Skip over the IE contents
2230 for (i=0; i<ie->ie_length; i++) {
2231 rc = usf_byte(usf, &c);
2241 * Decode an information element using field identifiers
2243 * The AAL parameters and ATM user cell rate IEs are formatted
2244 * with a one-byte identifier preceeding each field. The routine
2245 * parses these IEs by using a table which relates the field
2246 * identifiers with the fields in the appropriate IE structure.
2247 * Field order in the received message is immaterial.
2250 * usf pointer to a unisig formatting structure
2251 * ie pointer to a cell rate IE structure
2252 * tbl pointer to an IE decoding table
2256 * errno error encountered
2260 usf_dec_ie_ident(usf, ie, tbl)
2262 struct ie_generic *ie;
2263 struct ie_decode_tbl *tbl;
2273 * Scan through the IE
2275 len = ie->ie_length;
2278 * Get the field identifier
2280 rc = usf_byte(usf, &c);
2286 * Look up the field in the table
2288 for (i=0; (tbl[i].ident != c) && tbl[i].len; i++) {
2290 if (tbl[i].ident == 0) {
2292 * Bad subfield identifier -- flag an
2293 * error and skip over the rest of the IE
2295 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
2297 rc = usf_byte(usf, &c);
2305 * Save final destination address
2307 dest = (void *)((int)ie + tbl[i].f_offs);
2310 * Get the field value
2312 switch (tbl[i].len) {
2318 rc = usf_byte(usf, &cv);
2325 switch (tbl[i].f_size) {
2327 *(u_int8_t *)dest = cv;
2330 *(u_int16_t *)dest = cv;
2333 *(u_int32_t *)dest = cv;
2341 rc = usf_short(usf, &sv);
2348 switch (tbl[i].f_size) {
2350 *(u_int16_t *)dest = sv;
2353 *(u_int32_t *)dest = sv;
2361 rc = usf_int3(usf, &iv);
2365 rc = usf_int(usf, &iv);
2372 switch (tbl[i].f_size) {
2374 *(u_int32_t *)dest = iv;
2384 "uni decode: id=%d,len=%d,off=%d,size=%d\n",
2385 tbl[i].ident, tbl[i].len,
2386 tbl[i].f_offs, tbl[i].f_size);
2403 * Decode an ATM address
2406 * usf pointer to a unisig formatting structure
2407 * addr pointer to an ATM address structure
2408 * len length of data remainig in the IE
2412 * errno error encountered
2416 usf_dec_atm_addr(usf, addr, len)
2425 * Check the address type
2427 addr->address_length = len;
2428 switch (addr->address_format) {
2429 case T_ATM_E164_ADDR:
2430 if (len > sizeof(Atm_addr_e164)) {
2433 cp = (u_char *) addr->address;
2435 case T_ATM_ENDSYS_ADDR:
2436 if (len != sizeof(Atm_addr_nsap)) {
2439 cp = (u_char *) addr->address;
2442 /* Silence the compiler */
2447 * Get the ATM address
2450 rc = usf_byte(usf, cp);
2461 rc = usf_byte(usf, &c);