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_encode.c,v 1.5 2000/01/17 20:49:56 mks Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/unisig_encode.c,v 1.6 2006/01/14 13:36:39 swildner Exp $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
34 * Message formatting module
38 #include <netproto/atm/kern_include.h>
40 #include "unisig_var.h"
41 #include "unisig_msg.h"
42 #include "unisig_mbuf.h"
43 #include "unisig_decode.h"
48 static int usf_enc_ie (struct usfmt
*, struct ie_generic
*);
49 static int usf_enc_ie_aalp (struct usfmt
*, struct ie_generic
*);
50 static int usf_enc_ie_clrt (struct usfmt
*, struct ie_generic
*);
51 static int usf_enc_ie_bbcp (struct usfmt
*, struct ie_generic
*);
52 static int usf_enc_ie_bhli (struct usfmt
*, struct ie_generic
*);
53 static int usf_enc_ie_blli (struct usfmt
*, struct ie_generic
*);
54 static int usf_enc_ie_clst (struct usfmt
*, struct ie_generic
*);
55 static int usf_enc_ie_cdad (struct usfmt
*, struct ie_generic
*);
56 static int usf_enc_ie_cdsa (struct usfmt
*, struct ie_generic
*);
57 static int usf_enc_ie_cgad (struct usfmt
*, struct ie_generic
*);
58 static int usf_enc_ie_cgsa (struct usfmt
*, struct ie_generic
*);
59 static int usf_enc_ie_caus (struct usfmt
*, struct ie_generic
*);
60 static int usf_enc_ie_cnid (struct usfmt
*, struct ie_generic
*);
61 static int usf_enc_ie_qosp (struct usfmt
*, struct ie_generic
*);
62 static int usf_enc_ie_brpi (struct usfmt
*, struct ie_generic
*);
63 static int usf_enc_ie_rsti (struct usfmt
*, struct ie_generic
*);
64 static int usf_enc_ie_bsdc (struct usfmt
*, struct ie_generic
*);
65 static int usf_enc_ie_trnt (struct usfmt
*, struct ie_generic
*);
66 static int usf_enc_ie_uimp (struct usfmt
*, struct ie_generic
*);
67 static int usf_enc_ie_ident (struct usfmt
*, struct ie_generic
*,
68 struct ie_decode_tbl
*);
69 static int usf_enc_atm_addr (struct usfmt
*, Atm_addr
*);
76 u_char ident
; /* IE identifier */
77 int (*encode
) (struct usfmt
*, struct ie_generic
*);
78 /* Encoding function */
80 { UNI_IE_AALP
, usf_enc_ie_aalp
},
81 { UNI_IE_CLRT
, usf_enc_ie_clrt
},
82 { UNI_IE_BBCP
, usf_enc_ie_bbcp
},
83 { UNI_IE_BHLI
, usf_enc_ie_bhli
},
84 { UNI_IE_BLLI
, usf_enc_ie_blli
},
85 { UNI_IE_CLST
, usf_enc_ie_clst
},
86 { UNI_IE_CDAD
, usf_enc_ie_cdad
},
87 { UNI_IE_CDSA
, usf_enc_ie_cdsa
},
88 { UNI_IE_CGAD
, usf_enc_ie_cgad
},
89 { UNI_IE_CGSA
, usf_enc_ie_cgsa
},
90 { UNI_IE_CAUS
, usf_enc_ie_caus
},
91 { UNI_IE_CNID
, usf_enc_ie_cnid
},
92 { UNI_IE_QOSP
, usf_enc_ie_qosp
},
93 { UNI_IE_BRPI
, usf_enc_ie_brpi
},
94 { UNI_IE_RSTI
, usf_enc_ie_rsti
},
95 { UNI_IE_BLSH
, usf_enc_ie_uimp
},
96 { UNI_IE_BNSH
, usf_enc_ie_uimp
},
97 { UNI_IE_BSDC
, usf_enc_ie_bsdc
},
98 { UNI_IE_TRNT
, usf_enc_ie_trnt
},
99 { UNI_IE_EPRF
, usf_enc_ie_uimp
},
100 { UNI_IE_EPST
, usf_enc_ie_uimp
},
104 extern struct ie_decode_tbl ie_aal1_tbl
[];
105 extern struct ie_decode_tbl ie_aal4_tbl_30
[];
106 extern struct ie_decode_tbl ie_aal4_tbl_31
[];
107 extern struct ie_decode_tbl ie_aal5_tbl_30
[];
108 extern struct ie_decode_tbl ie_aal5_tbl_31
[];
109 extern struct ie_decode_tbl ie_clrt_tbl
[];
113 * Encode a UNI signalling message
116 * usf pointer to a unisig formatting structure
117 * msg pointer to a signalling message structure
121 * errno error encountered
125 usf_enc_msg(struct usfmt
*usf
, struct unisig_msg
*msg
)
130 struct ie_generic
*ie
;
134 u_char sb
[sizeof(short)];
137 ATM_DEBUG2("usf_enc_msg: usf=%p, msg=%p\n",
141 * Encode the protocol discriminator
143 c
= UNI_MSG_DISC_Q93B
;
144 rc
= usf_byte(usf
, &c
);
149 * Encode the call reference length
152 rc
= usf_byte(usf
, &c
);
157 * Encode the call reference
159 rc
= usf_int3(usf
, &msg
->msg_call_ref
);
164 * Encode the message type
166 rc
= usf_byte(usf
, &msg
->msg_type
);
171 * Encode the message type extension
173 c
= ((msg
->msg_type_flag
& UNI_MSG_TYPE_FLAG_MASK
) <<
174 UNI_MSG_TYPE_FLAG_SHIFT
) +
175 (msg
->msg_type_action
& UNI_MSG_TYPE_ACT_MASK
) +
177 rc
= usf_byte(usf
, &c
);
182 * Save the location of the message length and encode a length
183 * of zero for now. We'll fix the length up at the end.
186 rc
= usf_byte_mark(usf
, &su
.sb
[sizeof(short)-2], &lp0
);
189 rc
= usf_byte_mark(usf
, &su
.sb
[sizeof(short)-1], &lp1
);
194 * Process information elements
197 for (i
=0; i
<UNI_MSG_IE_CNT
; i
++) {
198 ie
= msg
->msg_ie_vec
[i
];
200 rc
= usf_enc_ie(usf
, ie
);
203 len
+= (ie
->ie_length
+ UNI_IE_HDR_LEN
);
209 * Fix the message length in the encoded message
211 su
.s
= htons((u_short
)len
);
212 *lp0
= su
.sb
[sizeof(short)-2];
213 *lp1
= su
.sb
[sizeof(short)-1];
220 * Encode an information element
223 * usf pointer to a UNISIG formatting structure
224 * msg pointer to a UNISIG message structure
225 * ie pointer to a generic IE structure
229 * errno error encountered
233 usf_enc_ie(struct usfmt
*usf
, struct ie_generic
*ie
)
241 u_char sb
[sizeof(short)];
244 ATM_DEBUG2("usf_enc_ie: usf=%p, ie=%p\n",
248 * Encode the IE identifier
250 rc
= usf_byte(usf
, &ie
->ie_ident
);
255 * Encode the extended type
257 c
= ((ie
->ie_coding
& UNI_IE_CODE_MASK
) << UNI_IE_CODE_SHIFT
) +
258 ((ie
->ie_flag
& UNI_IE_FLAG_MASK
) <<
260 (ie
->ie_action
& UNI_IE_ACT_MASK
) +
262 rc
= usf_byte(usf
, &c
);
267 * Mark the current location in the output stream. Encode a
268 * length of zero for now; we'll come back and fix it up at
272 rc
= usf_byte_mark(usf
, &su
.sb
[sizeof(short)-2], &lp0
);
275 rc
= usf_byte_mark(usf
, &su
.sb
[sizeof(short)-1], &lp1
);
280 * Look up the information element in the table
282 for (i
=0; (ie
->ie_ident
!= ie_table
[i
].ident
) &&
283 (ie_table
[i
].encode
!= NULL
); i
++) {
285 if (ie_table
[i
].encode
== NULL
) {
293 * Process the IE by calling the function indicated
296 rc
= ie_table
[i
].encode(usf
, ie
);
301 * Set the length in the output stream
303 su
.s
= htons((u_short
)ie
->ie_length
);
304 *lp0
= su
.sb
[sizeof(short)-2];
305 *lp1
= su
.sb
[sizeof(short)-1];
312 * Encode an AAL parameters information element
315 * usf pointer to a unisig formatting structure
316 * ie pointer to an AAL parms IE structure
320 * errno error encountered
324 usf_enc_ie_aalp(struct usfmt
*usf
, struct ie_generic
*ie
)
328 ATM_DEBUG2("usf_enc_ie_aalp: usf=%p, ie=%p\n",
334 * Encode the AAL type
336 if (ie
->ie_aalp_aal_type
== T_ATM_ABSENT
)
338 rc
= usf_byte(usf
, &ie
->ie_aalp_aal_type
);
343 * Process based on AAL type
345 switch (ie
->ie_aalp_aal_type
) {
346 case UNI_IE_AALP_AT_AAL1
:
347 rc
= usf_enc_ie_ident(usf
, ie
, ie_aal1_tbl
);
349 case UNI_IE_AALP_AT_AAL3
:
350 if (usf
->usf_sig
->us_proto
== ATM_SIG_UNI30
)
351 rc
= usf_enc_ie_ident(usf
, ie
, ie_aal4_tbl_30
);
353 rc
= usf_enc_ie_ident(usf
, ie
, ie_aal4_tbl_31
);
355 case UNI_IE_AALP_AT_AAL5
:
356 if (usf
->usf_sig
->us_proto
== ATM_SIG_UNI30
)
357 rc
= usf_enc_ie_ident(usf
, ie
, ie_aal5_tbl_30
);
359 rc
= usf_enc_ie_ident(usf
, ie
, ie_aal5_tbl_31
);
361 case UNI_IE_AALP_AT_AALU
:
363 * Encode the user data
366 while (i
< sizeof(ie
->ie_aalp_user_info
)) {
367 rc
= usf_byte(usf
, &ie
->ie_aalp_user_info
[i
]);
384 * Encode a user cell rate information element
386 * This routine just encodes the parameters required for best
390 * usf pointer to a unisig formatting structure
391 * ie pointer to a cell rate IE structure
395 * errno error encountered
399 usf_enc_ie_clrt(struct usfmt
*usf
, struct ie_generic
*ie
)
403 ATM_DEBUG2("usf_enc_ie_clrt: usf=%p, ie=%p\n",
408 * Encode Peak Cell Rate Forward CLP = 0 + 1
410 c
= UNI_IE_CLRT_FWD_PEAK_01_ID
;
411 rc
= usf_byte(usf
, &c
);
414 rc
= usf_int3(usf
, &ie
->ie_clrt_fwd_peak_01
);
419 * Encode Peak Cell Rate Backward CLP = 0 + 1
421 c
= UNI_IE_CLRT_BKWD_PEAK_01_ID
;
422 rc
= usf_byte(usf
, &c
);
425 rc
= usf_int3(usf
, &ie
->ie_clrt_bkwd_peak_01
);
430 * Encode Best Effort Flag
432 c
= UNI_IE_CLRT_BEST_EFFORT_ID
;
433 rc
= usf_byte(usf
, &c
);
444 * Encode the user cell rate IE using the table
447 rc
= usf_enc_ie_ident(usf
, ie
, ie_clrt_tbl
);
454 * Encode a broadband bearer capability information element
457 * usf pointer to a unisig formatting structure
458 * ie pointer to a cell rate IE structure
462 * errno error encountered
466 usf_enc_ie_bbcp(struct usfmt
*usf
, struct ie_generic
*ie
)
471 ATM_DEBUG2("usf_enc_ie_bbcp: usf=%p, ie=%p\n",
477 * Encode the broadband bearer class
479 if (ie
->ie_bbcp_bearer_class
== T_ATM_ABSENT
)
481 c
= ie
->ie_bbcp_bearer_class
& UNI_IE_BBCP_BC_MASK
;
482 if (ie
->ie_bbcp_bearer_class
!= UNI_IE_BBCP_BC_BCOB_X
)
484 rc
= usf_byte(usf
, &c
);
490 * If the broadband bearer class was X, the next
491 * byte has the traffic type and timing requirements
493 if (ie
->ie_bbcp_bearer_class
== UNI_IE_BBCP_BC_BCOB_X
) {
494 c
= ((ie
->ie_bbcp_traffic_type
& UNI_IE_BBCP_TT_MASK
) <<
495 UNI_IE_BBCP_TT_SHIFT
) +
496 (ie
->ie_bbcp_timing_req
&
497 UNI_IE_BBCP_TR_MASK
) +
499 rc
= usf_byte(usf
, &c
);
506 * Encode the clipping and user plane connection configuration
508 c
= ((ie
->ie_bbcp_clipping
& UNI_IE_BBCP_SC_MASK
) <<
509 UNI_IE_BBCP_SC_SHIFT
) +
510 (ie
->ie_bbcp_conn_config
&
511 UNI_IE_BBCP_CC_MASK
) +
513 rc
= usf_byte(usf
, &c
);
523 * Encode a broadband high layer information element
526 * usf pointer to a unisig formatting structure
527 * ie pointer to a cell rate IE structure
531 * errno error encountered
535 usf_enc_ie_bhli(struct usfmt
*usf
, struct ie_generic
*ie
)
540 ATM_DEBUG2("usf_enc_ie_bhli: usf=%p, ie=%p\n",
546 * Encode the high layer information type
548 if (ie
->ie_bhli_type
== T_ATM_ABSENT
)
550 type
= ie
->ie_bhli_type
| UNI_IE_EXT_BIT
;
551 rc
= usf_ext(usf
, &type
);
557 * What comes next depends on the type
559 switch (ie
->ie_bhli_type
) {
560 case UNI_IE_BHLI_TYPE_ISO
:
561 case UNI_IE_BHLI_TYPE_USER
:
563 * ISO or user-specified parameters -- take the
564 * length of information from the IE length
566 for (i
=0; i
<ie
->ie_length
-1; i
++) {
567 rc
= usf_byte(usf
, &ie
->ie_bhli_info
[i
]);
573 case UNI_IE_BHLI_TYPE_HLP
:
575 * Make sure the IE is long enough for the high
576 * layer profile information, then get it
578 if (usf
->usf_sig
->us_proto
!= ATM_SIG_UNI30
)
580 for (i
=0; i
<UNI_IE_BHLI_HLP_LEN
; i
++) {
581 rc
= usf_byte(usf
, &ie
->ie_bhli_info
[i
]);
587 case UNI_IE_BHLI_TYPE_VSA
:
589 * Make sure the IE is long enough for the vendor-
590 * specific application information, then get it
592 for (i
=0; i
<UNI_IE_BHLI_VSA_LEN
; i
++) {
593 rc
= usf_byte(usf
, &ie
->ie_bhli_info
[i
]);
608 * Encode a broadband low layer information element
611 * usf pointer to a unisig formatting structure
612 * ie pointer to a cell rate IE structure
616 * errno error encountered
620 usf_enc_ie_blli(struct usfmt
*usf
, struct ie_generic
*ie
)
626 ATM_DEBUG2("usf_enc_ie_blli: usf=%p, ie=%p\n",
632 * Encode paramteters for whichever protocol layers the
637 * Layer 1 information
639 if (ie
->ie_blli_l1_id
&& ie
->ie_blli_l1_id
!= T_ATM_ABSENT
) {
640 c
= (UNI_IE_BLLI_L1_ID
<< UNI_IE_BLLI_LID_SHIFT
) +
642 UNI_IE_BLLI_LP_MASK
) +
644 rc
= usf_byte(usf
, &c
);
651 * Layer 2 information
653 if (ie
->ie_blli_l2_id
&& ie
->ie_blli_l2_id
!= T_ATM_ABSENT
) {
654 c
= (UNI_IE_BLLI_L2_ID
<< UNI_IE_BLLI_LID_SHIFT
) +
656 UNI_IE_BLLI_LP_MASK
);
658 switch (ie
->ie_blli_l2_id
) {
659 case UNI_IE_BLLI_L2P_X25L
:
660 case UNI_IE_BLLI_L2P_X25M
:
661 case UNI_IE_BLLI_L2P_HDLC1
:
662 case UNI_IE_BLLI_L2P_HDLC2
:
663 case UNI_IE_BLLI_L2P_HDLC3
:
664 case UNI_IE_BLLI_L2P_Q922
:
665 case UNI_IE_BLLI_L2P_ISO7776
:
667 * Write the Layer 2 type
669 rc
= usf_byte(usf
, &c
);
675 * Encode the Layer 2 mode
677 if (ie
->ie_blli_l2_mode
) {
678 c
= (ie
->ie_blli_l2_mode
&
679 UNI_IE_BLLI_L2MODE_MASK
) <<
680 UNI_IE_BLLI_L2MODE_SHIFT
;
681 if (!ie
->ie_blli_l2_window
)
684 rc
= usf_byte(usf
, &c
);
691 * Encode the Layer 2 window size
693 if (ie
->ie_blli_l2_window
) {
694 c
= (ie
->ie_blli_l2_window
&
698 rc
= usf_byte(usf
, &c
);
704 case UNI_IE_BLLI_L2P_USER
:
706 * Write the Layer 2 type
708 rc
= usf_byte(usf
, &c
);
714 * Encode the user-specified layer 2 info
716 c
= (ie
->ie_blli_l2_user_proto
&
719 rc
= usf_byte(usf
, &c
);
726 * Write the Layer 2 type
729 rc
= usf_byte(usf
, &c
);
738 * Layer 3 information
740 if (ie
->ie_blli_l3_id
&& ie
->ie_blli_l3_id
!= T_ATM_ABSENT
) {
742 * Encode the layer 3 protocol ID
744 c
= (UNI_IE_BLLI_L3_ID
<< UNI_IE_BLLI_LID_SHIFT
) +
746 UNI_IE_BLLI_LP_MASK
);
749 * Process other fields based on protocol ID
751 switch(ie
->ie_blli_l3_id
) {
752 case UNI_IE_BLLI_L3P_X25
:
753 case UNI_IE_BLLI_L3P_ISO8208
:
754 case UNI_IE_BLLI_L3P_ISO8878
:
756 * Write the protocol ID
758 rc
= usf_byte(usf
, &c
);
763 if (ie
->ie_blli_l3_mode
||
764 ie
->ie_blli_l3_packet_size
||
765 ie
->ie_blli_l3_window
) {
766 c
= (ie
->ie_blli_l3_mode
&
767 UNI_IE_BLLI_L3MODE_MASK
) <<
768 UNI_IE_BLLI_L3MODE_SHIFT
;
769 if (!ie
->ie_blli_l3_packet_size
&&
770 !ie
->ie_blli_l3_window
)
773 rc
= usf_byte(usf
, &c
);
779 if (ie
->ie_blli_l3_packet_size
||
780 ie
->ie_blli_l3_window
) {
781 c
= ie
->ie_blli_l3_packet_size
&
782 UNI_IE_BLLI_L3PS_MASK
;
783 if (!ie
->ie_blli_l3_window
)
786 rc
= usf_byte(usf
, &c
);
792 if (ie
->ie_blli_l3_window
) {
793 c
= (ie
->ie_blli_l3_window
&
797 rc
= usf_byte(usf
, &c
);
803 case UNI_IE_BLLI_L3P_USER
:
805 * Write the protocol ID
807 rc
= usf_byte(usf
, &c
);
813 * Encode the user-specified protocol info
815 c
= (ie
->ie_blli_l3_user_proto
&
819 rc
= usf_byte(usf
, &c
);
824 case UNI_IE_BLLI_L3P_ISO9577
:
826 * Write the protocol ID
828 rc
= usf_byte(usf
, &c
);
836 ipi
= ie
->ie_blli_l3_ipi
<<
837 UNI_IE_BLLI_L3IPI_SHIFT
;
838 rc
= usf_ext(usf
, &ipi
);
843 if (ie
->ie_blli_l3_ipi
==
844 UNI_IE_BLLI_L3IPI_SNAP
) {
846 rc
= usf_byte(usf
, &c
);
851 &ie
->ie_blli_l3_oui
[0]);
856 &ie
->ie_blli_l3_oui
[1]);
861 &ie
->ie_blli_l3_oui
[2]);
866 &ie
->ie_blli_l3_pid
[0]);
871 &ie
->ie_blli_l3_pid
[1]);
880 * Write the layer 3 protocol ID
883 rc
= usf_byte(usf
, &c
);
896 * Encode a call state information element
899 * usf pointer to a unisig formatting structure
900 * ie pointer to a cell rate IE structure
904 * errno error encountered
908 usf_enc_ie_clst(struct usfmt
*usf
, struct ie_generic
*ie
)
913 ATM_DEBUG2("usf_enc_ie_clst: usf=%p, ie=%p\n",
916 c
= ie
->ie_clst_state
& UNI_IE_CLST_STATE_MASK
;
917 rc
= usf_byte(usf
, &c
);
927 * Encode a called party number information element
930 * usf pointer to a unisig formatting structure
931 * ie pointer to a cell rate IE structure
935 * errno error encountered
939 usf_enc_ie_cdad(struct usfmt
*usf
, struct ie_generic
*ie
)
944 ATM_DEBUG2("usf_enc_ie_cdad: usf=%p, ie=%p\n",
948 * Encode the numbering plan
950 switch(ie
->ie_cdad_addr
.address_format
) {
951 case T_ATM_E164_ADDR
:
952 c
= UNI_IE_CDAD_PLAN_E164
+
953 (UNI_IE_CDAD_TYPE_INTL
954 << UNI_IE_CDAD_TYPE_SHIFT
);
955 ie
->ie_length
= sizeof(Atm_addr_e164
) + 1;
957 case T_ATM_ENDSYS_ADDR
:
958 c
= UNI_IE_CDAD_PLAN_NSAP
+
959 (UNI_IE_CDAD_TYPE_UNK
960 << UNI_IE_CDAD_TYPE_SHIFT
);
961 ie
->ie_length
= sizeof(Atm_addr_nsap
) + 1;
967 rc
= usf_byte(usf
, &c
);
972 * Encode the ATM address
974 rc
= usf_enc_atm_addr(usf
, &ie
->ie_cdad_addr
);
981 * Encode a called party subaddress information element
984 * usf pointer to a unisig formatting structure
985 * ie pointer to a cell rate IE structure
989 * errno error encountered
993 usf_enc_ie_cdsa(struct usfmt
*usf
, struct ie_generic
*ie
)
999 * Encode the subaddress type
1001 switch(ie
->ie_cdsa_addr
.address_format
) {
1002 case T_ATM_ENDSYS_ADDR
:
1003 c
= UNI_IE_CDSA_TYPE_AESA
<< UNI_IE_CDSA_TYPE_SHIFT
;
1004 ie
->ie_length
= sizeof(Atm_addr_nsap
) + 1;
1009 c
|= UNI_IE_EXT_BIT
;
1010 rc
= usf_byte(usf
, &c
);
1015 * Encode the ATM address
1017 rc
= usf_enc_atm_addr(usf
, &ie
->ie_cdsa_addr
);
1024 * Encode a calling party number information element
1027 * usf pointer to a unisig formatting structure
1028 * ie pointer to a cell rate IE structure
1032 * errno error encountered
1036 usf_enc_ie_cgad(struct usfmt
*usf
, struct ie_generic
*ie
)
1041 ATM_DEBUG2("usf_enc_ie_cgad: usf=%p, ie=%p\n",
1045 * Encode the numbering plan
1047 switch(ie
->ie_cgad_addr
.address_format
) {
1048 case T_ATM_E164_ADDR
:
1049 c
= UNI_IE_CGAD_PLAN_E164
+
1050 (UNI_IE_CGAD_TYPE_INTL
1051 << UNI_IE_CGAD_TYPE_SHIFT
) +
1053 ie
->ie_length
= sizeof(Atm_addr_e164
) + 1;
1055 case T_ATM_ENDSYS_ADDR
:
1056 c
= UNI_IE_CGAD_PLAN_NSAP
+
1057 (UNI_IE_CGAD_TYPE_UNK
1058 << UNI_IE_CGAD_TYPE_SHIFT
) +
1060 ie
->ie_length
= sizeof(Atm_addr_nsap
) + 1;
1065 rc
= usf_byte(usf
, &c
);
1070 * Encode the presentation and screening indicators
1073 c
= ((ie
->ie_cgad_pres_ind
& UNI_IE_CGAD_PRES_MASK
)
1074 << UNI_IE_CGAD_PRES_SHIFT
) +
1075 (ie
->ie_cgad_screen_ind
&
1076 UNI_IE_CGAD_SCR_MASK
) +
1078 rc
= usf_byte(usf
, &c
);
1085 * Encode the ATM address
1087 rc
= usf_enc_atm_addr(usf
, &ie
->ie_cgad_addr
);
1094 * Encode a calling party subaddress information element
1097 * usf pointer to a unisig formatting structure
1098 * ie pointer to a cell rate IE structure
1102 * errno error encountered
1106 usf_enc_ie_cgsa(struct usfmt
*usf
, struct ie_generic
*ie
)
1112 * Encode the subaddress type
1114 switch(ie
->ie_cgsa_addr
.address_format
) {
1115 case T_ATM_ENDSYS_ADDR
:
1116 c
= UNI_IE_CGSA_TYPE_AESA
<< UNI_IE_CGSA_TYPE_SHIFT
;
1117 ie
->ie_length
= sizeof(Atm_addr_nsap
) + 1;
1122 c
|= UNI_IE_EXT_BIT
;
1123 rc
= usf_byte(usf
, &c
);
1128 * Encode the ATM address
1130 rc
= usf_enc_atm_addr(usf
, &ie
->ie_cgsa_addr
);
1137 * Encode a cause information element
1140 * usf pointer to a unisig formatting structure
1141 * ie pointer to a cell rate IE structure
1145 * errno error encountered
1149 usf_enc_ie_caus(struct usfmt
*usf
, struct ie_generic
*ie
)
1154 ATM_DEBUG2("usf_enc_ie_caus: usf=%p, ie=%p\n",
1160 * Encode the cause location
1162 c
= (ie
->ie_caus_loc
& UNI_IE_CAUS_LOC_MASK
) | UNI_IE_EXT_BIT
;
1163 rc
= usf_byte(usf
, &c
);
1169 * Encode the cause value
1171 c
= ie
->ie_caus_cause
| UNI_IE_EXT_BIT
;
1172 rc
= usf_byte(usf
, &c
);
1178 * Encode any included diagnostics
1180 for (i
= 0; i
< ie
->ie_caus_diag_len
&&
1181 i
< sizeof(ie
->ie_caus_diagnostic
);
1183 rc
= usf_byte(usf
, &ie
->ie_caus_diagnostic
[i
]);
1194 * Encode a conection identifier information element
1197 * usf pointer to a unisig formatting structure
1198 * ie pointer to a cell rate IE structure
1202 * errno error encountered
1206 usf_enc_ie_cnid(struct usfmt
*usf
, struct ie_generic
*ie
)
1211 ATM_DEBUG2("usf_enc_ie_cnid: usf=%p, ie=%p\n",
1214 c
= ((ie
->ie_cnid_vp_sig
& UNI_IE_CNID_VPSIG_MASK
)
1215 << UNI_IE_CNID_VPSIG_SHIFT
) +
1216 (ie
->ie_cnid_pref_excl
& UNI_IE_CNID_PREX_MASK
) +
1218 rc
= usf_byte(usf
, &c
);
1222 rc
= usf_short(usf
, &ie
->ie_cnid_vpci
);
1225 rc
= usf_short(usf
, &ie
->ie_cnid_vci
);
1235 * Encode a quality of service parameters information element
1238 * usf pointer to a unisig formatting structure
1239 * ie pointer to a cell rate IE structure
1243 * errno error encountered
1247 usf_enc_ie_qosp(struct usfmt
*usf
, struct ie_generic
*ie
)
1251 ATM_DEBUG2("usf_enc_ie_qosp: usf=%p, ie=%p\n",
1255 * Encode forward QoS class
1257 if (ie
->ie_qosp_fwd_class
== T_ATM_ABSENT
||
1258 ie
->ie_qosp_bkwd_class
== T_ATM_ABSENT
)
1260 rc
= usf_byte(usf
, &ie
->ie_qosp_fwd_class
);
1265 * Encode backward QoS class
1267 rc
= usf_byte(usf
, &ie
->ie_qosp_bkwd_class
);
1275 * Encode a broadband repeat indicator information element
1278 * usf pointer to a unisig formatting structure
1279 * ie pointer to a cell rate IE structure
1283 * errno error encountered
1287 usf_enc_ie_brpi(struct usfmt
*usf
, struct ie_generic
*ie
)
1292 ATM_DEBUG2("usf_enc_ie_brpi: usf=%p, ie=%p\n",
1296 * Encode the repeat indicator
1298 c
= ie
->ie_brpi_ind
+ UNI_IE_EXT_BIT
;
1299 rc
= usf_byte(usf
, &c
);
1306 * Encode a restart indicator information element
1309 * usf pointer to a unisig formatting structure
1310 * ie pointer to a cell rate IE structure
1314 * errno error encountered
1318 usf_enc_ie_rsti(struct usfmt
*usf
, struct ie_generic
*ie
)
1323 ATM_DEBUG2("usf_enc_ie_rsti: usf=%p, ie=%p\n",
1327 * Encode the restart class
1329 c
= (ie
->ie_rsti_class
& UNI_IE_RSTI_CLASS_MASK
) |
1331 rc
= usf_byte(usf
, &c
);
1339 * Encode a broadband sending complete information element
1342 * usf pointer to a unisig formatting structure
1343 * ie pointer to a broadband sending complete IE structure
1347 * errno error encountered
1351 usf_enc_ie_bsdc(struct usfmt
*usf
, struct ie_generic
*ie
)
1356 ATM_DEBUG2("usf_enc_ie_bsdc: usf=%p, ie=%p\n",
1360 * Encode the sending complete indicator
1362 c
= UNI_IE_BSDC_IND
| UNI_IE_EXT_BIT
;
1363 rc
= usf_byte(usf
, &c
);
1371 * Encode a transit network selection information element
1374 * usf pointer to a unisig formatting structure
1375 * ie pointer to a transit network selection rate IE structure
1379 * errno error encountered
1383 usf_enc_ie_trnt(struct usfmt
*usf
, struct ie_generic
*ie
)
1388 ATM_DEBUG2("usf_enc_ie_trnt: usf=%p, ie=%p\n",
1392 * Encode the sending complete indicator
1394 c
= ((ie
->ie_trnt_id_type
& UNI_IE_TRNT_IDT_MASK
) <<
1395 UNI_IE_TRNT_IDT_SHIFT
) +
1396 (ie
->ie_trnt_id_plan
& UNI_IE_TRNT_IDP_MASK
) +
1398 rc
= usf_byte(usf
, &c
);
1404 * Encode the network identification
1406 for (i
=0; i
<ie
->ie_trnt_id_len
; i
++) {
1407 rc
= usf_byte(usf
, &ie
->ie_trnt_id
[i
]);
1418 * Encode an unsupported IE type
1421 * usf pointer to a unisig formatting structure
1422 * ie pointer to an IE structure
1429 usf_enc_ie_uimp(struct usfmt
*usf
, struct ie_generic
*ie
)
1436 * Encode an information element using field identifiers
1438 * The AAL parameters and ATM user cell rate IEs are formatted
1439 * with a one-byte identifier preceeding each field. The routine
1440 * encodes these IEs by using a table which relates the field
1441 * identifiers with the fields in the appropriate IE structure.
1444 * usf pointer to a unisig formatting structure
1445 * ie pointer to a cell rate IE structure
1446 * tbl pointer to an IE decoding table
1450 * errno error encountered
1454 usf_enc_ie_ident(struct usfmt
*usf
, struct ie_generic
*ie
,
1455 struct ie_decode_tbl
*tbl
)
1463 ATM_DEBUG3("usf_enc_ie_ident: usf=%p, ie=%p, tbl=%p\n",
1467 * Scan through the IE table
1470 for (i
=0; tbl
[i
].ident
; i
++) {
1472 * Check whether to send the field
1474 cp
= (char *) ((int)ie
+ tbl
[i
].f_offs
);
1475 if (tbl
[i
].len
== 0) {
1476 if ((*cp
== T_NO
|| *cp
== T_ATM_ABSENT
))
1479 switch (tbl
[i
].f_size
) {
1481 if (*(int8_t *)cp
== T_ATM_ABSENT
)
1485 if (*(int16_t *)cp
== T_ATM_ABSENT
)
1489 if (*(int32_t *)cp
== T_ATM_ABSENT
)
1495 "uni encode: id=%d,len=%d,off=%d,size=%d\n",
1496 tbl
[i
].ident
, tbl
[i
].len
,
1497 tbl
[i
].f_offs
, tbl
[i
].f_size
);
1503 * Encode the field identifier
1505 rc
= usf_byte(usf
, &tbl
[i
].ident
);
1511 * Encode the field value
1513 switch (tbl
[i
].len
) {
1517 switch (tbl
[i
].f_size
) {
1519 cv
= *(u_int8_t
*)cp
;
1522 cv
= *(u_int16_t
*)cp
;
1525 cv
= *(u_int32_t
*)cp
;
1530 rc
= usf_byte(usf
, &cv
);
1534 switch (tbl
[i
].f_size
) {
1536 sv
= *(u_int16_t
*)cp
;
1539 sv
= *(u_int32_t
*)cp
;
1544 rc
= usf_short(usf
, &sv
);
1548 switch (tbl
[i
].f_size
) {
1550 iv
= *(u_int32_t
*)cp
;
1555 rc
= usf_int3(usf
, &iv
);
1559 switch (tbl
[i
].f_size
) {
1561 iv
= *(u_int32_t
*)cp
;
1566 rc
= usf_int(usf
, &iv
);
1579 ie
->ie_length
= len
;
1585 * Encode an ATM address
1588 * usf pointer to a unisig formatting structure
1589 * addr pointer to an ATM address structure. The address
1590 * type must already be set correctly.
1594 * errno error encountered
1598 usf_enc_atm_addr(struct usfmt
*usf
, Atm_addr
*addr
)
1604 * Check the address type
1606 switch (addr
->address_format
) {
1607 case T_ATM_E164_ADDR
:
1608 cp
= (u_char
*) addr
->address
;
1609 len
= sizeof(Atm_addr_e164
);
1611 case T_ATM_ENDSYS_ADDR
:
1612 cp
= (u_char
*) addr
->address
;
1613 len
= sizeof(Atm_addr_nsap
);
1620 * Get the address bytes
1623 rc
= usf_byte(usf
, cp
);