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.3 2003/08/07 21:17:35 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 "unisig_var.h"
41 #include "unisig_msg.h"
42 #include "unisig_mbuf.h"
43 #include "unisig_decode.h"
48 static int usf_enc_ie __P((struct usfmt *, struct ie_generic *));
49 static int usf_enc_ie_aalp __P((struct usfmt *, struct ie_generic *));
50 static int usf_enc_ie_clrt __P((struct usfmt *, struct ie_generic *));
51 static int usf_enc_ie_bbcp __P((struct usfmt *, struct ie_generic *));
52 static int usf_enc_ie_bhli __P((struct usfmt *, struct ie_generic *));
53 static int usf_enc_ie_blli __P((struct usfmt *, struct ie_generic *));
54 static int usf_enc_ie_clst __P((struct usfmt *, struct ie_generic *));
55 static int usf_enc_ie_cdad __P((struct usfmt *, struct ie_generic *));
56 static int usf_enc_ie_cdsa __P((struct usfmt *, struct ie_generic *));
57 static int usf_enc_ie_cgad __P((struct usfmt *, struct ie_generic *));
58 static int usf_enc_ie_cgsa __P((struct usfmt *, struct ie_generic *));
59 static int usf_enc_ie_caus __P((struct usfmt *, struct ie_generic *));
60 static int usf_enc_ie_cnid __P((struct usfmt *, struct ie_generic *));
61 static int usf_enc_ie_qosp __P((struct usfmt *, struct ie_generic *));
62 static int usf_enc_ie_brpi __P((struct usfmt *, struct ie_generic *));
63 static int usf_enc_ie_rsti __P((struct usfmt *, struct ie_generic *));
64 static int usf_enc_ie_bsdc __P((struct usfmt *, struct ie_generic *));
65 static int usf_enc_ie_trnt __P((struct usfmt *, struct ie_generic *));
66 static int usf_enc_ie_uimp __P((struct usfmt *, struct ie_generic *));
67 static int usf_enc_ie_ident __P((struct usfmt *, struct ie_generic *,
68 struct ie_decode_tbl *));
69 static int usf_enc_atm_addr __P((struct usfmt *, Atm_addr *));
76 u_char ident; /* IE identifier */
77 int (*encode) __P((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(usf, msg)
127 struct unisig_msg *msg;
132 struct ie_generic *ie;
136 u_char sb[sizeof(short)];
139 ATM_DEBUG2("usf_enc_msg: usf=%p, msg=%p\n",
143 * Encode the protocol discriminator
145 c = UNI_MSG_DISC_Q93B;
146 rc = usf_byte(usf, &c);
151 * Encode the call reference length
154 rc = usf_byte(usf, &c);
159 * Encode the call reference
161 rc = usf_int3(usf, &msg->msg_call_ref);
166 * Encode the message type
168 rc = usf_byte(usf, &msg->msg_type);
173 * Encode the message type extension
175 c = ((msg->msg_type_flag & UNI_MSG_TYPE_FLAG_MASK) <<
176 UNI_MSG_TYPE_FLAG_SHIFT) +
177 (msg->msg_type_action & UNI_MSG_TYPE_ACT_MASK) +
179 rc = usf_byte(usf, &c);
184 * Save the location of the message length and encode a length
185 * of zero for now. We'll fix the length up at the end.
188 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-2], &lp0);
191 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-1], &lp1);
196 * Process information elements
199 for (i=0; i<UNI_MSG_IE_CNT; i++) {
200 ie = msg->msg_ie_vec[i];
202 rc = usf_enc_ie(usf, ie);
205 len += (ie->ie_length + UNI_IE_HDR_LEN);
211 * Fix the message length in the encoded message
213 su.s = htons((u_short)len);
214 *lp0 = su.sb[sizeof(short)-2];
215 *lp1 = su.sb[sizeof(short)-1];
222 * Encode an information element
225 * usf pointer to a UNISIG formatting structure
226 * msg pointer to a UNISIG message structure
227 * ie pointer to a generic IE structure
231 * errno error encountered
237 struct ie_generic *ie;
245 u_char sb[sizeof(short)];
248 ATM_DEBUG2("usf_enc_ie: usf=%p, ie=%p\n",
252 * Encode the IE identifier
254 rc = usf_byte(usf, &ie->ie_ident);
259 * Encode the extended type
261 c = ((ie->ie_coding & UNI_IE_CODE_MASK) << UNI_IE_CODE_SHIFT) +
262 ((ie->ie_flag & UNI_IE_FLAG_MASK) <<
264 (ie->ie_action & UNI_IE_ACT_MASK) +
266 rc = usf_byte(usf, &c);
271 * Mark the current location in the output stream. Encode a
272 * length of zero for now; we'll come back and fix it up at
276 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-2], &lp0);
279 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-1], &lp1);
284 * Look up the information element in the table
286 for (i=0; (ie->ie_ident != ie_table[i].ident) &&
287 (ie_table[i].encode != NULL); i++) {
289 if (ie_table[i].encode == NULL) {
297 * Process the IE by calling the function indicated
300 rc = ie_table[i].encode(usf, ie);
305 * Set the length in the output stream
307 su.s = htons((u_short)ie->ie_length);
308 *lp0 = su.sb[sizeof(short)-2];
309 *lp1 = su.sb[sizeof(short)-1];
316 * Encode an AAL parameters information element
319 * usf pointer to a unisig formatting structure
320 * ie pointer to an AAL parms IE structure
324 * errno error encountered
328 usf_enc_ie_aalp(usf, ie)
330 struct ie_generic *ie;
334 ATM_DEBUG2("usf_enc_ie_aalp: usf=%p, ie=%p\n",
340 * Encode the AAL type
342 if (ie->ie_aalp_aal_type == T_ATM_ABSENT)
344 rc = usf_byte(usf, &ie->ie_aalp_aal_type);
349 * Process based on AAL type
351 switch (ie->ie_aalp_aal_type) {
352 case UNI_IE_AALP_AT_AAL1:
353 rc = usf_enc_ie_ident(usf, ie, ie_aal1_tbl);
355 case UNI_IE_AALP_AT_AAL3:
356 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
357 rc = usf_enc_ie_ident(usf, ie, ie_aal4_tbl_30);
359 rc = usf_enc_ie_ident(usf, ie, ie_aal4_tbl_31);
361 case UNI_IE_AALP_AT_AAL5:
362 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
363 rc = usf_enc_ie_ident(usf, ie, ie_aal5_tbl_30);
365 rc = usf_enc_ie_ident(usf, ie, ie_aal5_tbl_31);
367 case UNI_IE_AALP_AT_AALU:
369 * Encode the user data
372 while (i < sizeof(ie->ie_aalp_user_info)) {
373 rc = usf_byte(usf, &ie->ie_aalp_user_info[i]);
390 * Encode a user cell rate information element
392 * This routine just encodes the parameters required for best
396 * usf pointer to a unisig formatting structure
397 * ie pointer to a cell rate IE structure
401 * errno error encountered
405 usf_enc_ie_clrt(usf, ie)
407 struct ie_generic *ie;
411 ATM_DEBUG2("usf_enc_ie_clrt: usf=%p, ie=%p\n",
416 * Encode Peak Cell Rate Forward CLP = 0 + 1
418 c = UNI_IE_CLRT_FWD_PEAK_01_ID;
419 rc = usf_byte(usf, &c);
422 rc = usf_int3(usf, &ie->ie_clrt_fwd_peak_01);
427 * Encode Peak Cell Rate Backward CLP = 0 + 1
429 c = UNI_IE_CLRT_BKWD_PEAK_01_ID;
430 rc = usf_byte(usf, &c);
433 rc = usf_int3(usf, &ie->ie_clrt_bkwd_peak_01);
438 * Encode Best Effort Flag
440 c = UNI_IE_CLRT_BEST_EFFORT_ID;
441 rc = usf_byte(usf, &c);
452 * Encode the user cell rate IE using the table
455 rc = usf_enc_ie_ident(usf, ie, ie_clrt_tbl);
462 * Encode a broadband bearer capability information element
465 * usf pointer to a unisig formatting structure
466 * ie pointer to a cell rate IE structure
470 * errno error encountered
474 usf_enc_ie_bbcp(usf, ie)
476 struct ie_generic *ie;
481 ATM_DEBUG2("usf_enc_ie_bbcp: usf=%p, ie=%p\n",
487 * Encode the broadband bearer class
489 if (ie->ie_bbcp_bearer_class == T_ATM_ABSENT)
491 c = ie->ie_bbcp_bearer_class & UNI_IE_BBCP_BC_MASK;
492 if (ie->ie_bbcp_bearer_class != UNI_IE_BBCP_BC_BCOB_X)
494 rc = usf_byte(usf, &c);
500 * If the broadband bearer class was X, the next
501 * byte has the traffic type and timing requirements
503 if (ie->ie_bbcp_bearer_class == UNI_IE_BBCP_BC_BCOB_X) {
504 c = ((ie->ie_bbcp_traffic_type & UNI_IE_BBCP_TT_MASK) <<
505 UNI_IE_BBCP_TT_SHIFT) +
506 (ie->ie_bbcp_timing_req &
507 UNI_IE_BBCP_TR_MASK) +
509 rc = usf_byte(usf, &c);
516 * Encode the clipping and user plane connection configuration
518 c = ((ie->ie_bbcp_clipping & UNI_IE_BBCP_SC_MASK) <<
519 UNI_IE_BBCP_SC_SHIFT) +
520 (ie->ie_bbcp_conn_config &
521 UNI_IE_BBCP_CC_MASK) +
523 rc = usf_byte(usf, &c);
533 * Encode a broadband high layer information element
536 * usf pointer to a unisig formatting structure
537 * ie pointer to a cell rate IE structure
541 * errno error encountered
545 usf_enc_ie_bhli(usf, ie)
547 struct ie_generic *ie;
552 ATM_DEBUG2("usf_enc_ie_bhli: usf=%p, ie=%p\n",
558 * Encode the high layer information type
560 if (ie->ie_bhli_type == T_ATM_ABSENT)
562 type = ie->ie_bhli_type | UNI_IE_EXT_BIT;
563 rc = usf_ext(usf, &type);
569 * What comes next depends on the type
571 switch (ie->ie_bhli_type) {
572 case UNI_IE_BHLI_TYPE_ISO:
573 case UNI_IE_BHLI_TYPE_USER:
575 * ISO or user-specified parameters -- take the
576 * length of information from the IE length
578 for (i=0; i<ie->ie_length-1; i++) {
579 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
585 case UNI_IE_BHLI_TYPE_HLP:
587 * Make sure the IE is long enough for the high
588 * layer profile information, then get it
590 if (usf->usf_sig->us_proto != ATM_SIG_UNI30)
592 for (i=0; i<UNI_IE_BHLI_HLP_LEN; i++) {
593 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
599 case UNI_IE_BHLI_TYPE_VSA:
601 * Make sure the IE is long enough for the vendor-
602 * specific application information, then get it
604 for (i=0; i<UNI_IE_BHLI_VSA_LEN; i++) {
605 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
620 * Encode a broadband low layer information element
623 * usf pointer to a unisig formatting structure
624 * ie pointer to a cell rate IE structure
628 * errno error encountered
632 usf_enc_ie_blli(usf, ie)
634 struct ie_generic *ie;
640 ATM_DEBUG2("usf_enc_ie_blli: usf=%p, ie=%p\n",
646 * Encode paramteters for whichever protocol layers the
651 * Layer 1 information
653 if (ie->ie_blli_l1_id && ie->ie_blli_l1_id != T_ATM_ABSENT) {
654 c = (UNI_IE_BLLI_L1_ID << UNI_IE_BLLI_LID_SHIFT) +
656 UNI_IE_BLLI_LP_MASK) +
658 rc = usf_byte(usf, &c);
665 * Layer 2 information
667 if (ie->ie_blli_l2_id && ie->ie_blli_l2_id != T_ATM_ABSENT) {
668 c = (UNI_IE_BLLI_L2_ID << UNI_IE_BLLI_LID_SHIFT) +
670 UNI_IE_BLLI_LP_MASK);
672 switch (ie->ie_blli_l2_id) {
673 case UNI_IE_BLLI_L2P_X25L:
674 case UNI_IE_BLLI_L2P_X25M:
675 case UNI_IE_BLLI_L2P_HDLC1:
676 case UNI_IE_BLLI_L2P_HDLC2:
677 case UNI_IE_BLLI_L2P_HDLC3:
678 case UNI_IE_BLLI_L2P_Q922:
679 case UNI_IE_BLLI_L2P_ISO7776:
681 * Write the Layer 2 type
683 rc = usf_byte(usf, &c);
689 * Encode the Layer 2 mode
691 if (ie->ie_blli_l2_mode) {
692 c = (ie->ie_blli_l2_mode &
693 UNI_IE_BLLI_L2MODE_MASK) <<
694 UNI_IE_BLLI_L2MODE_SHIFT;
695 if (!ie->ie_blli_l2_window)
698 rc = usf_byte(usf, &c);
705 * Encode the Layer 2 window size
707 if (ie->ie_blli_l2_window) {
708 c = (ie->ie_blli_l2_window &
712 rc = usf_byte(usf, &c);
718 case UNI_IE_BLLI_L2P_USER:
720 * Write the Layer 2 type
722 rc = usf_byte(usf, &c);
728 * Encode the user-specified layer 2 info
730 c = (ie->ie_blli_l2_user_proto &
733 rc = usf_byte(usf, &c);
740 * Write the Layer 2 type
743 rc = usf_byte(usf, &c);
752 * Layer 3 information
754 if (ie->ie_blli_l3_id && ie->ie_blli_l3_id != T_ATM_ABSENT) {
756 * Encode the layer 3 protocol ID
758 c = (UNI_IE_BLLI_L3_ID << UNI_IE_BLLI_LID_SHIFT) +
760 UNI_IE_BLLI_LP_MASK);
763 * Process other fields based on protocol ID
765 switch(ie->ie_blli_l3_id) {
766 case UNI_IE_BLLI_L3P_X25:
767 case UNI_IE_BLLI_L3P_ISO8208:
768 case UNI_IE_BLLI_L3P_ISO8878:
770 * Write the protocol ID
772 rc = usf_byte(usf, &c);
777 if (ie->ie_blli_l3_mode ||
778 ie->ie_blli_l3_packet_size ||
779 ie->ie_blli_l3_window) {
780 c = (ie->ie_blli_l3_mode &
781 UNI_IE_BLLI_L3MODE_MASK) <<
782 UNI_IE_BLLI_L3MODE_SHIFT;
783 if (!ie->ie_blli_l3_packet_size &&
784 !ie->ie_blli_l3_window)
787 rc = usf_byte(usf, &c);
793 if (ie->ie_blli_l3_packet_size ||
794 ie->ie_blli_l3_window) {
795 c = ie->ie_blli_l3_packet_size &
796 UNI_IE_BLLI_L3PS_MASK;
797 if (!ie->ie_blli_l3_window)
800 rc = usf_byte(usf, &c);
806 if (ie->ie_blli_l3_window) {
807 c = (ie->ie_blli_l3_window &
811 rc = usf_byte(usf, &c);
817 case UNI_IE_BLLI_L3P_USER:
819 * Write the protocol ID
821 rc = usf_byte(usf, &c);
827 * Encode the user-specified protocol info
829 c = (ie->ie_blli_l3_user_proto &
833 rc = usf_byte(usf, &c);
838 case UNI_IE_BLLI_L3P_ISO9577:
840 * Write the protocol ID
842 rc = usf_byte(usf, &c);
850 ipi = ie->ie_blli_l3_ipi <<
851 UNI_IE_BLLI_L3IPI_SHIFT;
852 rc = usf_ext(usf, &ipi);
857 if (ie->ie_blli_l3_ipi ==
858 UNI_IE_BLLI_L3IPI_SNAP) {
860 rc = usf_byte(usf, &c);
865 &ie->ie_blli_l3_oui[0]);
870 &ie->ie_blli_l3_oui[1]);
875 &ie->ie_blli_l3_oui[2]);
880 &ie->ie_blli_l3_pid[0]);
885 &ie->ie_blli_l3_pid[1]);
894 * Write the layer 3 protocol ID
897 rc = usf_byte(usf, &c);
910 * Encode a call state information element
913 * usf pointer to a unisig formatting structure
914 * ie pointer to a cell rate IE structure
918 * errno error encountered
922 usf_enc_ie_clst(usf, ie)
924 struct ie_generic *ie;
929 ATM_DEBUG2("usf_enc_ie_clst: usf=%p, ie=%p\n",
932 c = ie->ie_clst_state & UNI_IE_CLST_STATE_MASK;
933 rc = usf_byte(usf, &c);
943 * Encode a called party number information element
946 * usf pointer to a unisig formatting structure
947 * ie pointer to a cell rate IE structure
951 * errno error encountered
955 usf_enc_ie_cdad(usf, ie)
957 struct ie_generic *ie;
962 ATM_DEBUG2("usf_enc_ie_cdad: usf=%p, ie=%p\n",
966 * Encode the numbering plan
968 switch(ie->ie_cdad_addr.address_format) {
969 case T_ATM_E164_ADDR:
970 c = UNI_IE_CDAD_PLAN_E164 +
971 (UNI_IE_CDAD_TYPE_INTL
972 << UNI_IE_CDAD_TYPE_SHIFT);
973 ie->ie_length = sizeof(Atm_addr_e164) + 1;
975 case T_ATM_ENDSYS_ADDR:
976 c = UNI_IE_CDAD_PLAN_NSAP +
977 (UNI_IE_CDAD_TYPE_UNK
978 << UNI_IE_CDAD_TYPE_SHIFT);
979 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
985 rc = usf_byte(usf, &c);
990 * Encode the ATM address
992 rc = usf_enc_atm_addr(usf, &ie->ie_cdad_addr);
999 * Encode a called party subaddress information element
1002 * usf pointer to a unisig formatting structure
1003 * ie pointer to a cell rate IE structure
1007 * errno error encountered
1011 usf_enc_ie_cdsa(usf, ie)
1013 struct ie_generic *ie;
1019 * Encode the subaddress type
1021 switch(ie->ie_cdsa_addr.address_format) {
1022 case T_ATM_ENDSYS_ADDR:
1023 c = UNI_IE_CDSA_TYPE_AESA << UNI_IE_CDSA_TYPE_SHIFT;
1024 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1029 c |= UNI_IE_EXT_BIT;
1030 rc = usf_byte(usf, &c);
1035 * Encode the ATM address
1037 rc = usf_enc_atm_addr(usf, &ie->ie_cdsa_addr);
1044 * Encode a calling party number information element
1047 * usf pointer to a unisig formatting structure
1048 * ie pointer to a cell rate IE structure
1052 * errno error encountered
1056 usf_enc_ie_cgad(usf, ie)
1058 struct ie_generic *ie;
1063 ATM_DEBUG2("usf_enc_ie_cgad: usf=%p, ie=%p\n",
1067 * Encode the numbering plan
1069 switch(ie->ie_cgad_addr.address_format) {
1070 case T_ATM_E164_ADDR:
1071 c = UNI_IE_CGAD_PLAN_E164 +
1072 (UNI_IE_CGAD_TYPE_INTL
1073 << UNI_IE_CGAD_TYPE_SHIFT) +
1075 ie->ie_length = sizeof(Atm_addr_e164) + 1;
1077 case T_ATM_ENDSYS_ADDR:
1078 c = UNI_IE_CGAD_PLAN_NSAP +
1079 (UNI_IE_CGAD_TYPE_UNK
1080 << UNI_IE_CGAD_TYPE_SHIFT) +
1082 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1087 rc = usf_byte(usf, &c);
1092 * Encode the presentation and screening indicators
1095 c = ((ie->ie_cgad_pres_ind & UNI_IE_CGAD_PRES_MASK)
1096 << UNI_IE_CGAD_PRES_SHIFT) +
1097 (ie->ie_cgad_screen_ind &
1098 UNI_IE_CGAD_SCR_MASK) +
1100 rc = usf_byte(usf, &c);
1107 * Encode the ATM address
1109 rc = usf_enc_atm_addr(usf, &ie->ie_cgad_addr);
1116 * Encode a calling party subaddress information element
1119 * usf pointer to a unisig formatting structure
1120 * ie pointer to a cell rate IE structure
1124 * errno error encountered
1128 usf_enc_ie_cgsa(usf, ie)
1130 struct ie_generic *ie;
1136 * Encode the subaddress type
1138 switch(ie->ie_cgsa_addr.address_format) {
1139 case T_ATM_ENDSYS_ADDR:
1140 c = UNI_IE_CGSA_TYPE_AESA << UNI_IE_CGSA_TYPE_SHIFT;
1141 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1146 c |= UNI_IE_EXT_BIT;
1147 rc = usf_byte(usf, &c);
1152 * Encode the ATM address
1154 rc = usf_enc_atm_addr(usf, &ie->ie_cgsa_addr);
1161 * Encode a cause information element
1164 * usf pointer to a unisig formatting structure
1165 * ie pointer to a cell rate IE structure
1169 * errno error encountered
1173 usf_enc_ie_caus(usf, ie)
1175 struct ie_generic *ie;
1180 ATM_DEBUG2("usf_enc_ie_caus: usf=%p, ie=%p\n",
1186 * Encode the cause location
1188 c = (ie->ie_caus_loc & UNI_IE_CAUS_LOC_MASK) | UNI_IE_EXT_BIT;
1189 rc = usf_byte(usf, &c);
1195 * Encode the cause value
1197 c = ie->ie_caus_cause | UNI_IE_EXT_BIT;
1198 rc = usf_byte(usf, &c);
1204 * Encode any included diagnostics
1206 for (i = 0; i < ie->ie_caus_diag_len &&
1207 i < sizeof(ie->ie_caus_diagnostic);
1209 rc = usf_byte(usf, &ie->ie_caus_diagnostic[i]);
1220 * Encode a conection identifier information element
1223 * usf pointer to a unisig formatting structure
1224 * ie pointer to a cell rate IE structure
1228 * errno error encountered
1232 usf_enc_ie_cnid(usf, ie)
1234 struct ie_generic *ie;
1239 ATM_DEBUG2("usf_enc_ie_cnid: usf=%p, ie=%p\n",
1242 c = ((ie->ie_cnid_vp_sig & UNI_IE_CNID_VPSIG_MASK)
1243 << UNI_IE_CNID_VPSIG_SHIFT) +
1244 (ie->ie_cnid_pref_excl & UNI_IE_CNID_PREX_MASK) +
1246 rc = usf_byte(usf, &c);
1250 rc = usf_short(usf, &ie->ie_cnid_vpci);
1253 rc = usf_short(usf, &ie->ie_cnid_vci);
1263 * Encode a quality of service parameters information element
1266 * usf pointer to a unisig formatting structure
1267 * ie pointer to a cell rate IE structure
1271 * errno error encountered
1275 usf_enc_ie_qosp(usf, ie)
1277 struct ie_generic *ie;
1281 ATM_DEBUG2("usf_enc_ie_qosp: usf=%p, ie=%p\n",
1285 * Encode forward QoS class
1287 if (ie->ie_qosp_fwd_class == T_ATM_ABSENT ||
1288 ie->ie_qosp_bkwd_class == T_ATM_ABSENT)
1290 rc = usf_byte(usf, &ie->ie_qosp_fwd_class);
1295 * Encode backward QoS class
1297 rc = usf_byte(usf, &ie->ie_qosp_bkwd_class);
1305 * Encode a broadband repeat indicator information element
1308 * usf pointer to a unisig formatting structure
1309 * ie pointer to a cell rate IE structure
1313 * errno error encountered
1317 usf_enc_ie_brpi(usf, ie)
1319 struct ie_generic *ie;
1324 ATM_DEBUG2("usf_enc_ie_brpi: usf=%p, ie=%p\n",
1328 * Encode the repeat indicator
1330 c = ie->ie_brpi_ind + UNI_IE_EXT_BIT;
1331 rc = usf_byte(usf, &c);
1338 * Encode a restart indicator information element
1341 * usf pointer to a unisig formatting structure
1342 * ie pointer to a cell rate IE structure
1346 * errno error encountered
1350 usf_enc_ie_rsti(usf, ie)
1352 struct ie_generic *ie;
1357 ATM_DEBUG2("usf_enc_ie_rsti: usf=%p, ie=%p\n",
1361 * Encode the restart class
1363 c = (ie->ie_rsti_class & UNI_IE_RSTI_CLASS_MASK) |
1365 rc = usf_byte(usf, &c);
1373 * Encode a broadband sending complete information element
1376 * usf pointer to a unisig formatting structure
1377 * ie pointer to a broadband sending complete IE structure
1381 * errno error encountered
1385 usf_enc_ie_bsdc(usf, ie)
1387 struct ie_generic *ie;
1392 ATM_DEBUG2("usf_enc_ie_bsdc: usf=%p, ie=%p\n",
1396 * Encode the sending complete indicator
1398 c = UNI_IE_BSDC_IND | UNI_IE_EXT_BIT;
1399 rc = usf_byte(usf, &c);
1407 * Encode a transit network selection information element
1410 * usf pointer to a unisig formatting structure
1411 * ie pointer to a transit network selection rate IE structure
1415 * errno error encountered
1419 usf_enc_ie_trnt(usf, ie)
1421 struct ie_generic *ie;
1426 ATM_DEBUG2("usf_enc_ie_trnt: usf=%p, ie=%p\n",
1430 * Encode the sending complete indicator
1432 c = ((ie->ie_trnt_id_type & UNI_IE_TRNT_IDT_MASK) <<
1433 UNI_IE_TRNT_IDT_SHIFT) +
1434 (ie->ie_trnt_id_plan & UNI_IE_TRNT_IDP_MASK) +
1436 rc = usf_byte(usf, &c);
1442 * Encode the network identification
1444 for (i=0; i<ie->ie_trnt_id_len; i++) {
1445 rc = usf_byte(usf, &ie->ie_trnt_id[i]);
1456 * Encode an unsupported IE type
1459 * usf pointer to a unisig formatting structure
1460 * ie pointer to an IE structure
1467 usf_enc_ie_uimp(usf, ie)
1469 struct ie_generic *ie;
1476 * Encode an information element using field identifiers
1478 * The AAL parameters and ATM user cell rate IEs are formatted
1479 * with a one-byte identifier preceeding each field. The routine
1480 * encodes these IEs by using a table which relates the field
1481 * identifiers with the fields in the appropriate IE structure.
1484 * usf pointer to a unisig formatting structure
1485 * ie pointer to a cell rate IE structure
1486 * tbl pointer to an IE decoding table
1490 * errno error encountered
1494 usf_enc_ie_ident(usf, ie, tbl)
1496 struct ie_generic *ie;
1497 struct ie_decode_tbl *tbl;
1505 ATM_DEBUG3("usf_enc_ie_ident: usf=%p, ie=%p, tbl=%p\n",
1509 * Scan through the IE table
1512 for (i=0; tbl[i].ident; i++) {
1514 * Check whether to send the field
1516 cp = (char *) ((int)ie + tbl[i].f_offs);
1517 if (tbl[i].len == 0) {
1518 if ((*cp == T_NO || *cp == T_ATM_ABSENT))
1521 switch (tbl[i].f_size) {
1523 if (*(int8_t *)cp == T_ATM_ABSENT)
1527 if (*(int16_t *)cp == T_ATM_ABSENT)
1531 if (*(int32_t *)cp == T_ATM_ABSENT)
1537 "uni encode: id=%d,len=%d,off=%d,size=%d\n",
1538 tbl[i].ident, tbl[i].len,
1539 tbl[i].f_offs, tbl[i].f_size);
1545 * Encode the field identifier
1547 rc = usf_byte(usf, &tbl[i].ident);
1553 * Encode the field value
1555 switch (tbl[i].len) {
1559 switch (tbl[i].f_size) {
1561 cv = *(u_int8_t *)cp;
1564 cv = *(u_int16_t *)cp;
1567 cv = *(u_int32_t *)cp;
1572 rc = usf_byte(usf, &cv);
1576 switch (tbl[i].f_size) {
1578 sv = *(u_int16_t *)cp;
1581 sv = *(u_int32_t *)cp;
1586 rc = usf_short(usf, &sv);
1590 switch (tbl[i].f_size) {
1592 iv = *(u_int32_t *)cp;
1597 rc = usf_int3(usf, &iv);
1601 switch (tbl[i].f_size) {
1603 iv = *(u_int32_t *)cp;
1608 rc = usf_int(usf, &iv);
1621 ie->ie_length = len;
1627 * Encode an ATM address
1630 * usf pointer to a unisig formatting structure
1631 * addr pointer to an ATM address structure. The address
1632 * type must already be set correctly.
1636 * errno error encountered
1640 usf_enc_atm_addr(usf, addr)
1648 * Check the address type
1650 switch (addr->address_format) {
1651 case T_ATM_E164_ADDR:
1652 cp = (u_char *) addr->address;
1653 len = sizeof(Atm_addr_e164);
1655 case T_ATM_ENDSYS_ADDR:
1656 cp = (u_char *) addr->address;
1657 len = sizeof(Atm_addr_nsap);
1664 * Get the address bytes
1667 rc = usf_byte(usf, cp);