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);