2 * ===================================
3 * HARP | Host ATM Research Platform
4 * ===================================
7 * This Host ATM Research Platform ("HARP") file (the "Software") is
8 * made available by Network Computing Services, Inc. ("NetworkCS")
9 * "AS IS". NetworkCS does not provide maintenance, improvements or
10 * support of any kind.
12 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16 * In no event shall NetworkCS be responsible for any damages, including
17 * but not limited to consequential damages, arising from or relating to
18 * any use of the Software or related support.
20 * Copyright 1994-1998 Network Computing Services, Inc.
22 * Copies of this Software may be made, however, the above copyright
23 * notice must be reproduced on all copies.
27 * ATM Forum UNI 3.0/3.1 Signalling Manager
28 * ----------------------------------------
30 * Message formatting module
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/errno.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/syslog.h>
45 #include <netatm/port.h>
46 #include <netatm/queue.h>
47 #include <netatm/atm.h>
48 #include <netatm/atm_sys.h>
49 #include <netatm/atm_sap.h>
50 #include <netatm/atm_cm.h>
51 #include <netatm/atm_if.h>
52 #include <netatm/atm_vc.h>
53 #include <netatm/atm_sigmgr.h>
54 #include <netatm/atm_stack.h>
55 #include <netatm/atm_pcb.h>
56 #include <netatm/atm_var.h>
58 #include <netatm/uni/unisig_var.h>
59 #include <netatm/uni/unisig_msg.h>
60 #include <netatm/uni/unisig_mbuf.h>
61 #include <netatm/uni/unisig_decode.h>
66 static int usf_enc_ie(struct usfmt *, struct ie_generic *);
67 static int usf_enc_ie_aalp(struct usfmt *, struct ie_generic *);
68 static int usf_enc_ie_clrt(struct usfmt *, struct ie_generic *);
69 static int usf_enc_ie_bbcp(struct usfmt *, struct ie_generic *);
70 static int usf_enc_ie_bhli(struct usfmt *, struct ie_generic *);
71 static int usf_enc_ie_blli(struct usfmt *, struct ie_generic *);
72 static int usf_enc_ie_clst(struct usfmt *, struct ie_generic *);
73 static int usf_enc_ie_cdad(struct usfmt *, struct ie_generic *);
74 static int usf_enc_ie_cdsa(struct usfmt *, struct ie_generic *);
75 static int usf_enc_ie_cgad(struct usfmt *, struct ie_generic *);
76 static int usf_enc_ie_cgsa(struct usfmt *, struct ie_generic *);
77 static int usf_enc_ie_caus(struct usfmt *, struct ie_generic *);
78 static int usf_enc_ie_cnid(struct usfmt *, struct ie_generic *);
79 static int usf_enc_ie_qosp(struct usfmt *, struct ie_generic *);
80 static int usf_enc_ie_brpi(struct usfmt *, struct ie_generic *);
81 static int usf_enc_ie_rsti(struct usfmt *, struct ie_generic *);
82 static int usf_enc_ie_bsdc(struct usfmt *, struct ie_generic *);
83 static int usf_enc_ie_trnt(struct usfmt *, struct ie_generic *);
84 static int usf_enc_ie_uimp(struct usfmt *, struct ie_generic *);
85 static int usf_enc_ie_ident(struct usfmt *, struct ie_generic *,
86 struct ie_decode_tbl *);
87 static int usf_enc_atm_addr(struct usfmt *, Atm_addr *);
94 u_char ident; /* IE identifier */
95 int (*encode)(struct usfmt *, struct ie_generic *);
96 /* Encoding function */
98 { UNI_IE_AALP, usf_enc_ie_aalp },
99 { UNI_IE_CLRT, usf_enc_ie_clrt },
100 { UNI_IE_BBCP, usf_enc_ie_bbcp },
101 { UNI_IE_BHLI, usf_enc_ie_bhli },
102 { UNI_IE_BLLI, usf_enc_ie_blli },
103 { UNI_IE_CLST, usf_enc_ie_clst },
104 { UNI_IE_CDAD, usf_enc_ie_cdad },
105 { UNI_IE_CDSA, usf_enc_ie_cdsa },
106 { UNI_IE_CGAD, usf_enc_ie_cgad },
107 { UNI_IE_CGSA, usf_enc_ie_cgsa },
108 { UNI_IE_CAUS, usf_enc_ie_caus },
109 { UNI_IE_CNID, usf_enc_ie_cnid },
110 { UNI_IE_QOSP, usf_enc_ie_qosp },
111 { UNI_IE_BRPI, usf_enc_ie_brpi },
112 { UNI_IE_RSTI, usf_enc_ie_rsti },
113 { UNI_IE_BLSH, usf_enc_ie_uimp },
114 { UNI_IE_BNSH, usf_enc_ie_uimp },
115 { UNI_IE_BSDC, usf_enc_ie_bsdc },
116 { UNI_IE_TRNT, usf_enc_ie_trnt },
117 { UNI_IE_EPRF, usf_enc_ie_uimp },
118 { UNI_IE_EPST, usf_enc_ie_uimp },
122 extern struct ie_decode_tbl ie_aal1_tbl[];
123 extern struct ie_decode_tbl ie_aal4_tbl_30[];
124 extern struct ie_decode_tbl ie_aal4_tbl_31[];
125 extern struct ie_decode_tbl ie_aal5_tbl_30[];
126 extern struct ie_decode_tbl ie_aal5_tbl_31[];
127 extern struct ie_decode_tbl ie_clrt_tbl[];
131 * Encode a UNI signalling message
134 * usf pointer to a unisig formatting structure
135 * msg pointer to a signalling message structure
139 * errno error encountered
143 usf_enc_msg(usf, msg)
145 struct unisig_msg *msg;
150 struct ie_generic *ie;
154 u_char sb[sizeof(short)];
157 ATM_DEBUG2("usf_enc_msg: usf=%p, msg=%p\n",
161 * Encode the protocol discriminator
163 c = UNI_MSG_DISC_Q93B;
164 rc = usf_byte(usf, &c);
169 * Encode the call reference length
172 rc = usf_byte(usf, &c);
177 * Encode the call reference
179 rc = usf_int3(usf, &msg->msg_call_ref);
184 * Encode the message type
186 rc = usf_byte(usf, &msg->msg_type);
191 * Encode the message type extension
193 c = ((msg->msg_type_flag & UNI_MSG_TYPE_FLAG_MASK) <<
194 UNI_MSG_TYPE_FLAG_SHIFT) +
195 (msg->msg_type_action & UNI_MSG_TYPE_ACT_MASK) +
197 rc = usf_byte(usf, &c);
202 * Save the location of the message length and encode a length
203 * of zero for now. We'll fix the length up at the end.
206 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-2], &lp0);
209 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-1], &lp1);
214 * Process information elements
217 for (i=0; i<UNI_MSG_IE_CNT; i++) {
218 ie = msg->msg_ie_vec[i];
220 rc = usf_enc_ie(usf, ie);
223 len += (ie->ie_length + UNI_IE_HDR_LEN);
229 * Fix the message length in the encoded message
231 su.s = htons((u_short)len);
232 *lp0 = su.sb[sizeof(short)-2];
233 *lp1 = su.sb[sizeof(short)-1];
240 * Encode an information element
243 * usf pointer to a UNISIG formatting structure
244 * msg pointer to a UNISIG message structure
245 * ie pointer to a generic IE structure
249 * errno error encountered
255 struct ie_generic *ie;
263 u_char sb[sizeof(short)];
266 ATM_DEBUG2("usf_enc_ie: usf=%p, ie=%p\n",
270 * Encode the IE identifier
272 rc = usf_byte(usf, &ie->ie_ident);
277 * Encode the extended type
279 c = ((ie->ie_coding & UNI_IE_CODE_MASK) << UNI_IE_CODE_SHIFT) +
280 ((ie->ie_flag & UNI_IE_FLAG_MASK) <<
282 (ie->ie_action & UNI_IE_ACT_MASK) +
284 rc = usf_byte(usf, &c);
289 * Mark the current location in the output stream. Encode a
290 * length of zero for now; we'll come back and fix it up at
294 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-2], &lp0);
297 rc = usf_byte_mark(usf, &su.sb[sizeof(short)-1], &lp1);
302 * Look up the information element in the table
304 for (i=0; (ie->ie_ident != ie_table[i].ident) &&
305 (ie_table[i].encode != NULL); i++) {
307 if (ie_table[i].encode == NULL) {
315 * Process the IE by calling the function indicated
318 rc = ie_table[i].encode(usf, ie);
323 * Set the length in the output stream
325 su.s = htons((u_short)ie->ie_length);
326 *lp0 = su.sb[sizeof(short)-2];
327 *lp1 = su.sb[sizeof(short)-1];
334 * Encode an AAL parameters information element
337 * usf pointer to a unisig formatting structure
338 * ie pointer to an AAL parms IE structure
342 * errno error encountered
346 usf_enc_ie_aalp(usf, ie)
348 struct ie_generic *ie;
352 ATM_DEBUG2("usf_enc_ie_aalp: usf=%p, ie=%p\n",
358 * Encode the AAL type
360 if (ie->ie_aalp_aal_type == T_ATM_ABSENT)
362 rc = usf_byte(usf, &ie->ie_aalp_aal_type);
367 * Process based on AAL type
369 switch (ie->ie_aalp_aal_type) {
370 case UNI_IE_AALP_AT_AAL1:
371 rc = usf_enc_ie_ident(usf, ie, ie_aal1_tbl);
373 case UNI_IE_AALP_AT_AAL3:
374 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
375 rc = usf_enc_ie_ident(usf, ie, ie_aal4_tbl_30);
377 rc = usf_enc_ie_ident(usf, ie, ie_aal4_tbl_31);
379 case UNI_IE_AALP_AT_AAL5:
380 if (usf->usf_sig->us_proto == ATM_SIG_UNI30)
381 rc = usf_enc_ie_ident(usf, ie, ie_aal5_tbl_30);
383 rc = usf_enc_ie_ident(usf, ie, ie_aal5_tbl_31);
385 case UNI_IE_AALP_AT_AALU:
387 * Encode the user data
390 while (i < sizeof(ie->ie_aalp_user_info)) {
391 rc = usf_byte(usf, &ie->ie_aalp_user_info[i]);
408 * Encode a user cell rate information element
410 * This routine just encodes the parameters required for best
414 * usf pointer to a unisig formatting structure
415 * ie pointer to a cell rate IE structure
419 * errno error encountered
423 usf_enc_ie_clrt(usf, ie)
425 struct ie_generic *ie;
429 ATM_DEBUG2("usf_enc_ie_clrt: usf=%p, ie=%p\n",
434 * Encode Peak Cell Rate Forward CLP = 0 + 1
436 c = UNI_IE_CLRT_FWD_PEAK_01_ID;
437 rc = usf_byte(usf, &c);
440 rc = usf_int3(usf, &ie->ie_clrt_fwd_peak_01);
445 * Encode Peak Cell Rate Backward CLP = 0 + 1
447 c = UNI_IE_CLRT_BKWD_PEAK_01_ID;
448 rc = usf_byte(usf, &c);
451 rc = usf_int3(usf, &ie->ie_clrt_bkwd_peak_01);
456 * Encode Best Effort Flag
458 c = UNI_IE_CLRT_BEST_EFFORT_ID;
459 rc = usf_byte(usf, &c);
470 * Encode the user cell rate IE using the table
473 rc = usf_enc_ie_ident(usf, ie, ie_clrt_tbl);
480 * Encode a broadband bearer capability information element
483 * usf pointer to a unisig formatting structure
484 * ie pointer to a cell rate IE structure
488 * errno error encountered
492 usf_enc_ie_bbcp(usf, ie)
494 struct ie_generic *ie;
499 ATM_DEBUG2("usf_enc_ie_bbcp: usf=%p, ie=%p\n",
505 * Encode the broadband bearer class
507 if (ie->ie_bbcp_bearer_class == T_ATM_ABSENT)
509 c = ie->ie_bbcp_bearer_class & UNI_IE_BBCP_BC_MASK;
510 if (ie->ie_bbcp_bearer_class != UNI_IE_BBCP_BC_BCOB_X)
512 rc = usf_byte(usf, &c);
518 * If the broadband bearer class was X, the next
519 * byte has the traffic type and timing requirements
521 if (ie->ie_bbcp_bearer_class == UNI_IE_BBCP_BC_BCOB_X) {
522 c = ((ie->ie_bbcp_traffic_type & UNI_IE_BBCP_TT_MASK) <<
523 UNI_IE_BBCP_TT_SHIFT) +
524 (ie->ie_bbcp_timing_req &
525 UNI_IE_BBCP_TR_MASK) +
527 rc = usf_byte(usf, &c);
534 * Encode the clipping and user plane connection configuration
536 c = ((ie->ie_bbcp_clipping & UNI_IE_BBCP_SC_MASK) <<
537 UNI_IE_BBCP_SC_SHIFT) +
538 (ie->ie_bbcp_conn_config &
539 UNI_IE_BBCP_CC_MASK) +
541 rc = usf_byte(usf, &c);
551 * Encode a broadband high layer information element
554 * usf pointer to a unisig formatting structure
555 * ie pointer to a cell rate IE structure
559 * errno error encountered
563 usf_enc_ie_bhli(usf, ie)
565 struct ie_generic *ie;
570 ATM_DEBUG2("usf_enc_ie_bhli: usf=%p, ie=%p\n",
576 * Encode the high layer information type
578 if (ie->ie_bhli_type == T_ATM_ABSENT)
580 type = ie->ie_bhli_type | UNI_IE_EXT_BIT;
581 rc = usf_ext(usf, &type);
587 * What comes next depends on the type
589 switch (ie->ie_bhli_type) {
590 case UNI_IE_BHLI_TYPE_ISO:
591 case UNI_IE_BHLI_TYPE_USER:
593 * ISO or user-specified parameters -- take the
594 * length of information from the IE length
596 for (i=0; i<ie->ie_length-1; i++) {
597 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
603 case UNI_IE_BHLI_TYPE_HLP:
605 * Make sure the IE is long enough for the high
606 * layer profile information, then get it
608 if (usf->usf_sig->us_proto != ATM_SIG_UNI30)
610 for (i=0; i<UNI_IE_BHLI_HLP_LEN; i++) {
611 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
617 case UNI_IE_BHLI_TYPE_VSA:
619 * Make sure the IE is long enough for the vendor-
620 * specific application information, then get it
622 for (i=0; i<UNI_IE_BHLI_VSA_LEN; i++) {
623 rc = usf_byte(usf, &ie->ie_bhli_info[i]);
638 * Encode a broadband low layer information element
641 * usf pointer to a unisig formatting structure
642 * ie pointer to a cell rate IE structure
646 * errno error encountered
650 usf_enc_ie_blli(usf, ie)
652 struct ie_generic *ie;
658 ATM_DEBUG2("usf_enc_ie_blli: usf=%p, ie=%p\n",
664 * Encode paramteters for whichever protocol layers the
669 * Layer 1 information
671 if (ie->ie_blli_l1_id && ie->ie_blli_l1_id != T_ATM_ABSENT) {
672 c = (UNI_IE_BLLI_L1_ID << UNI_IE_BLLI_LID_SHIFT) +
674 UNI_IE_BLLI_LP_MASK) +
676 rc = usf_byte(usf, &c);
683 * Layer 2 information
685 if (ie->ie_blli_l2_id && ie->ie_blli_l2_id != T_ATM_ABSENT) {
686 c = (UNI_IE_BLLI_L2_ID << UNI_IE_BLLI_LID_SHIFT) +
688 UNI_IE_BLLI_LP_MASK);
690 switch (ie->ie_blli_l2_id) {
691 case UNI_IE_BLLI_L2P_X25L:
692 case UNI_IE_BLLI_L2P_X25M:
693 case UNI_IE_BLLI_L2P_HDLC1:
694 case UNI_IE_BLLI_L2P_HDLC2:
695 case UNI_IE_BLLI_L2P_HDLC3:
696 case UNI_IE_BLLI_L2P_Q922:
697 case UNI_IE_BLLI_L2P_ISO7776:
699 * Write the Layer 2 type
701 rc = usf_byte(usf, &c);
707 * Encode the Layer 2 mode
709 if (ie->ie_blli_l2_mode) {
710 c = (ie->ie_blli_l2_mode &
711 UNI_IE_BLLI_L2MODE_MASK) <<
712 UNI_IE_BLLI_L2MODE_SHIFT;
713 if (!ie->ie_blli_l2_window)
716 rc = usf_byte(usf, &c);
723 * Encode the Layer 2 window size
725 if (ie->ie_blli_l2_window) {
726 c = (ie->ie_blli_l2_window &
730 rc = usf_byte(usf, &c);
736 case UNI_IE_BLLI_L2P_USER:
738 * Write the Layer 2 type
740 rc = usf_byte(usf, &c);
746 * Encode the user-specified layer 2 info
748 c = (ie->ie_blli_l2_user_proto &
751 rc = usf_byte(usf, &c);
758 * Write the Layer 2 type
761 rc = usf_byte(usf, &c);
770 * Layer 3 information
772 if (ie->ie_blli_l3_id && ie->ie_blli_l3_id != T_ATM_ABSENT) {
774 * Encode the layer 3 protocol ID
776 c = (UNI_IE_BLLI_L3_ID << UNI_IE_BLLI_LID_SHIFT) +
778 UNI_IE_BLLI_LP_MASK);
781 * Process other fields based on protocol ID
783 switch(ie->ie_blli_l3_id) {
784 case UNI_IE_BLLI_L3P_X25:
785 case UNI_IE_BLLI_L3P_ISO8208:
786 case UNI_IE_BLLI_L3P_ISO8878:
788 * Write the protocol ID
790 rc = usf_byte(usf, &c);
795 if (ie->ie_blli_l3_mode ||
796 ie->ie_blli_l3_packet_size ||
797 ie->ie_blli_l3_window) {
798 c = (ie->ie_blli_l3_mode &
799 UNI_IE_BLLI_L3MODE_MASK) <<
800 UNI_IE_BLLI_L3MODE_SHIFT;
801 if (!ie->ie_blli_l3_packet_size &&
802 !ie->ie_blli_l3_window)
805 rc = usf_byte(usf, &c);
811 if (ie->ie_blli_l3_packet_size ||
812 ie->ie_blli_l3_window) {
813 c = ie->ie_blli_l3_packet_size &
814 UNI_IE_BLLI_L3PS_MASK;
815 if (!ie->ie_blli_l3_window)
818 rc = usf_byte(usf, &c);
824 if (ie->ie_blli_l3_window) {
825 c = (ie->ie_blli_l3_window &
829 rc = usf_byte(usf, &c);
835 case UNI_IE_BLLI_L3P_USER:
837 * Write the protocol ID
839 rc = usf_byte(usf, &c);
845 * Encode the user-specified protocol info
847 c = (ie->ie_blli_l3_user_proto &
851 rc = usf_byte(usf, &c);
856 case UNI_IE_BLLI_L3P_ISO9577:
858 * Write the protocol ID
860 rc = usf_byte(usf, &c);
868 ipi = ie->ie_blli_l3_ipi <<
869 UNI_IE_BLLI_L3IPI_SHIFT;
870 rc = usf_ext(usf, &ipi);
875 if (ie->ie_blli_l3_ipi ==
876 UNI_IE_BLLI_L3IPI_SNAP) {
878 rc = usf_byte(usf, &c);
883 &ie->ie_blli_l3_oui[0]);
888 &ie->ie_blli_l3_oui[1]);
893 &ie->ie_blli_l3_oui[2]);
898 &ie->ie_blli_l3_pid[0]);
903 &ie->ie_blli_l3_pid[1]);
912 * Write the layer 3 protocol ID
915 rc = usf_byte(usf, &c);
928 * Encode a call state information element
931 * usf pointer to a unisig formatting structure
932 * ie pointer to a cell rate IE structure
936 * errno error encountered
940 usf_enc_ie_clst(usf, ie)
942 struct ie_generic *ie;
947 ATM_DEBUG2("usf_enc_ie_clst: usf=%p, ie=%p\n",
950 c = ie->ie_clst_state & UNI_IE_CLST_STATE_MASK;
951 rc = usf_byte(usf, &c);
961 * Encode a called party number information element
964 * usf pointer to a unisig formatting structure
965 * ie pointer to a cell rate IE structure
969 * errno error encountered
973 usf_enc_ie_cdad(usf, ie)
975 struct ie_generic *ie;
980 ATM_DEBUG2("usf_enc_ie_cdad: usf=%p, ie=%p\n",
984 * Encode the numbering plan
986 switch(ie->ie_cdad_addr.address_format) {
987 case T_ATM_E164_ADDR:
988 c = UNI_IE_CDAD_PLAN_E164 +
989 (UNI_IE_CDAD_TYPE_INTL
990 << UNI_IE_CDAD_TYPE_SHIFT);
991 ie->ie_length = sizeof(Atm_addr_e164) + 1;
993 case T_ATM_ENDSYS_ADDR:
994 c = UNI_IE_CDAD_PLAN_NSAP +
995 (UNI_IE_CDAD_TYPE_UNK
996 << UNI_IE_CDAD_TYPE_SHIFT);
997 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1002 c |= UNI_IE_EXT_BIT;
1003 rc = usf_byte(usf, &c);
1008 * Encode the ATM address
1010 rc = usf_enc_atm_addr(usf, &ie->ie_cdad_addr);
1017 * Encode a called party subaddress information element
1020 * usf pointer to a unisig formatting structure
1021 * ie pointer to a cell rate IE structure
1025 * errno error encountered
1029 usf_enc_ie_cdsa(usf, ie)
1031 struct ie_generic *ie;
1037 * Encode the subaddress type
1039 switch(ie->ie_cdsa_addr.address_format) {
1040 case T_ATM_ENDSYS_ADDR:
1041 c = UNI_IE_CDSA_TYPE_AESA << UNI_IE_CDSA_TYPE_SHIFT;
1042 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1047 c |= UNI_IE_EXT_BIT;
1048 rc = usf_byte(usf, &c);
1053 * Encode the ATM address
1055 rc = usf_enc_atm_addr(usf, &ie->ie_cdsa_addr);
1062 * Encode a calling party number information element
1065 * usf pointer to a unisig formatting structure
1066 * ie pointer to a cell rate IE structure
1070 * errno error encountered
1074 usf_enc_ie_cgad(usf, ie)
1076 struct ie_generic *ie;
1081 ATM_DEBUG2("usf_enc_ie_cgad: usf=%p, ie=%p\n",
1085 * Encode the numbering plan
1087 switch(ie->ie_cgad_addr.address_format) {
1088 case T_ATM_E164_ADDR:
1089 c = UNI_IE_CGAD_PLAN_E164 +
1090 (UNI_IE_CGAD_TYPE_INTL
1091 << UNI_IE_CGAD_TYPE_SHIFT) +
1093 ie->ie_length = sizeof(Atm_addr_e164) + 1;
1095 case T_ATM_ENDSYS_ADDR:
1096 c = UNI_IE_CGAD_PLAN_NSAP +
1097 (UNI_IE_CGAD_TYPE_UNK
1098 << UNI_IE_CGAD_TYPE_SHIFT) +
1100 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1105 rc = usf_byte(usf, &c);
1110 * Encode the presentation and screening indicators
1113 c = ((ie->ie_cgad_pres_ind & UNI_IE_CGAD_PRES_MASK)
1114 << UNI_IE_CGAD_PRES_SHIFT) +
1115 (ie->ie_cgad_screen_ind &
1116 UNI_IE_CGAD_SCR_MASK) +
1118 rc = usf_byte(usf, &c);
1125 * Encode the ATM address
1127 rc = usf_enc_atm_addr(usf, &ie->ie_cgad_addr);
1134 * Encode a calling party subaddress information element
1137 * usf pointer to a unisig formatting structure
1138 * ie pointer to a cell rate IE structure
1142 * errno error encountered
1146 usf_enc_ie_cgsa(usf, ie)
1148 struct ie_generic *ie;
1154 * Encode the subaddress type
1156 switch(ie->ie_cgsa_addr.address_format) {
1157 case T_ATM_ENDSYS_ADDR:
1158 c = UNI_IE_CGSA_TYPE_AESA << UNI_IE_CGSA_TYPE_SHIFT;
1159 ie->ie_length = sizeof(Atm_addr_nsap) + 1;
1164 c |= UNI_IE_EXT_BIT;
1165 rc = usf_byte(usf, &c);
1170 * Encode the ATM address
1172 rc = usf_enc_atm_addr(usf, &ie->ie_cgsa_addr);
1179 * Encode a cause information element
1182 * usf pointer to a unisig formatting structure
1183 * ie pointer to a cell rate IE structure
1187 * errno error encountered
1191 usf_enc_ie_caus(usf, ie)
1193 struct ie_generic *ie;
1198 ATM_DEBUG2("usf_enc_ie_caus: usf=%p, ie=%p\n",
1204 * Encode the cause location
1206 c = (ie->ie_caus_loc & UNI_IE_CAUS_LOC_MASK) | UNI_IE_EXT_BIT;
1207 rc = usf_byte(usf, &c);
1213 * Encode the cause value
1215 c = ie->ie_caus_cause | UNI_IE_EXT_BIT;
1216 rc = usf_byte(usf, &c);
1222 * Encode any included diagnostics
1224 for (i = 0; i < ie->ie_caus_diag_len &&
1225 i < sizeof(ie->ie_caus_diagnostic);
1227 rc = usf_byte(usf, &ie->ie_caus_diagnostic[i]);
1238 * Encode a conection identifier information element
1241 * usf pointer to a unisig formatting structure
1242 * ie pointer to a cell rate IE structure
1246 * errno error encountered
1250 usf_enc_ie_cnid(usf, ie)
1252 struct ie_generic *ie;
1257 ATM_DEBUG2("usf_enc_ie_cnid: usf=%p, ie=%p\n",
1260 c = ((ie->ie_cnid_vp_sig & UNI_IE_CNID_VPSIG_MASK)
1261 << UNI_IE_CNID_VPSIG_SHIFT) +
1262 (ie->ie_cnid_pref_excl & UNI_IE_CNID_PREX_MASK) +
1264 rc = usf_byte(usf, &c);
1268 rc = usf_short(usf, &ie->ie_cnid_vpci);
1271 rc = usf_short(usf, &ie->ie_cnid_vci);
1281 * Encode a quality of service parameters information element
1284 * usf pointer to a unisig formatting structure
1285 * ie pointer to a cell rate IE structure
1289 * errno error encountered
1293 usf_enc_ie_qosp(usf, ie)
1295 struct ie_generic *ie;
1299 ATM_DEBUG2("usf_enc_ie_qosp: usf=%p, ie=%p\n",
1303 * Encode forward QoS class
1305 if (ie->ie_qosp_fwd_class == T_ATM_ABSENT ||
1306 ie->ie_qosp_bkwd_class == T_ATM_ABSENT)
1308 rc = usf_byte(usf, &ie->ie_qosp_fwd_class);
1313 * Encode backward QoS class
1315 rc = usf_byte(usf, &ie->ie_qosp_bkwd_class);
1323 * Encode a broadband repeat indicator information element
1326 * usf pointer to a unisig formatting structure
1327 * ie pointer to a cell rate IE structure
1331 * errno error encountered
1335 usf_enc_ie_brpi(usf, ie)
1337 struct ie_generic *ie;
1342 ATM_DEBUG2("usf_enc_ie_brpi: usf=%p, ie=%p\n",
1346 * Encode the repeat indicator
1348 c = ie->ie_brpi_ind + UNI_IE_EXT_BIT;
1349 rc = usf_byte(usf, &c);
1356 * Encode a restart indicator information element
1359 * usf pointer to a unisig formatting structure
1360 * ie pointer to a cell rate IE structure
1364 * errno error encountered
1368 usf_enc_ie_rsti(usf, ie)
1370 struct ie_generic *ie;
1375 ATM_DEBUG2("usf_enc_ie_rsti: usf=%p, ie=%p\n",
1379 * Encode the restart class
1381 c = (ie->ie_rsti_class & UNI_IE_RSTI_CLASS_MASK) |
1383 rc = usf_byte(usf, &c);
1391 * Encode a broadband sending complete information element
1394 * usf pointer to a unisig formatting structure
1395 * ie pointer to a broadband sending complete IE structure
1399 * errno error encountered
1403 usf_enc_ie_bsdc(usf, ie)
1405 struct ie_generic *ie;
1410 ATM_DEBUG2("usf_enc_ie_bsdc: usf=%p, ie=%p\n",
1414 * Encode the sending complete indicator
1416 c = UNI_IE_BSDC_IND | UNI_IE_EXT_BIT;
1417 rc = usf_byte(usf, &c);
1425 * Encode a transit network selection information element
1428 * usf pointer to a unisig formatting structure
1429 * ie pointer to a transit network selection rate IE structure
1433 * errno error encountered
1437 usf_enc_ie_trnt(usf, ie)
1439 struct ie_generic *ie;
1444 ATM_DEBUG2("usf_enc_ie_trnt: usf=%p, ie=%p\n",
1448 * Encode the sending complete indicator
1450 c = ((ie->ie_trnt_id_type & UNI_IE_TRNT_IDT_MASK) <<
1451 UNI_IE_TRNT_IDT_SHIFT) +
1452 (ie->ie_trnt_id_plan & UNI_IE_TRNT_IDP_MASK) +
1454 rc = usf_byte(usf, &c);
1460 * Encode the network identification
1462 for (i=0; i<ie->ie_trnt_id_len; i++) {
1463 rc = usf_byte(usf, &ie->ie_trnt_id[i]);
1474 * Encode an unsupported IE type
1477 * usf pointer to a unisig formatting structure
1478 * ie pointer to an IE structure
1485 usf_enc_ie_uimp(usf, ie)
1487 struct ie_generic *ie;
1494 * Encode an information element using field identifiers
1496 * The AAL parameters and ATM user cell rate IEs are formatted
1497 * with a one-byte identifier preceding each field. The routine
1498 * encodes these IEs by using a table which relates the field
1499 * identifiers with the fields in the appropriate IE structure.
1502 * usf pointer to a unisig formatting structure
1503 * ie pointer to a cell rate IE structure
1504 * tbl pointer to an IE decoding table
1508 * errno error encountered
1512 usf_enc_ie_ident(usf, ie, tbl)
1514 struct ie_generic *ie;
1515 struct ie_decode_tbl *tbl;
1523 ATM_DEBUG3("usf_enc_ie_ident: usf=%p, ie=%p, tbl=%p\n",
1527 * Scan through the IE table
1530 for (i=0; tbl[i].ident; i++) {
1532 * Check whether to send the field
1534 cp = (char *) ((intptr_t)ie + tbl[i].f_offs);
1535 if (tbl[i].len == 0) {
1536 if ((*cp == T_NO || *(int8_t *)cp == T_ATM_ABSENT))
1539 switch (tbl[i].f_size) {
1541 if (*(int8_t *)cp == T_ATM_ABSENT)
1545 if (*(int16_t *)cp == T_ATM_ABSENT)
1549 if (*(int32_t *)cp == T_ATM_ABSENT)
1555 "uni encode: id=%d,len=%d,off=%d,size=%d\n",
1556 tbl[i].ident, tbl[i].len,
1557 tbl[i].f_offs, tbl[i].f_size);
1563 * Encode the field identifier
1565 rc = usf_byte(usf, &tbl[i].ident);
1571 * Encode the field value
1573 switch (tbl[i].len) {
1577 switch (tbl[i].f_size) {
1579 cv = *(u_int8_t *)cp;
1582 cv = *(u_int16_t *)cp;
1585 cv = *(u_int32_t *)cp;
1590 rc = usf_byte(usf, &cv);
1594 switch (tbl[i].f_size) {
1596 sv = *(u_int16_t *)cp;
1599 sv = *(u_int32_t *)cp;
1604 rc = usf_short(usf, &sv);
1608 switch (tbl[i].f_size) {
1610 iv = *(u_int32_t *)cp;
1615 rc = usf_int3(usf, &iv);
1619 switch (tbl[i].f_size) {
1621 iv = *(u_int32_t *)cp;
1626 rc = usf_int(usf, &iv);
1639 ie->ie_length = len;
1645 * Encode an ATM address
1648 * usf pointer to a unisig formatting structure
1649 * addr pointer to an ATM address structure. The address
1650 * type must already be set correctly.
1654 * errno error encountered
1658 usf_enc_atm_addr(usf, addr)
1666 * Check the address type
1668 switch (addr->address_format) {
1669 case T_ATM_E164_ADDR:
1670 cp = (u_char *) addr->address;
1671 len = sizeof(Atm_addr_e164);
1673 case T_ATM_ENDSYS_ADDR:
1674 cp = (u_char *) addr->address;
1675 len = sizeof(Atm_addr_nsap);
1682 * Get the address bytes
1685 rc = usf_byte(usf, cp);