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 $
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>
46 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/unisig_decode.c,v 1.5 2000/01/17 20:49:56 mks Exp $");
49 #define ALLOC_IE(ie) \
50 (ie) = (struct ie_generic *) atm_allocate(&unisig_iepool); \
58 static int usf_dec_ie __P((struct usfmt *, struct unisig_msg *, struct ie_generic *));
59 static int usf_dec_ie_hdr __P((struct usfmt *, struct ie_generic *));
60 static int usf_dec_ie_aalp __P((struct usfmt *, struct ie_generic *));
61 static int usf_dec_ie_clrt __P((struct usfmt *, struct ie_generic *));
62 static int usf_dec_ie_bbcp __P((struct usfmt *, struct ie_generic *));
63 static int usf_dec_ie_bhli __P((struct usfmt *, struct ie_generic *));
64 static int usf_dec_ie_blli __P((struct usfmt *, struct ie_generic *));
65 static int usf_dec_ie_clst __P((struct usfmt *, struct ie_generic *));
66 static int usf_dec_ie_cdad __P((struct usfmt *, struct ie_generic *));
67 static int usf_dec_ie_cdsa __P((struct usfmt *, struct ie_generic *));
68 static int usf_dec_ie_cgad __P((struct usfmt *, struct ie_generic *));
69 static int usf_dec_ie_cgsa __P((struct usfmt *, struct ie_generic *));
70 static int usf_dec_ie_caus __P((struct usfmt *, struct ie_generic *));
71 static int usf_dec_ie_cnid __P((struct usfmt *, struct ie_generic *));
72 static int usf_dec_ie_qosp __P((struct usfmt *, struct ie_generic *));
73 static int usf_dec_ie_brpi __P((struct usfmt *, struct ie_generic *));
74 static int usf_dec_ie_rsti __P((struct usfmt *, struct ie_generic *));
75 static int usf_dec_ie_bsdc __P((struct usfmt *, struct ie_generic *));
76 static int usf_dec_ie_trnt __P((struct usfmt *, struct ie_generic *));
77 static int usf_dec_ie_uimp __P((struct usfmt *, struct ie_generic *));
78 static int usf_dec_ie_ident __P((struct usfmt *, struct ie_generic *,
79 struct ie_decode_tbl *));
80 static int usf_dec_atm_addr __P((struct usfmt *, Atm_addr *, int));
84 * Table associating IE type with IE vector index
86 u_char unisig_ie_ident_vec[] = {
112 * Tables specifying which IEs are mandatory, optional, and
113 * not allowed for each Q.2931 message type
115 static u_char uni_calp_ie_tbl[] = {
116 IE_NA, /* ATM AAL Parameters */
117 IE_NA, /* ATM User Cell Rate */
118 IE_NA, /* Broadband Bearer Capability */
119 IE_NA, /* Broadband High Layer Information */
120 IE_NA, /* Broadband Low Layer Information */
121 IE_NA, /* Call State */
122 IE_NA, /* Called Party Number */
123 IE_NA, /* Called Party Subaddress */
124 IE_NA, /* Calling Party Number */
125 IE_NA, /* Calling Party Subaddress */
127 IE_OPT, /* Connection Identifier */
128 IE_NA, /* Quality of Service Parameters */
129 IE_NA, /* Broadband Repeat Indicator */
130 IE_NA, /* Restart Indicator */
131 IE_NA, /* Broadband Locking Shift */
132 IE_NA, /* Broadband Non-locking Shift */
133 IE_NA, /* Broadband Sending Complete */
134 IE_NA, /* Transit Net */
135 IE_OPT, /* Endpoint Reference */
136 IE_NA /* Endpoint State */
139 static u_char uni_conn_ie_tbl[] = {
140 IE_OPT, /* ATM AAL Parameters */
141 IE_NA, /* ATM User Cell Rate */
142 IE_NA, /* Broadband Bearer Capability */
143 IE_NA, /* Broadband High Layer Information */
144 IE_OPT, /* Broadband Low Layer Information */
145 IE_NA, /* Call State */
146 IE_NA, /* Called Party Number */
147 IE_NA, /* Called Party Subaddress */
148 IE_NA, /* Calling Party Number */
149 IE_NA, /* Calling Party Subaddress */
151 IE_OPT, /* Connection Identifier */
152 IE_NA, /* Quality of Service Parameters */
153 IE_NA, /* Broadband Repeat Indicator */
154 IE_NA, /* Restart Indicator */
155 IE_NA, /* Broadband Locking Shift */
156 IE_NA, /* Broadband Non-locking Shift */
157 IE_NA, /* Broadband Sending Complete */
158 IE_NA, /* Transit Net */
159 IE_OPT, /* Endpoint Reference */
160 IE_NA /* Endpoint State */
163 static u_char uni_cack_ie_tbl[] = {
164 IE_NA, /* ATM AAL Parameters */
165 IE_NA, /* ATM User Cell Rate */
166 IE_NA, /* Broadband Bearer Capability */
167 IE_NA, /* Broadband High Layer Information */
168 IE_NA, /* Broadband Low Layer Information */
169 IE_NA, /* Call State */
170 IE_NA, /* Called Party Number */
171 IE_NA, /* Called Party Subaddress */
172 IE_NA, /* Calling Party Number */
173 IE_NA, /* Calling Party Subaddress */
175 IE_NA, /* Connection Identifier */
176 IE_NA, /* Quality of Service Parameters */
177 IE_NA, /* Broadband Repeat Indicator */
178 IE_NA, /* Restart Indicator */
179 IE_NA, /* Broadband Locking Shift */
180 IE_NA, /* Broadband Non-locking Shift */
181 IE_NA, /* Broadband Sending Complete */
182 IE_NA, /* Transit Net */
183 IE_NA, /* Endpoint Reference */
184 IE_NA /* Endpoint State */
187 static u_char uni_setu_ie_tbl[] = {
188 IE_MAND, /* ATM AAL Parameters (not required by
190 IE_MAND, /* ATM User Cell Rate */
191 IE_MAND, /* Broadband Bearer Capability */
192 IE_OPT, /* Broadband High Layer Information */
193 IE_MAND, /* Broadband Low Layer Information (not required by UNI 3.0 */
194 IE_NA, /* Call State */
195 IE_MAND, /* Called Party Number */
196 IE_OPT, /* Called Party Subaddress */
197 IE_OPT, /* Calling Party Number */
198 IE_OPT, /* Calling Party Subaddress */
200 IE_MAND, /* Connection Identifier */
201 IE_MAND, /* Quality of Service Parameters */
202 IE_OPT, /* Broadband Repeat Indicator */
203 IE_NA, /* Restart Indicator */
204 IE_NA, /* Broadband Locking Shift */
205 IE_NA, /* Broadband Non-locking Shift */
206 IE_OPT, /* Broadband Sending Complete */
207 IE_NA, /* Transit Net */
208 IE_OPT, /* Endpoint Reference */
209 IE_NA /* Endpoint State */
212 static u_char uni_rlse_ie_tbl[] = {
213 IE_NA, /* ATM AAL Parameters */
214 IE_NA, /* ATM User Cell Rate */
215 IE_NA, /* Broadband Bearer Capability */
216 IE_NA, /* Broadband High Layer Information */
217 IE_NA, /* Broadband Low Layer Information */
218 IE_NA, /* Call State */
219 IE_NA, /* Called Party Number */
220 IE_NA, /* Called Party Subaddress */
221 IE_NA, /* Calling Party Number */
222 IE_NA, /* Calling Party Subaddress */
224 IE_NA, /* Connection Identifier */
225 IE_NA, /* Quality of Service Parameters */
226 IE_NA, /* Broadband Repeat Indicator */
227 IE_NA, /* Restart Indicator */
228 IE_NA, /* Broadband Locking Shift */
229 IE_NA, /* Broadband Non-locking Shift */
230 IE_NA, /* Broadband Sending Complete */
231 IE_NA, /* Transit Net */
232 IE_NA, /* Endpoint Reference */
233 IE_NA /* Endpoint State */
236 static u_char uni_rlsc_ie_tbl[] = {
237 IE_NA, /* ATM AAL Parameters */
238 IE_NA, /* ATM User Cell Rate */
239 IE_NA, /* Broadband Bearer Capability */
240 IE_NA, /* Broadband High Layer Information */
241 IE_NA, /* Broadband Low Layer Information */
242 IE_NA, /* Call State */
243 IE_NA, /* Called Party Number */
244 IE_NA, /* Called Party Subaddress */
245 IE_NA, /* Calling Party Number */
246 IE_NA, /* Calling Party Subaddress */
248 IE_NA, /* Connection Identifier */
249 IE_NA, /* Quality of Service Parameters */
250 IE_NA, /* Broadband Repeat Indicator */
251 IE_NA, /* Restart Indicator */
252 IE_NA, /* Broadband Locking Shift */
253 IE_NA, /* Broadband Non-locking Shift */
254 IE_NA, /* Broadband Sending Complete */
255 IE_NA, /* Transit Net */
256 IE_NA, /* Endpoint Reference */
257 IE_NA /* Endpoint State */
260 static u_char uni_rstr_ie_tbl[] = {
261 IE_NA, /* ATM AAL Parameters */
262 IE_NA, /* ATM User Cell Rate */
263 IE_NA, /* Broadband Bearer Capability */
264 IE_NA, /* Broadband High Layer Information */
265 IE_NA, /* Broadband Low Layer Information */
266 IE_NA, /* Call State */
267 IE_NA, /* Called Party Number */
268 IE_NA, /* Called Party Subaddress */
269 IE_NA, /* Calling Party Number */
270 IE_NA, /* Calling Party Subaddress */
272 IE_OPT, /* Connection Identifier */
273 IE_NA, /* Quality of Service Parameters */
274 IE_NA, /* Broadband Repeat Indicator */
275 IE_MAND, /* Restart Indicator */
276 IE_NA, /* Broadband Locking Shift */
277 IE_NA, /* Broadband Non-locking Shift */
278 IE_NA, /* Broadband Sending Complete */
279 IE_NA, /* Transit Net */
280 IE_NA, /* Endpoint Reference */
281 IE_NA /* Endpoint State */
284 static u_char uni_rsta_ie_tbl[] = {
285 IE_NA, /* ATM AAL Parameters */
286 IE_NA, /* ATM User Cell Rate */
287 IE_NA, /* Broadband Bearer Capability */
288 IE_NA, /* Broadband High Layer Information */
289 IE_NA, /* Broadband Low Layer Information */
290 IE_NA, /* Call State */
291 IE_NA, /* Called Party Number */
292 IE_NA, /* Called Party Subaddress */
293 IE_NA, /* Calling Party Number */
294 IE_NA, /* Calling Party Subaddress */
296 IE_OPT, /* Connection Identifier */
297 IE_NA, /* Quality of Service Parameters */
298 IE_NA, /* Broadband Repeat Indicator */
299 IE_MAND, /* Restart Indicator */
300 IE_NA, /* Broadband Locking Shift */
301 IE_NA, /* Broadband Non-locking Shift */
302 IE_NA, /* Broadband Sending Complete */
303 IE_NA, /* Transit Net */
304 IE_NA, /* Endpoint Reference */
305 IE_NA /* Endpoint State */
308 static u_char uni_stat_ie_tbl[] = {
309 IE_NA, /* ATM AAL Parameters */
310 IE_NA, /* ATM User Cell Rate */
311 IE_NA, /* Broadband Bearer Capability */
312 IE_NA, /* Broadband High Layer Information */
313 IE_NA, /* Broadband Low Layer Information */
314 IE_MAND, /* Call State */
315 IE_NA, /* Called Party Number */
316 IE_NA, /* Called Party Subaddress */
317 IE_NA, /* Calling Party Number */
318 IE_NA, /* Calling Party Subaddress */
320 IE_NA, /* Connection Identifier */
321 IE_NA, /* Quality of Service Parameters */
322 IE_NA, /* Broadband Repeat Indicator */
323 IE_NA, /* Restart Indicator */
324 IE_NA, /* Broadband Locking Shift */
325 IE_NA, /* Broadband Non-locking Shift */
326 IE_NA, /* Broadband Sending Complete */
327 IE_NA, /* Transit Net */
328 IE_OPT, /* Endpoint Reference */
329 IE_OPT /* Endpoint State */
332 static u_char uni_senq_ie_tbl[] = {
333 IE_NA, /* ATM AAL Parameters */
334 IE_NA, /* ATM User Cell Rate */
335 IE_NA, /* Broadband Bearer Capability */
336 IE_NA, /* Broadband High Layer Information */
337 IE_NA, /* Broadband Low Layer Information */
338 IE_NA, /* Call State */
339 IE_NA, /* Called Party Number */
340 IE_NA, /* Called Party Subaddress */
341 IE_NA, /* Calling Party Number */
342 IE_NA, /* Calling Party Subaddress */
344 IE_NA, /* Connection Identifier */
345 IE_NA, /* Quality of Service Parameters */
346 IE_NA, /* Broadband Repeat Indicator */
347 IE_NA, /* Restart Indicator */
348 IE_NA, /* Broadband Locking Shift */
349 IE_NA, /* Broadband Non-locking Shift */
350 IE_NA, /* Broadband Sending Complete */
351 IE_NA, /* Transit Net */
352 IE_OPT, /* Endpoint Reference */
353 IE_NA /* Endpoint State */
356 static u_char uni_addp_ie_tbl[] = {
357 IE_OPT, /* ATM AAL Parameters */
358 IE_NA, /* ATM User Cell Rate */
359 IE_NA, /* Broadband Bearer Capability */
360 IE_OPT, /* Broadband High Layer Information */
361 IE_OPT, /* Broadband Low Layer Information */
362 IE_NA, /* Call State */
363 IE_MAND, /* Called Party Number */
364 IE_OPT, /* Called Party Subaddress */
365 IE_OPT, /* Calling Party Number */
366 IE_OPT, /* Calling Party Subaddress */
368 IE_NA, /* Connection Identifier */
369 IE_NA, /* Quality of Service Parameters */
370 IE_NA, /* Broadband Repeat Indicator */
371 IE_NA, /* Restart Indicator */
372 IE_NA, /* Broadband Locking Shift */
373 IE_NA, /* Broadband Non-locking Shift */
374 IE_OPT, /* Broadband Sending Complete */
375 IE_NA, /* Transit Net */
376 IE_MAND, /* Endpoint Reference */
377 IE_NA /* Endpoint State */
380 static u_char uni_adpa_ie_tbl[] = {
381 IE_NA, /* ATM AAL Parameters */
382 IE_NA, /* ATM User Cell Rate */
383 IE_NA, /* Broadband Bearer Capability */
384 IE_NA, /* Broadband High Layer Information */
385 IE_NA, /* Broadband Low Layer Information */
386 IE_NA, /* Call State */
387 IE_NA, /* Called Party Number */
388 IE_NA, /* Called Party Subaddress */
389 IE_NA, /* Calling Party Number */
390 IE_NA, /* Calling Party Subaddress */
392 IE_NA, /* Connection Identifier */
393 IE_NA, /* Quality of Service Parameters */
394 IE_NA, /* Broadband Repeat Indicator */
395 IE_NA, /* Restart Indicator */
396 IE_NA, /* Broadband Locking Shift */
397 IE_NA, /* Broadband Non-locking Shift */
398 IE_NA, /* Broadband Sending Complete */
399 IE_NA, /* Transit Net */
400 IE_MAND, /* Endpoint Reference */
401 IE_NA /* Endpoint State */
404 static u_char uni_adpr_ie_tbl[] = {
405 IE_NA, /* ATM AAL Parameters */
406 IE_NA, /* ATM User Cell Rate */
407 IE_NA, /* Broadband Bearer Capability */
408 IE_NA, /* Broadband High Layer Information */
409 IE_NA, /* Broadband Low Layer Information */
410 IE_NA, /* Call State */
411 IE_NA, /* Called Party Number */
412 IE_NA, /* Called Party Subaddress */
413 IE_NA, /* Calling Party Number */
414 IE_NA, /* Calling Party Subaddress */
416 IE_NA, /* Connection Identifier */
417 IE_NA, /* Quality of Service Parameters */
418 IE_NA, /* Broadband Repeat Indicator */
419 IE_NA, /* Restart Indicator */
420 IE_NA, /* Broadband Locking Shift */
421 IE_NA, /* Broadband Non-locking Shift */
422 IE_NA, /* Broadband Sending Complete */
423 IE_NA, /* Transit Net */
424 IE_MAND, /* Endpoint Reference */
425 IE_NA /* Endpoint State */
428 static u_char uni_drpp_ie_tbl[] = {
429 IE_NA, /* ATM AAL Parameters */
430 IE_NA, /* ATM User Cell Rate */
431 IE_NA, /* Broadband Bearer Capability */
432 IE_NA, /* Broadband High Layer Information */
433 IE_NA, /* Broadband Low Layer Information */
434 IE_NA, /* Call State */
435 IE_NA, /* Called Party Number */
436 IE_NA, /* Called Party Subaddress */
437 IE_NA, /* Calling Party Number */
438 IE_NA, /* Calling Party Subaddress */
440 IE_NA, /* Connection Identifier */
441 IE_NA, /* Quality of Service Parameters */
442 IE_NA, /* Broadband Repeat Indicator */
443 IE_NA, /* Restart Indicator */
444 IE_NA, /* Broadband Locking Shift */
445 IE_NA, /* Broadband Non-locking Shift */
446 IE_NA, /* Broadband Sending Complete */
447 IE_NA, /* Transit Net */
448 IE_MAND, /* Endpoint Reference */
449 IE_NA /* Endpoint State */
452 static u_char uni_drpa_ie_tbl[] = {
453 IE_NA, /* ATM AAL Parameters */
454 IE_NA, /* ATM User Cell Rate */
455 IE_NA, /* Broadband Bearer Capability */
456 IE_NA, /* Broadband High Layer Information */
457 IE_NA, /* Broadband Low Layer Information */
458 IE_NA, /* Call State */
459 IE_NA, /* Called Party Number */
460 IE_NA, /* Called Party Subaddress */
461 IE_NA, /* Calling Party Number */
462 IE_NA, /* Calling Party Subaddress */
464 IE_NA, /* Connection Identifier */
465 IE_NA, /* Quality of Service Parameters */
466 IE_NA, /* Broadband Repeat Indicator */
467 IE_NA, /* Restart Indicator */
468 IE_NA, /* Broadband Locking Shift */
469 IE_NA, /* Broadband Non-locking Shift */
470 IE_NA, /* Broadband Sending Complete */
471 IE_NA, /* Transit Net */
472 IE_MAND, /* Endpoint Reference */
473 IE_NA /* Endpoint State */
477 * Table of Q.2931 message types
482 } uni_msg_types[] = {
483 { UNI_MSG_CALP, uni_calp_ie_tbl },
484 { UNI_MSG_CONN, uni_conn_ie_tbl },
485 { UNI_MSG_CACK, uni_cack_ie_tbl },
486 { UNI_MSG_SETU, uni_setu_ie_tbl },
487 { UNI_MSG_RLSE, uni_rlse_ie_tbl },
488 { UNI_MSG_RLSC, uni_rlsc_ie_tbl },
489 { UNI_MSG_RSTR, uni_rstr_ie_tbl },
490 { UNI_MSG_RSTA, uni_rsta_ie_tbl },
491 { UNI_MSG_STAT, uni_stat_ie_tbl },
492 { UNI_MSG_SENQ, uni_senq_ie_tbl },
493 { UNI_MSG_ADDP, uni_addp_ie_tbl },
494 { UNI_MSG_ADPA, uni_adpa_ie_tbl },
495 { UNI_MSG_ADPR, uni_adpr_ie_tbl },
496 { UNI_MSG_DRPP, uni_drpp_ie_tbl },
497 { UNI_MSG_DRPA, uni_drpa_ie_tbl },
502 * Table of information elements
504 static struct ie_ent ie_table[] = {
505 { UNI_IE_AALP, 5, 16, UNI_MSG_IE_AALP, usf_dec_ie_aalp },
506 { UNI_IE_CLRT, 0, 26, UNI_MSG_IE_CLRT, usf_dec_ie_clrt },
507 { UNI_IE_BBCP, 2, 3, UNI_MSG_IE_BBCP, usf_dec_ie_bbcp },
508 { UNI_IE_BHLI, 1, 9, UNI_MSG_IE_BHLI, usf_dec_ie_bhli },
509 { UNI_IE_BLLI, 0, 13, UNI_MSG_IE_BLLI, usf_dec_ie_blli },
510 { UNI_IE_CLST, 1, 1, UNI_MSG_IE_CLST, usf_dec_ie_clst },
511 { UNI_IE_CDAD, 1, 21, UNI_MSG_IE_CDAD, usf_dec_ie_cdad },
512 { UNI_IE_CDSA, 1, 21, UNI_MSG_IE_CDSA, usf_dec_ie_cdsa },
513 { UNI_IE_CGAD, 1, 22, UNI_MSG_IE_CGAD, usf_dec_ie_cgad },
514 { UNI_IE_CGSA, 1, 21, UNI_MSG_IE_CGSA, usf_dec_ie_cgsa },
515 { UNI_IE_CAUS, 2, 30, UNI_MSG_IE_CAUS, usf_dec_ie_caus },
516 { UNI_IE_CNID, 5, 5, UNI_MSG_IE_CNID, usf_dec_ie_cnid },
517 { UNI_IE_QOSP, 2, 2, UNI_MSG_IE_QOSP, usf_dec_ie_qosp },
518 { UNI_IE_BRPI, 1, 1, UNI_MSG_IE_BRPI, usf_dec_ie_brpi },
519 { UNI_IE_RSTI, 1, 1, UNI_MSG_IE_RSTI, usf_dec_ie_rsti },
520 { UNI_IE_BLSH, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
521 { UNI_IE_BNSH, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
522 { UNI_IE_BSDC, 1, 1, UNI_MSG_IE_BSDC, usf_dec_ie_bsdc },
523 { UNI_IE_TRNT, 1, 5, UNI_MSG_IE_TRNT, usf_dec_ie_trnt },
524 { UNI_IE_EPRF, 3, 3, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
525 { UNI_IE_EPST, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp },
530 * Decoding table for AAL 1
532 struct ie_decode_tbl ie_aal1_tbl[] = {
533 { 133, 1, IE_OFF_SIZE(ie_aalp_1_subtype) },
534 { 134, 1, IE_OFF_SIZE(ie_aalp_1_cbr_rate) },
535 { 135, 2, IE_OFF_SIZE(ie_aalp_1_multiplier) },
536 { 136, 1, IE_OFF_SIZE(ie_aalp_1_clock_recovery) },
537 { 137, 1, IE_OFF_SIZE(ie_aalp_1_error_correction) },
538 { 138, 1, IE_OFF_SIZE(ie_aalp_1_struct_data_tran) },
539 { 139, 1, IE_OFF_SIZE(ie_aalp_1_partial_cells) },
544 * Decoding table for AAL 3/4
546 struct ie_decode_tbl ie_aal4_tbl_30[] = {
547 { 140, 2, IE_OFF_SIZE(ie_aalp_4_fwd_max_sdu) },
548 { 129, 2, IE_OFF_SIZE(ie_aalp_4_bkwd_max_sdu) },
549 { 130, 2, IE_OFF_SIZE(ie_aalp_4_mid_range) },
550 { 131, 1, IE_OFF_SIZE(ie_aalp_4_mode) },
551 { 132, 1, IE_OFF_SIZE(ie_aalp_4_sscs_type) },
554 struct ie_decode_tbl ie_aal4_tbl_31[] = {
555 { 140, 2, IE_OFF_SIZE(ie_aalp_4_fwd_max_sdu) },
556 { 129, 2, IE_OFF_SIZE(ie_aalp_4_bkwd_max_sdu) },
557 { 130, 4, IE_OFF_SIZE(ie_aalp_4_mid_range) },
558 { 132, 1, IE_OFF_SIZE(ie_aalp_4_sscs_type) },
563 * Decoding table for AAL 5
565 struct ie_decode_tbl ie_aal5_tbl_30[] = {
566 { 140, 2, IE_OFF_SIZE(ie_aalp_5_fwd_max_sdu) },
567 { 129, 2, IE_OFF_SIZE(ie_aalp_5_bkwd_max_sdu) },
568 { 131, 1, IE_OFF_SIZE(ie_aalp_5_mode) },
569 { 132, 1, IE_OFF_SIZE(ie_aalp_5_sscs_type) },
572 struct ie_decode_tbl ie_aal5_tbl_31[] = {
573 { 140, 2, IE_OFF_SIZE(ie_aalp_5_fwd_max_sdu) },
574 { 129, 2, IE_OFF_SIZE(ie_aalp_5_bkwd_max_sdu) },
575 { 132, 1, IE_OFF_SIZE(ie_aalp_5_sscs_type) },
580 * Decoding table for ATM user cell rate
582 struct ie_decode_tbl ie_clrt_tbl[] = {
583 {UNI_IE_CLRT_FWD_PEAK_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_peak)},
584 {UNI_IE_CLRT_BKWD_PEAK_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_peak)},
585 {UNI_IE_CLRT_FWD_PEAK_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_peak_01)},
586 {UNI_IE_CLRT_BKWD_PEAK_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_peak_01)},
587 {UNI_IE_CLRT_FWD_SUST_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_sust)},
588 {UNI_IE_CLRT_BKWD_SUST_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_sust)},
589 {UNI_IE_CLRT_FWD_SUST_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_sust_01)},
590 {UNI_IE_CLRT_BKWD_SUST_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_sust_01)},
591 {UNI_IE_CLRT_FWD_BURST_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_burst)},
592 {UNI_IE_CLRT_BKWD_BURST_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_burst)},
593 {UNI_IE_CLRT_FWD_BURST_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_burst_01)},
594 {UNI_IE_CLRT_BKWD_BURST_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_burst_01)},
595 {UNI_IE_CLRT_BEST_EFFORT_ID, 0, IE_OFF_SIZE(ie_clrt_best_effort)},
596 {UNI_IE_CLRT_TM_OPTIONS_ID, 1, IE_OFF_SIZE(ie_clrt_tm_options)},
601 * IEs initialized to empty values
603 struct ie_aalp ie_aalp_absent = {
607 struct ie_clrt ie_clrt_absent = {
624 struct ie_bbcp ie_bbcp_absent = {
632 struct ie_bhli ie_bhli_absent = {
634 { 0, 0, 0, 0, 0, 0, 0, 0 }
637 struct ie_blli ie_blli_absent = {
655 struct ie_clst ie_clst_absent = {
659 struct ie_cdad ie_cdad_absent = {
665 struct ie_cdsa ie_cdsa_absent = {
669 struct ie_cgad ie_cgad_absent = {
677 struct ie_cgsa ie_cgsa_absent = {
681 struct ie_caus ie_caus_absent = {
687 struct ie_cnid ie_cnid_absent = {
694 struct ie_qosp ie_qosp_absent = {
699 struct ie_brpi ie_brpi_absent = {
703 struct ie_rsti ie_rsti_absent = {
707 struct ie_blsh ie_blsh_absent = {
711 struct ie_bnsh ie_bnsh_absent = {
715 struct ie_bsdc ie_bsdc_absent = {
719 struct ie_trnt ie_trnt_absent = {
725 struct ie_eprf ie_eprf_absent = {
730 struct ie_epst ie_epst_absent = {
736 * Decode a UNI signalling message
739 * usf pointer to a unisig formatting structure
740 * msg pointer to a signalling message structure
744 * errno error encountered
748 usf_dec_msg(usf, msg)
750 struct unisig_msg *msg;
755 struct ie_generic *ie;
757 ATM_DEBUG2("usf_dec_msg: usf=%p, msg=%p\n", usf, msg);
760 * Check the total message length
762 if (usf_count(usf) < UNI_MSG_MIN_LEN) {
767 * Get and check the protocol discriminator
769 rc = usf_byte(usf, &c);
772 if (c != UNI_MSG_DISC_Q93B)
776 * Get and check the call reference length
778 rc = usf_byte(usf, &c);
785 * Get the call reference
787 rc = usf_int3(usf, &msg->msg_call_ref);
792 * Get the message type
794 rc = usf_byte(usf, &msg->msg_type);
799 * Get the message type extension
801 rc = usf_byte(usf, &c);
804 msg->msg_type_flag = (c >> UNI_MSG_TYPE_FLAG_SHIFT) &
805 UNI_MSG_TYPE_FLAG_MASK;
806 msg->msg_type_action = c & UNI_MSG_TYPE_ACT_MASK;
809 * Get the message length and make sure we actually have
810 * enough data for the whole message
812 rc = usf_short(usf, &s);
816 if (usf_count(usf) != msg->msg_length) {
821 * Process information elements
823 len = msg->msg_length;
826 rc = usf_dec_ie(usf, msg, ie);
831 len -= (ie->ie_length + UNI_IE_HDR_LEN);
835 * Make sure that mandatory IEs are included and
836 * unwanted ones aren't
838 for (i=0; msg->msg_type!=uni_msg_types[i].msg_type &&
839 uni_msg_types[i].msg_type!=0; i++) {
841 if (!uni_msg_types[i].msg_ie_tbl)
845 * If the message type is in the table, check the IEs.
846 * If it isn't, the receive routine will catch the error.
848 ie_tbl = uni_msg_types[i].msg_ie_tbl;
849 for (i=0; i<UNI_MSG_IE_CNT-1; i++) {
852 if (!msg->msg_ie_vec[i]) {
854 * Mandatory IE missing
857 ie->ie_ident = unisig_ie_ident_vec[i];
858 ie->ie_err_cause = UNI_IE_CAUS_MISSING;
859 MSG_IE_ADD(msg, ie, UNI_MSG_IE_ERR);
863 if (msg->msg_ie_vec[i]) {
865 * Disallowed IE present
867 ie = msg->msg_ie_vec[i];
869 (struct ie_generic *) 0;
870 MSG_IE_ADD(msg, ie, UNI_MSG_IE_ERR);
889 * Decode an information element
891 * This routine will be called repeatedly as long as there are
892 * information elements left to be decoded. It will decode the
893 * first part of the IE, look its type up in a table, and call
894 * the appropriate routine to decode the rest. After an IE is
895 * successfully decoded, it is linked into the UNI signalling
896 * message structure. If an error is discovered, the IE is linked
897 * into the IE error chain and an error cause is set in the header.
900 * usf pointer to a UNISIG formatting structure
901 * msg pointer to a UNISIG message structure
902 * ie pointer to a generic IE structure
906 * errno error encountered
910 usf_dec_ie(usf, msg, ie)
912 struct unisig_msg *msg;
913 struct ie_generic *ie;
918 * Decode the IE header (identifier, instruction field,
921 rc = usf_dec_ie_hdr(usf, ie);
925 * Ignore the IE if it is of zero length.
927 if (!ie->ie_length) {
933 * Look up the information element in the table
935 for (i=0; (ie->ie_ident != ie_table[i].ident) &&
936 (ie_table[i].decode != NULL); i++) {
938 if (ie_table[i].decode == NULL) {
942 ie_index = UNI_MSG_IE_ERR;
944 ie_index = ie_table[i].p_idx;
948 * Check for unimplemented or unrecognized IEs
950 if (ie_index == UNI_MSG_IE_ERR) {
951 ie->ie_err_cause = UNI_IE_CAUS_IEEXIST;
954 * Skip over the invalid IE
956 rc = usf_dec_ie_uimp(usf, ie);
963 * Check the length against the IE table
965 if (ie->ie_length < ie_table[i].min_len ||
966 ie->ie_length > ie_table[i].max_len) {
967 ie_index = UNI_MSG_IE_ERR;
968 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
971 * Skip over the invalid IE
973 rc = usf_dec_ie_uimp(usf, ie);
980 * Process the IE by calling the function indicated
983 rc = ie_table[i].decode(usf, ie);
988 * Link the IE into the signalling message
991 if (ie->ie_err_cause) {
992 ie_index = UNI_MSG_IE_ERR;
994 MSG_IE_ADD(msg, ie, ie_index);
1001 * Decode an information element header
1004 * usf pointer to a UNISIG formatting structure
1005 * ie pointer to a generic IE structure
1009 * errno error encountered
1013 usf_dec_ie_hdr(usf, ie)
1015 struct ie_generic *ie;
1022 * Get the IE identifier
1024 rc = usf_byte(usf, &ie->ie_ident);
1029 * Get the extended type
1031 rc = usf_byte(usf, &c);
1034 ie->ie_coding = (c >> UNI_IE_CODE_SHIFT) & UNI_IE_CODE_MASK;
1035 ie->ie_flag = (c >> UNI_IE_FLAG_SHIFT) & UNI_IE_FLAG_MASK;
1036 ie->ie_action = c & UNI_IE_ACT_MASK;
1041 rc = usf_short(usf, &s);
1051 * Decode an AAL parameters information element
1054 * usf pointer to a unisig formatting structure
1055 * ie pointer to an AAL parms IE structure
1059 * errno error encountered
1063 usf_dec_ie_aalp(usf, ie)
1065 struct ie_generic *ie;
1072 KM_COPY(&ie_aalp_absent, &ie->ie_u.ie_aalp,
1073 sizeof(ie_aalp_absent));
1078 rc = usf_byte(usf, &ie->ie_aalp_aal_type);
1083 * Subtract the length of the AAL type from the total.
1084 * It will be readjusted after usf_dec_ie_ident is finished.
1089 * Process based on AAL type
1091 switch (ie->ie_aalp_aal_type) {
1092 case UNI_IE_AALP_AT_AAL1:
1094 * Clear the AAL 1 subparameters
1096 ie->ie_aalp_1_subtype = T_ATM_ABSENT;
1097 ie->ie_aalp_1_cbr_rate = T_ATM_ABSENT;
1098 ie->ie_aalp_1_multiplier = T_ATM_ABSENT;
1099 ie->ie_aalp_1_clock_recovery = T_ATM_ABSENT;
1100 ie->ie_aalp_1_error_correction = T_ATM_ABSENT;
1101 ie->ie_aalp_1_struct_data_tran = T_ATM_ABSENT;
1102 ie->ie_aalp_1_partial_cells = T_ATM_ABSENT;
1105 * Parse the AAL fields based on their IDs
1107 rc = usf_dec_ie_ident(usf, ie, ie_aal1_tbl);
1109 case UNI_IE_AALP_AT_AAL3:
1111 * Clear the AAL 3/4 subparameters
1113 ie->ie_aalp_4_fwd_max_sdu = T_ATM_ABSENT;
1114 ie->ie_aalp_4_bkwd_max_sdu = T_ATM_ABSENT;
1115 ie->ie_aalp_4_mid_range = T_ATM_ABSENT;
1116 ie->ie_aalp_4_mode = T_ATM_ABSENT;
1117 ie->ie_aalp_4_sscs_type = T_ATM_ABSENT;
1120 * Parse the AAL fields based on their IDs
1122 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
1123 rc = usf_dec_ie_ident(usf, ie, ie_aal4_tbl_30);
1125 rc = usf_dec_ie_ident(usf, ie, ie_aal4_tbl_31);
1128 * If either forward or backward maximum SDU
1129 * size is specified, the other must also be
1132 if ((ie->ie_aalp_4_fwd_max_sdu != T_ATM_ABSENT &&
1133 ie->ie_aalp_4_bkwd_max_sdu == T_ATM_ABSENT) ||
1134 (ie->ie_aalp_4_fwd_max_sdu == T_ATM_ABSENT &&
1135 ie->ie_aalp_4_bkwd_max_sdu != T_ATM_ABSENT)) {
1136 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1139 case UNI_IE_AALP_AT_AAL5:
1141 * Clear the AAL 5 subparameters
1143 ie->ie_aalp_5_fwd_max_sdu = T_ATM_ABSENT;
1144 ie->ie_aalp_5_bkwd_max_sdu = T_ATM_ABSENT;
1145 ie->ie_aalp_5_mode = T_ATM_ABSENT;
1146 ie->ie_aalp_5_sscs_type = T_ATM_ABSENT;
1149 * Parse the AAL fields based on their IDs
1151 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
1152 rc = usf_dec_ie_ident(usf, ie, ie_aal5_tbl_30);
1154 rc = usf_dec_ie_ident(usf, ie, ie_aal5_tbl_31);
1157 * If either forward or backward maximum SDU
1158 * size is specified, the other must also be
1161 if ((ie->ie_aalp_5_fwd_max_sdu != T_ATM_ABSENT &&
1162 ie->ie_aalp_5_bkwd_max_sdu == T_ATM_ABSENT) ||
1163 (ie->ie_aalp_5_fwd_max_sdu == T_ATM_ABSENT &&
1164 ie->ie_aalp_5_bkwd_max_sdu != T_ATM_ABSENT)) {
1165 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1168 case UNI_IE_AALP_AT_AALU:
1170 * Check user parameter length
1173 sizeof(ie->ie_aalp_user_info) +
1175 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1182 while (i < ie->ie_length - 2) {
1183 rc = usf_byte(usf, &ie->ie_aalp_user_info[i]);
1190 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1199 * Decode a user cell rate information element
1202 * usf pointer to a unisig formatting structure
1203 * ie pointer to a cell rate IE structure
1207 * errno error encountered
1211 usf_dec_ie_clrt(usf, ie)
1213 struct ie_generic *ie;
1220 KM_COPY(&ie_clrt_absent, &ie->ie_u.ie_clrt,
1221 sizeof(ie_clrt_absent));
1224 * Parse the IE using field identifiers
1226 rc = usf_dec_ie_ident(usf, ie, ie_clrt_tbl);
1232 * Decode a broadband bearer capability information element
1235 * usf pointer to a unisig formatting structure
1236 * ie pointer to a cell rate IE structure
1240 * errno error encountered
1244 usf_dec_ie_bbcp(usf, ie)
1246 struct ie_generic *ie;
1254 KM_COPY(&ie_bbcp_absent, &ie->ie_u.ie_bbcp,
1255 sizeof(ie_bbcp_absent));
1258 * Get the broadband bearer class
1260 rc = usf_byte(usf, &c);
1263 ie->ie_bbcp_bearer_class = c & UNI_IE_BBCP_BC_MASK;
1266 * If the broadband bearer class was X, the next
1267 * byte has the traffic type and timing requirements
1269 if (ie->ie_bbcp_bearer_class == UNI_IE_BBCP_BC_BCOB_X &&
1270 !(c & UNI_IE_EXT_BIT)) {
1271 rc = usf_byte(usf, &c);
1274 ie->ie_bbcp_traffic_type = (c >> UNI_IE_BBCP_TT_SHIFT) &
1275 UNI_IE_BBCP_TT_MASK;
1276 ie->ie_bbcp_timing_req = c & UNI_IE_BBCP_TR_MASK;
1280 * Get the clipping and user plane connection configuration
1282 if (c & UNI_IE_EXT_BIT) {
1283 rc = usf_byte(usf, &c);
1286 ie->ie_bbcp_clipping = (c >> UNI_IE_BBCP_SC_SHIFT) &
1287 UNI_IE_BBCP_SC_MASK;
1288 ie->ie_bbcp_conn_config = c & UNI_IE_BBCP_CC_MASK;
1296 * Decode a broadband high layer information element
1299 * usf pointer to a unisig formatting structure
1300 * ie pointer to a cell rate IE structure
1304 * errno error encountered
1308 usf_dec_ie_bhli(usf, ie)
1310 struct ie_generic *ie;
1318 KM_COPY(&ie_bhli_absent, &ie->ie_u.ie_bhli,
1319 sizeof(ie_bhli_absent));
1322 * Get the high layer information type
1324 rc = usf_ext(usf, &i);
1325 ie->ie_bhli_type = i & UNI_IE_EXT_MASK;
1330 * What comes next depends on the type
1332 switch (ie->ie_bhli_type) {
1333 case UNI_IE_BHLI_TYPE_ISO:
1334 case UNI_IE_BHLI_TYPE_USER:
1336 * ISO or user-specified parameters -- take the
1337 * length of information from the IE length
1339 for (i=0; i<ie->ie_length-1; i++) {
1340 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
1345 case UNI_IE_BHLI_TYPE_HLP:
1347 * Make sure the IE is long enough for the high
1348 * layer profile information, then get it
1350 if (usf->usf_sig->us_proto != ATM_SIG_UNI30)
1351 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1352 if (ie->ie_length < UNI_IE_BHLI_HLP_LEN+1)
1353 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1354 for (i=0; i<ie->ie_length &&
1355 i<UNI_IE_BHLI_HLP_LEN; i++) {
1356 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
1361 case UNI_IE_BHLI_TYPE_VSA:
1363 * Make sure the IE is long enough for the vendor-
1364 * specific application information, then get it
1366 if (ie->ie_length < UNI_IE_BHLI_VSA_LEN+1)
1367 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1368 for (i=0; i<ie->ie_length &&
1369 i<UNI_IE_BHLI_VSA_LEN; i++) {
1370 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
1376 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1377 for (i=0; i<ie->ie_length; i++) {
1378 rc = usf_byte(usf, &c);
1389 * Decode a broadband low layer information element
1392 * usf pointer to a unisig formatting structure
1393 * ie pointer to a cell rate IE structure
1397 * errno error encountered
1401 usf_dec_ie_blli(usf, ie)
1403 struct ie_generic *ie;
1412 KM_COPY(&ie_blli_absent, &ie->ie_u.ie_blli,
1413 sizeof(ie_blli_absent));
1416 * Get paramteters for the protocol layers as long as
1417 * there is still information left in the IE
1422 * Get the type and process based on what it is
1424 rc = usf_byte(usf, &id);
1427 switch (((id & UNI_IE_EXT_MASK) >>
1428 UNI_IE_BLLI_LID_SHIFT) &
1429 UNI_IE_BLLI_LID_MASK) {
1430 case UNI_IE_BLLI_L1_ID:
1434 ie->ie_blli_l1_id = id & UNI_IE_BLLI_LP_MASK;
1437 case UNI_IE_BLLI_L2_ID:
1439 * Layer 2 info--contents vary based on type
1441 ie->ie_blli_l2_id = id & UNI_IE_BLLI_LP_MASK;
1443 if (id & UNI_IE_EXT_BIT)
1445 switch (ie->ie_blli_l2_id) {
1446 case UNI_IE_BLLI_L2P_X25L:
1447 case UNI_IE_BLLI_L2P_X25M:
1448 case UNI_IE_BLLI_L2P_HDLC1:
1449 case UNI_IE_BLLI_L2P_HDLC2:
1450 case UNI_IE_BLLI_L2P_HDLC3:
1451 case UNI_IE_BLLI_L2P_Q922:
1452 case UNI_IE_BLLI_L2P_ISO7776:
1453 rc = usf_byte(usf, &c);
1457 ie->ie_blli_l2_mode = (c >>
1458 UNI_IE_BLLI_L2MODE_SHIFT) &
1459 UNI_IE_BLLI_L2MODE_MASK;
1460 if (!(c & UNI_IE_EXT_BIT))
1462 rc = usf_byte(usf, &c);
1466 ie->ie_blli_l2_window =
1467 c & UNI_IE_EXT_MASK;
1469 case UNI_IE_BLLI_L2P_USER:
1470 rc = usf_byte(usf, &c);
1474 ie->ie_blli_l2_user_proto =
1475 c & UNI_IE_EXT_MASK;
1479 case UNI_IE_BLLI_L3_ID:
1481 * Layer 3 info--contents vary based on type
1483 ie->ie_blli_l3_id = id & UNI_IE_BLLI_LP_MASK;
1485 switch (ie->ie_blli_l3_id) {
1486 case UNI_IE_BLLI_L3P_X25:
1487 case UNI_IE_BLLI_L3P_ISO8208:
1488 case UNI_IE_BLLI_L3P_ISO8878:
1489 rc = usf_byte(usf, &c);
1493 ie->ie_blli_l3_mode = (c >>
1494 UNI_IE_BLLI_L3MODE_SHIFT) &
1495 UNI_IE_BLLI_L3MODE_MASK;
1496 if (!(c & UNI_IE_EXT_BIT))
1498 rc = usf_byte(usf, &c);
1502 ie->ie_blli_l3_packet_size =
1503 c & UNI_IE_BLLI_L3PS_MASK;
1504 if (!(c & UNI_IE_EXT_BIT))
1506 rc = usf_byte(usf, &c);
1510 ie->ie_blli_l3_window =
1511 c & UNI_IE_EXT_MASK;
1513 case UNI_IE_BLLI_L3P_USER:
1514 rc = usf_byte(usf, &c);
1518 ie->ie_blli_l3_mode =
1519 c & UNI_IE_EXT_MASK;
1521 case UNI_IE_BLLI_L3P_ISO9577:
1522 rc = usf_ext(usf, &ipi);
1526 ie->ie_blli_l3_ipi = ipi >>
1527 UNI_IE_BLLI_L3IPI_SHIFT;
1528 if (ie->ie_blli_l3_ipi !=
1529 UNI_IE_BLLI_L3IPI_SNAP)
1532 rc = usf_byte(usf, &c);
1533 ie->ie_blli_l3_snap_id = c & UNI_IE_EXT_MASK;
1539 &ie->ie_blli_l3_oui[0]);
1543 &ie->ie_blli_l3_oui[1]);
1547 &ie->ie_blli_l3_oui[2]);
1551 &ie->ie_blli_l3_pid[0]);
1555 &ie->ie_blli_l3_pid[1]);
1563 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1564 for (i=0; i<ie->ie_length; i++) {
1565 rc = usf_byte(usf, &c);
1577 * Decode a call state information element
1580 * usf pointer to a unisig formatting structure
1581 * ie pointer to a cell rate IE structure
1585 * errno error encountered
1589 usf_dec_ie_clst(usf, ie)
1591 struct ie_generic *ie;
1599 KM_COPY(&ie_clst_absent, &ie->ie_u.ie_clst,
1600 sizeof(ie_clst_absent));
1602 rc = usf_byte(usf, &c);
1605 ie->ie_clst_state = c & UNI_IE_CLST_STATE_MASK;
1612 * Decode a called party number information element
1615 * usf pointer to a unisig formatting structure
1616 * ie pointer to a cell rate IE structure
1620 * errno error encountered
1624 usf_dec_ie_cdad(usf, ie)
1626 struct ie_generic *ie;
1634 KM_COPY(&ie_cdad_absent, &ie->ie_u.ie_cdad,
1635 sizeof(ie_cdad_absent));
1638 * Get and check the numbering plan
1640 rc = usf_byte(usf, &c);
1643 ie->ie_cdad_plan = c & UNI_IE_CDAD_PLAN_MASK;
1644 len = ie->ie_length - 1;
1645 switch (ie->ie_cdad_plan) {
1646 case UNI_IE_CDAD_PLAN_E164:
1647 ie->ie_cdad_addr.address_format = T_ATM_E164_ADDR;
1649 case UNI_IE_CDAD_PLAN_NSAP:
1650 ie->ie_cdad_addr.address_format = T_ATM_ENDSYS_ADDR;
1654 * Invalid numbering plan
1656 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1658 rc = usf_byte(usf, &c);
1668 * Get the ATM address
1670 rc = usf_dec_atm_addr(usf, &ie->ie_cdad_addr, len);
1672 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1681 * Decode a called party subaddress information element
1684 * usf pointer to a unisig formatting structure
1685 * ie pointer to a cell rate IE structure
1689 * errno error encountered
1693 usf_dec_ie_cdsa(usf, ie)
1695 struct ie_generic *ie;
1703 KM_COPY(&ie_cdsa_absent, &ie->ie_u.ie_cdsa,
1704 sizeof(ie_cdsa_absent));
1707 * Get and check the subaddress type
1709 rc = usf_byte(usf, &c);
1712 len = ie->ie_length - 1;
1713 if (((c >> UNI_IE_CDSA_TYPE_SHIFT) & UNI_IE_CDSA_TYPE_MASK) !=
1714 UNI_IE_CDSA_TYPE_AESA) {
1716 * Invalid subaddress type
1718 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1720 rc = usf_byte(usf, &c);
1730 * Get the ATM address
1732 ie->ie_cdsa_addr.address_format = T_ATM_ENDSYS_ADDR;
1733 rc = usf_dec_atm_addr(usf, &ie->ie_cdsa_addr, len);
1735 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1744 * Decode a calling party number information element
1747 * usf pointer to a unisig formatting structure
1748 * ie pointer to a cell rate IE structure
1752 * errno error encountered
1756 usf_dec_ie_cgad(usf, ie)
1758 struct ie_generic *ie;
1766 KM_COPY(&ie_cgad_absent, &ie->ie_u.ie_cgad,
1767 sizeof(ie_cgad_absent));
1770 * Get and check the numbering plan
1772 len = ie->ie_length;
1773 rc = usf_byte(usf, &c);
1776 ie->ie_cgad_type = (c >> UNI_IE_CGAD_TYPE_SHIFT) &
1777 UNI_IE_CGAD_TYPE_MASK;
1778 ie->ie_cgad_plan = c & UNI_IE_CGAD_PLAN_MASK;
1780 switch (ie->ie_cgad_plan) {
1781 case UNI_IE_CGAD_PLAN_E164:
1782 ie->ie_cgad_addr.address_format = T_ATM_E164_ADDR;
1784 case UNI_IE_CGAD_PLAN_NSAP:
1785 ie->ie_cgad_addr.address_format = T_ATM_ENDSYS_ADDR;
1788 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1790 rc = usf_byte(usf, &c);
1800 * Get the presentation and screening indicators, if present
1802 if (!(c & UNI_IE_EXT_BIT)) {
1803 rc = usf_byte(usf, &c);
1807 ie->ie_cgad_pres_ind = (c >> UNI_IE_CGAD_PRES_SHIFT) &
1808 UNI_IE_CGAD_PRES_MASK;
1809 ie->ie_cgad_screen_ind = c & UNI_IE_CGAD_SCR_MASK;
1811 ie->ie_cgad_pres_ind = 0;
1812 ie->ie_cgad_screen_ind =0;
1816 * Get the ATM address
1818 rc = usf_dec_atm_addr(usf, &ie->ie_cgad_addr, len);
1820 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1829 * Decode a calling party subaddress information element
1832 * usf pointer to a unisig formatting structure
1833 * ie pointer to a cell rate IE structure
1837 * errno error encountered
1841 usf_dec_ie_cgsa(usf, ie)
1843 struct ie_generic *ie;
1851 KM_COPY(&ie_cgsa_absent, &ie->ie_u.ie_cgsa,
1852 sizeof(ie_cgsa_absent));
1855 * Get and check the subaddress type
1857 rc = usf_byte(usf, &c);
1860 len = ie->ie_length - 1;
1861 if (((c >> UNI_IE_CGSA_TYPE_SHIFT) & UNI_IE_CGSA_TYPE_MASK) !=
1862 UNI_IE_CGSA_TYPE_AESA) {
1864 * Invalid subaddress type
1866 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1868 rc = usf_byte(usf, &c);
1878 * Get the ATM address
1880 ie->ie_cgsa_addr.address_format = T_ATM_ENDSYS_ADDR;
1881 rc = usf_dec_atm_addr(usf, &ie->ie_cgsa_addr, len);
1883 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
1892 * Decode a cause information element
1895 * usf pointer to a unisig formatting structure
1896 * ie pointer to a cell rate IE structure
1900 * errno error encountered
1904 usf_dec_ie_caus(usf, ie)
1906 struct ie_generic *ie;
1914 KM_COPY(&ie_caus_absent, &ie->ie_u.ie_caus,
1915 sizeof(ie_caus_absent));
1918 * Get the cause location
1920 rc = usf_byte(usf, &c);
1923 ie->ie_caus_loc = c & UNI_IE_CAUS_LOC_MASK;
1926 * Get the cause value
1928 rc = usf_byte(usf, &c);
1931 ie->ie_caus_cause = c & UNI_IE_EXT_MASK;
1934 * Get any included diagnostics
1936 len = ie->ie_length - 2;
1937 for (i = 0, ie->ie_caus_diag_len = 0;
1938 len && i < sizeof(ie->ie_caus_diagnostic);
1939 len--, i++, ie->ie_caus_diag_len++) {
1940 rc = usf_byte(usf, &ie->ie_caus_diagnostic[i]);
1950 * Decode a conection identifier information element
1953 * usf pointer to a unisig formatting structure
1954 * ie pointer to a cell rate IE structure
1958 * errno error encountered
1962 usf_dec_ie_cnid(usf, ie)
1964 struct ie_generic *ie;
1971 KM_COPY(&ie_cnid_absent, &ie->ie_u.ie_cnid,
1972 sizeof(ie_cnid_absent));
1974 rc = usf_ext(usf, &i);
1977 ie->ie_cnid_vp_sig = (i >> UNI_IE_CNID_VPSIG_SHIFT) &
1978 UNI_IE_CNID_VPSIG_MASK;
1979 ie->ie_cnid_pref_excl = i & UNI_IE_CNID_PREX_MASK;
1981 rc = usf_short(usf, &ie->ie_cnid_vpci);
1984 rc = usf_short(usf, &ie->ie_cnid_vci);
1990 * Decode a quality of service parameters information element
1993 * usf pointer to a unisig formatting structure
1994 * ie pointer to a cell rate IE structure
1998 * errno error encountered
2002 usf_dec_ie_qosp(usf, ie)
2004 struct ie_generic *ie;
2011 KM_COPY(&ie_qosp_absent, &ie->ie_u.ie_qosp,
2012 sizeof(ie_qosp_absent));
2015 * Get forward QoS class
2017 rc = usf_byte(usf, &ie->ie_qosp_fwd_class);
2022 * Get backward QoS class
2024 rc = usf_byte(usf, &ie->ie_qosp_bkwd_class);
2031 * Decode a broadband repeat indicator information element
2034 * usf pointer to a unisig formatting structure
2035 * ie pointer to a cell rate IE structure
2039 * errno error encountered
2043 usf_dec_ie_brpi(usf, ie)
2045 struct ie_generic *ie;
2053 KM_COPY(&ie_brpi_absent, &ie->ie_u.ie_brpi,
2054 sizeof(ie_brpi_absent));
2057 * Get the repeat indicator
2059 rc = usf_byte(usf, &c);
2063 ie->ie_brpi_ind = c & UNI_IE_BRPI_IND_MASK;
2070 * Decode a restart indicator information element
2073 * usf pointer to a unisig formatting structure
2074 * ie pointer to a cell rate IE structure
2078 * errno error encountered
2082 usf_dec_ie_rsti(usf, ie)
2084 struct ie_generic *ie;
2092 KM_COPY(&ie_rsti_absent, &ie->ie_u.ie_rsti,
2093 sizeof(ie_rsti_absent));
2096 * Get the restart class
2098 rc = usf_byte(usf, &c);
2102 ie->ie_rsti_class = c & UNI_IE_RSTI_CLASS_MASK;
2109 * Decode a broadband sending complete information element
2112 * usf pointer to a unisig formatting structure
2113 * ie pointer to a broadband sending complete IE structure
2117 * errno error encountered
2121 usf_dec_ie_bsdc(usf, ie)
2123 struct ie_generic *ie;
2131 KM_COPY(&ie_bsdc_absent, &ie->ie_u.ie_bsdc,
2132 sizeof(ie_bsdc_absent));
2135 * Get the sending complete indicator
2137 rc = usf_byte(usf, &c);
2142 * Validate the indicator
2144 c &= UNI_IE_EXT_MASK;
2145 if (c != UNI_IE_BSDC_IND)
2146 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
2147 ie->ie_bsdc_ind = c;
2154 * Decode a transit network selection information element
2157 * usf pointer to a unisig formatting structure
2158 * ie pointer to a transit network selection IE structure
2162 * errno error encountered
2166 usf_dec_ie_trnt(usf, ie)
2168 struct ie_generic *ie;
2176 KM_COPY(&ie_trnt_absent, &ie->ie_u.ie_trnt,
2177 sizeof(ie_trnt_absent));
2180 * Get the network ID type and plan
2182 rc = usf_byte(usf, &c);
2185 ie->ie_trnt_id_type = (c >> UNI_IE_TRNT_IDT_SHIFT) &
2186 UNI_IE_TRNT_IDT_MASK;
2187 ie->ie_trnt_id_plan = c & UNI_IE_TRNT_IDP_MASK;
2190 * Get the length of the network ID
2192 len = ie->ie_length - 1;
2193 ie->ie_trnt_id_len = MIN(len, sizeof(ie->ie_trnt_id));
2196 * Get the network ID
2198 for (i=0; i<len; i++) {
2199 if (i<sizeof(ie->ie_trnt_id))
2200 rc = usf_byte(usf, &ie->ie_trnt_id[i]);
2202 rc = usf_byte(usf, &c);
2212 * Decode an unimplemented information element
2215 * usf pointer to a unisig formatting structure
2216 * ie pointer to a cell rate IE structure
2220 * errno error encountered
2224 usf_dec_ie_uimp(usf, ie)
2226 struct ie_generic *ie;
2232 * Skip over the IE contents
2234 for (i=0; i<ie->ie_length; i++) {
2235 rc = usf_byte(usf, &c);
2245 * Decode an information element using field identifiers
2247 * The AAL parameters and ATM user cell rate IEs are formatted
2248 * with a one-byte identifier preceeding each field. The routine
2249 * parses these IEs by using a table which relates the field
2250 * identifiers with the fields in the appropriate IE structure.
2251 * Field order in the received message is immaterial.
2254 * usf pointer to a unisig formatting structure
2255 * ie pointer to a cell rate IE structure
2256 * tbl pointer to an IE decoding table
2260 * errno error encountered
2264 usf_dec_ie_ident(usf, ie, tbl)
2266 struct ie_generic *ie;
2267 struct ie_decode_tbl *tbl;
2277 * Scan through the IE
2279 len = ie->ie_length;
2282 * Get the field identifier
2284 rc = usf_byte(usf, &c);
2290 * Look up the field in the table
2292 for (i=0; (tbl[i].ident != c) && tbl[i].len; i++) {
2294 if (tbl[i].ident == 0) {
2296 * Bad subfield identifier -- flag an
2297 * error and skip over the rest of the IE
2299 ie->ie_err_cause = UNI_IE_CAUS_IECONTENT;
2301 rc = usf_byte(usf, &c);
2309 * Save final destination address
2311 dest = (void *)((int)ie + tbl[i].f_offs);
2314 * Get the field value
2316 switch (tbl[i].len) {
2322 rc = usf_byte(usf, &cv);
2329 switch (tbl[i].f_size) {
2331 *(u_int8_t *)dest = cv;
2334 *(u_int16_t *)dest = cv;
2337 *(u_int32_t *)dest = cv;
2345 rc = usf_short(usf, &sv);
2352 switch (tbl[i].f_size) {
2354 *(u_int16_t *)dest = sv;
2357 *(u_int32_t *)dest = sv;
2365 rc = usf_int3(usf, &iv);
2369 rc = usf_int(usf, &iv);
2376 switch (tbl[i].f_size) {
2378 *(u_int32_t *)dest = iv;
2388 "uni decode: id=%d,len=%d,off=%d,size=%d\n",
2389 tbl[i].ident, tbl[i].len,
2390 tbl[i].f_offs, tbl[i].f_size);
2407 * Decode an ATM address
2410 * usf pointer to a unisig formatting structure
2411 * addr pointer to an ATM address structure
2412 * len length of data remainig in the IE
2416 * errno error encountered
2420 usf_dec_atm_addr(usf, addr, len)
2429 * Check the address type
2431 addr->address_length = len;
2432 switch (addr->address_format) {
2433 case T_ATM_E164_ADDR:
2434 if (len > sizeof(Atm_addr_e164)) {
2437 cp = (u_char *) addr->address;
2439 case T_ATM_ENDSYS_ADDR:
2440 if (len != sizeof(Atm_addr_nsap)) {
2443 cp = (u_char *) addr->address;
2446 /* Silence the compiler */
2451 * Get the ATM address
2454 rc = usf_byte(usf, cp);
2465 rc = usf_byte(usf, &c);