Pre-2.0 release: Sync with HAMMER 65 - simplify PFS operations.
[dragonfly.git] / sys / netproto / atm / uni / unisig_subr.c
blob45823932f8ad92ca9ba20c5f78b7274102e1ea76
1 /*
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_subr.c,v 1.7 2000/01/17 20:49:58 mks Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/unisig_subr.c,v 1.6 2006/01/14 13:36:39 swildner Exp $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
34 * Subroutines
38 #include <netproto/atm/kern_include.h>
40 #include "unisig_var.h"
41 #include "unisig_msg.h"
44 * External variables
46 extern struct ie_aalp ie_aalp_absent;
47 extern struct ie_clrt ie_clrt_absent;
48 extern struct ie_bbcp ie_bbcp_absent;
49 extern struct ie_bhli ie_bhli_absent;
50 extern struct ie_blli ie_blli_absent;
51 extern struct ie_clst ie_clst_absent;
52 extern struct ie_cdad ie_cdad_absent;
53 extern struct ie_cdsa ie_cdsa_absent;
54 extern struct ie_cgad ie_cgad_absent;
55 extern struct ie_cgsa ie_cgsa_absent;
56 extern struct ie_caus ie_caus_absent;
57 extern struct ie_cnid ie_cnid_absent;
58 extern struct ie_qosp ie_qosp_absent;
59 extern struct ie_brpi ie_brpi_absent;
60 extern struct ie_rsti ie_rsti_absent;
61 extern struct ie_blsh ie_blsh_absent;
62 extern struct ie_bnsh ie_bnsh_absent;
63 extern struct ie_bsdc ie_bsdc_absent;
64 extern struct ie_trnt ie_trnt_absent;
65 extern struct ie_eprf ie_eprf_absent;
66 extern struct ie_epst ie_epst_absent;
70 * Set a User Location cause code in an ATM attribute block
72 * Arguments:
73 * aap pointer to attribute block
74 * cause cause code
76 * Returns:
77 * none
80 void
81 unisig_cause_attr_from_user(Atm_attributes *aap, int cause)
83 if (cause == T_ATM_ABSENT)
84 return;
87 * Set the fields in the attribute block
89 aap->cause.tag = T_ATM_PRESENT;
90 aap->cause.v.coding_standard = T_ATM_ITU_CODING;
91 aap->cause.v.location = T_ATM_LOC_USER;
92 aap->cause.v.cause_value = cause;
93 KM_ZERO(aap->cause.v.diagnostics,
94 sizeof(aap->cause.v.diagnostics));
99 * Set a cause code in an ATM attribute block from a Cause IE
101 * Arguments:
102 * aap pointer to attribute block
103 * iep pointer to Cause IE
105 * Returns:
106 * none
109 void
110 unisig_cause_attr_from_ie(Atm_attributes *aap, struct ie_generic *iep)
113 * Set the fields in the attribute block
115 aap->cause.tag = T_ATM_PRESENT;
116 aap->cause.v.coding_standard = iep->ie_coding;
117 aap->cause.v.location = iep->ie_caus_loc;
118 aap->cause.v.cause_value = iep->ie_caus_cause;
119 KM_ZERO(aap->cause.v.diagnostics, sizeof(aap->cause.v.diagnostics));
120 KM_COPY(iep->ie_caus_diagnostic, aap->cause.v.diagnostics,
121 MIN(sizeof(aap->cause.v.diagnostics), iep->ie_caus_diag_len));
126 * Open a UNI VCC
128 * Called when a user wants to open a VC. This function will construct
129 * a VCCB and, if we are opening an SVC, call the Q.2931 VC state
130 * machine. The user will have to wait for a notify event to be sure
131 * the SVC is fully open.
133 * Must be called from a critical section.
135 * Arguments:
136 * usp pointer to UNISIG protocol instance
137 * cvp pointer to connection parameters for the VCC
139 * Returns:
140 * 0 VCC creation successful
141 * errno VCC setup failed - reason indicated
145 unisig_open_vcc(struct unisig *usp, Atm_connvc *cvp)
147 struct atm_pif *pip = usp->us_pif;
148 struct unisig_vccb *uvp;
149 Atm_addr_pvc *pvp;
150 int err, pvc;
152 ATM_DEBUG2("unisig_open_vcc: usp=%p, cvp=%p\n", usp, cvp);
155 * Validate user parameters. AAL and encapsulation are
156 * checked by the connection manager
160 * Check called party address(es)
162 if(cvp->cvc_attr.called.tag != T_ATM_PRESENT ||
163 cvp->cvc_attr.called.addr.address_format ==
164 T_ATM_ABSENT) {
165 return(EINVAL);
167 switch (cvp->cvc_attr.called.addr.address_format) {
168 case T_ATM_PVC_ADDR:
170 * Make sure VPI/VCI is valid
172 pvc = 1;
173 pvp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
174 if ((ATM_PVC_GET_VPI(pvp) > pip->pif_maxvpi) ||
175 (ATM_PVC_GET_VCI(pvp) == 0) ||
176 (ATM_PVC_GET_VCI(pvp) > pip->pif_maxvci)) {
177 return(ERANGE);
181 * Make sure VPI/VCI is not already in use
183 if (unisig_find_vpvc(usp,
184 ATM_PVC_GET_VPI(pvp),
185 ATM_PVC_GET_VCI(pvp), 0)) {
186 return(EEXIST);
188 ATM_DEBUG2("unisig_open_vcc: VPI.VCI=%d.%d\n",
189 ATM_PVC_GET_VPI(pvp),
190 ATM_PVC_GET_VCI(pvp));
191 break;
193 case T_ATM_ENDSYS_ADDR:
195 * Check signalling state
197 pvc = 0;
198 pvp = NULL;
199 if (usp->us_state != UNISIG_ACTIVE) {
200 return(ENETDOWN);
204 * Make sure there's no subaddress
206 if (cvp->cvc_attr.called.subaddr.address_format !=
207 T_ATM_ABSENT) {
208 return(EINVAL);
210 break;
212 case T_ATM_E164_ADDR:
214 * Check signalling state
216 pvc = 0;
217 pvp = NULL;
218 if (usp->us_state != UNISIG_ACTIVE) {
219 return(ENETDOWN);
223 * Check destination address format
225 if (cvp->cvc_attr.called.subaddr.address_format !=
226 T_ATM_ENDSYS_ADDR &&
227 cvp->cvc_attr.called.subaddr.address_format !=
228 T_ATM_ABSENT) {
229 return(EINVAL);
231 break;
233 default:
234 return(EPROTONOSUPPORT);
238 * Check that this is for the same interface UNISIG uses
240 if (!cvp->cvc_attr.nif ||
241 cvp->cvc_attr.nif->nif_pif != usp->us_pif) {
242 return(EINVAL);
246 * Allocate control block for VCC
248 uvp = (struct unisig_vccb *)atm_allocate(&unisig_vcpool);
249 if (uvp == NULL) {
250 return(ENOMEM);
254 * Fill in VCCB
256 if (pvc) {
257 uvp->uv_type = VCC_PVC | VCC_IN | VCC_OUT;
258 uvp->uv_vpi = ATM_PVC_GET_VPI(pvp);
259 uvp->uv_vci = ATM_PVC_GET_VCI(pvp);
260 uvp->uv_sstate = (usp->us_state == UNISIG_ACTIVE ?
261 UNI_PVC_ACTIVE : UNI_PVC_ACT_DOWN);
262 uvp->uv_ustate = VCCU_OPEN;
263 } else {
264 uvp->uv_type = VCC_SVC | VCC_IN | VCC_OUT;
265 uvp->uv_sstate = UNI_NULL;
266 uvp->uv_ustate = VCCU_POPEN;
268 uvp->uv_proto = usp->us_pif->pif_sigmgr->sm_proto;
269 uvp->uv_pif = usp->us_pif;
270 uvp->uv_nif = cvp->cvc_attr.nif;
271 uvp->uv_connvc = cvp;
272 uvp->uv_tstamp = time_second;
275 * Put VCCB on UNISIG queue
277 ENQUEUE(uvp, struct unisig_vccb, uv_sigelem, usp->us_vccq);
280 * Call the VC state machine if this is an SVC
282 if (!pvc) {
283 err = unisig_vc_state(usp, uvp, UNI_VC_SETUP_CALL,
284 (struct unisig_msg *) 0);
285 if (err) {
287 * On error, delete the VCCB
289 DEQUEUE(uvp, struct unisig_vccb, uv_sigelem,
290 usp->us_vccq);
291 atm_free((caddr_t)uvp);
292 return(err);
297 * Link VCCB to VCC connection block
299 cvp->cvc_vcc = (struct vccb *) uvp;
301 return(0);
306 * Close a UNISIG VCC
308 * Called when a user wants to close a VCC. This function will clean
309 * up the VCCB and, for an SVC, send a close request.
311 * Must be called from a critical section.
313 * Arguments:
314 * usp pointer to UNISIG protocol instance
315 * uvp pointer to VCCB for the VCC to be closed
317 * Returns:
318 * 0 VCC is now closed
319 * errno error encountered
322 unisig_close_vcc(struct unisig *usp, struct unisig_vccb *uvp)
324 int err = 0;
326 ATM_DEBUG2("unisig_close_vcc: uvp=%p, state=%d\n", uvp,
327 uvp->uv_sstate);
330 * Check that this is for the same interface UNISIG uses
332 if (uvp->uv_pif != usp->us_pif) {
333 return (EINVAL);
337 * Mark the close time.
339 uvp->uv_tstamp = time_second;
342 * Process based on the connection type
344 if (uvp->uv_type & VCC_PVC) {
345 uvp->uv_sstate = UNI_FREE;
346 uvp->uv_ustate = VCCU_CLOSED;
347 } else if (uvp->uv_type & VCC_SVC) {
349 * Call the VC state machine
351 uvp->uv_ustate = VCCU_CLOSED;
352 err = unisig_vc_state(usp, uvp, UNI_VC_RELEASE_CALL,
353 (struct unisig_msg *) 0);
357 * Wait for user to free resources
359 return(err);
364 * Clear a UNISIG VCC
366 * Called to internally clear a VCC. No external protocol is
367 * initiated, the VCC is just closed and the owner is notified.
369 * Must be called from a critical section.
371 * Arguments:
372 * usp pointer to UNISIG protocol instance
373 * uvp pointer to VCCB for the VCC to be closed
374 * cause cause code giving the reason for the close
376 * Returns:
377 * 0 VCC is closed
378 * errno error encountered
381 unisig_clear_vcc(struct unisig *usp, struct unisig_vccb *uvp, int cause)
383 u_char outstate;
385 ATM_DEBUG3("unisig_clear_vcc: uvp=%p, state=%d, cause=%d\n",
386 uvp, uvp->uv_sstate, cause);
389 * Check that this is for the same interface UNISIG uses
391 if (uvp->uv_pif != usp->us_pif) {
392 return (EINVAL);
396 * Kill any possible timer
398 UNISIG_VC_CANCEL((struct vccb *) uvp);
401 * Mark the close time.
403 uvp->uv_tstamp = time_second;
406 * Close the VCC and notify the user
408 outstate = uvp->uv_sstate;
409 uvp->uv_sstate = UNI_FREE;
410 uvp->uv_ustate = VCCU_CLOSED;
411 if (outstate == UNI_ACTIVE ||
412 outstate == UNI_CALL_INITIATED ||
413 outstate == UNI_CALL_OUT_PROC ||
414 outstate == UNI_CONNECT_REQUEST ||
415 outstate == UNI_RELEASE_REQUEST ||
416 outstate == UNI_RELEASE_IND ||
417 outstate == UNI_SSCF_RECOV ||
418 outstate == UNI_PVC_ACT_DOWN ||
419 outstate == UNI_PVC_ACTIVE) {
420 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr, cause);
421 atm_cm_cleared(uvp->uv_connvc);
425 * Wait for user to free resources
427 return(0);
431 #ifdef NOTDEF
433 * Reset the switch state
435 * Arguments:
436 * usp pointer to UNISIG protocol instance
438 * Returns:
439 * none
442 void
443 unisig_switch_reset(struct unisig *usp, int cause)
445 struct unisig_vccb *uvp, *vnext;
447 ATM_DEBUG2("unisig_switch_reset: usp=%p, cause=%d\n",
448 usp, cause);
451 * Terminate all of our VCCs
453 crit_enter();
454 for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp;
455 uvp = vnext) {
456 vnext = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem);
458 if (uvp->uv_type & VCC_SVC) {
460 * Close the SVC and notify the owner
462 unisig_clear_vcc(usp, uvp,
463 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
464 } else if (uvp->uv_type & VCC_PVC) {
466 * Notify PVC owner of the state change
468 switch(cause) {
469 case UNI_DOWN:
470 uvp->uv_sstate = UNI_PVC_ACT_DOWN;
471 break;
472 case UNI_UP:
473 uvp->uv_sstate = UNI_PVC_ACTIVE;
474 break;
476 atm_cm_cleared(uvp->uv_connvc, cause);
477 } else {
478 log(LOG_ERR, "unisig: invalid VCC type: vccb=%p, type=%d\n",
479 uvp, uvp->uv_type);
482 crit_exit();
484 #endif
488 * Copy connection parameters from UNI 3.0 message IEs into
489 * an attribute block
491 * Arguments:
492 * usp pointer to UNISIG protocol instance
493 * msg pointer to the SETUP message
494 * ap pointer to the attribute block
496 * Returns:
497 * none
500 void
501 unisig_save_attrs(struct unisig *usp, struct unisig_msg *msg,
502 Atm_attributes *ap)
505 * Sanity check
507 if (!msg || !ap)
508 return;
511 * Save the AAL parameters (AAL 3/4 and AAL 5 only)
513 if (msg->msg_ie_aalp) {
514 struct ie_generic *aalp = msg->msg_ie_aalp;
516 switch(msg->msg_ie_aalp->ie_aalp_aal_type) {
517 case UNI_IE_AALP_AT_AAL3:
518 ap->aal.tag = T_ATM_PRESENT;
519 ap->aal.type =
520 msg->msg_ie_aalp->ie_aalp_aal_type;
521 ap->aal.v.aal4.forward_max_SDU_size =
522 msg->msg_ie_aalp->ie_aalp_4_fwd_max_sdu;
523 ap->aal.v.aal4.backward_max_SDU_size =
524 msg->msg_ie_aalp->ie_aalp_4_bkwd_max_sdu;
525 ap->aal.v.aal4.SSCS_type =
526 msg->msg_ie_aalp->ie_aalp_4_sscs_type;
527 if (aalp->ie_aalp_4_mid_range == T_ATM_ABSENT) {
528 ap->aal.v.aal4.mid_low = T_ATM_ABSENT;
529 ap->aal.v.aal4.mid_high = T_ATM_ABSENT;
530 } else {
531 if (usp->us_proto == ATM_SIG_UNI30) {
532 ap->aal.v.aal4.mid_low = 0;
533 ap->aal.v.aal4.mid_high =
534 aalp->ie_aalp_4_mid_range
535 & UNI_IE_AALP_A3_R_MASK;
536 } else {
537 ap->aal.v.aal4.mid_low =
538 (aalp->ie_aalp_4_mid_range >>
539 UNI_IE_AALP_A3_R_SHIFT)
540 & UNI_IE_AALP_A3_R_MASK;
541 ap->aal.v.aal4.mid_high =
542 aalp->ie_aalp_4_mid_range
543 & UNI_IE_AALP_A3_R_MASK;
546 break;
547 case UNI_IE_AALP_AT_AAL5:
548 ap->aal.tag = T_ATM_PRESENT;
549 ap->aal.type =
550 msg->msg_ie_aalp->ie_aalp_aal_type;
551 ap->aal.v.aal5.forward_max_SDU_size =
552 msg->msg_ie_aalp->ie_aalp_5_fwd_max_sdu;
553 ap->aal.v.aal5.backward_max_SDU_size =
554 msg->msg_ie_aalp->ie_aalp_5_bkwd_max_sdu;
555 ap->aal.v.aal5.SSCS_type =
556 msg->msg_ie_aalp->ie_aalp_5_sscs_type;
557 break;
562 * Save traffic descriptor attributes
564 if (msg->msg_ie_clrt) {
565 ap->traffic.tag = T_ATM_PRESENT;
566 ap->traffic.v.forward.PCR_high_priority =
567 msg->msg_ie_clrt->ie_clrt_fwd_peak;
568 ap->traffic.v.forward.PCR_all_traffic =
569 msg->msg_ie_clrt->ie_clrt_fwd_peak_01;
570 ap->traffic.v.forward.SCR_high_priority =
571 msg->msg_ie_clrt->ie_clrt_fwd_sust;
572 ap->traffic.v.forward.SCR_all_traffic =
573 msg->msg_ie_clrt->ie_clrt_fwd_sust_01;
574 ap->traffic.v.forward.MBS_high_priority =
575 msg->msg_ie_clrt->ie_clrt_fwd_burst;
576 ap->traffic.v.forward.MBS_all_traffic =
577 msg->msg_ie_clrt->ie_clrt_fwd_burst_01;
578 ap->traffic.v.backward.PCR_high_priority =
579 msg->msg_ie_clrt->ie_clrt_bkwd_peak;
580 ap->traffic.v.backward.PCR_all_traffic =
581 msg->msg_ie_clrt->ie_clrt_bkwd_peak_01;
582 ap->traffic.v.backward.SCR_high_priority =
583 msg->msg_ie_clrt->ie_clrt_bkwd_sust;
584 ap->traffic.v.backward.SCR_all_traffic =
585 msg->msg_ie_clrt->ie_clrt_bkwd_sust_01;
586 ap->traffic.v.backward.MBS_high_priority =
587 msg->msg_ie_clrt->ie_clrt_bkwd_burst;
588 ap->traffic.v.backward.MBS_all_traffic =
589 msg->msg_ie_clrt->ie_clrt_bkwd_burst_01;
590 ap->traffic.v.best_effort =
591 msg->msg_ie_clrt->ie_clrt_best_effort;
592 if (msg->msg_ie_clrt->ie_clrt_tm_options ==
593 T_ATM_ABSENT) {
594 ap->traffic.v.forward.tagging = T_NO;
595 ap->traffic.v.backward.tagging = T_NO;
596 } else {
597 ap->traffic.v.forward.tagging =
598 (msg->msg_ie_clrt->ie_clrt_tm_options &
599 UNI_IE_CLRT_TM_FWD_TAG) != 0;
600 ap->traffic.v.backward.tagging =
601 (msg->msg_ie_clrt->ie_clrt_tm_options &
602 UNI_IE_CLRT_TM_BKWD_TAG) != 0;
607 * Save broadband bearer attributes
609 if (msg->msg_ie_bbcp) {
610 ap->bearer.tag = T_ATM_PRESENT;
611 ap->bearer.v.bearer_class =
612 msg->msg_ie_bbcp->ie_bbcp_bearer_class;
613 ap->bearer.v.traffic_type =
614 msg->msg_ie_bbcp->ie_bbcp_traffic_type;
615 ap->bearer.v.timing_requirements =
616 msg->msg_ie_bbcp->ie_bbcp_timing_req;
617 ap->bearer.v.clipping_susceptibility =
618 msg->msg_ie_bbcp->ie_bbcp_clipping;
619 ap->bearer.v.connection_configuration =
620 msg->msg_ie_bbcp->ie_bbcp_conn_config;
624 * Save broadband high layer attributes
626 if (msg->msg_ie_bhli) {
627 ap->bhli.tag = T_ATM_PRESENT;
628 ap->bhli.v.ID_type = msg->msg_ie_bhli->ie_bhli_type;
629 switch(ap->bhli.v.ID_type) {
630 case T_ATM_ISO_APP_ID:
631 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
632 ap->bhli.v.ID.ISO_ID,
633 sizeof(ap->bhli.v.ID.ISO_ID));
634 break;
635 case T_ATM_USER_APP_ID:
636 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
637 ap->bhli.v.ID.user_defined_ID,
638 sizeof(ap->bhli.v.ID.user_defined_ID));
639 break;
640 case T_ATM_VENDOR_APP_ID:
641 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
642 ap->bhli.v.ID.vendor_ID.OUI,
643 sizeof(ap->bhli.v.ID.vendor_ID.OUI));
644 KM_COPY(&msg->msg_ie_bhli->ie_bhli_info[sizeof(ap->bhli.v.ID.vendor_ID.OUI)-1],
645 ap->bhli.v.ID.vendor_ID.app_ID,
646 sizeof(ap->bhli.v.ID.vendor_ID.app_ID));
647 break;
652 * Save Broadband low layer, user layer 2 and 3 attributes
654 if (msg->msg_ie_blli) {
656 * Layer 2 parameters
658 switch(msg->msg_ie_blli->ie_blli_l2_id) {
659 case UNI_IE_BLLI_L2P_ISO1745:
660 case UNI_IE_BLLI_L2P_Q921:
661 case UNI_IE_BLLI_L2P_X25L:
662 case UNI_IE_BLLI_L2P_X25M:
663 case UNI_IE_BLLI_L2P_LAPB:
664 case UNI_IE_BLLI_L2P_HDLC1:
665 case UNI_IE_BLLI_L2P_HDLC2:
666 case UNI_IE_BLLI_L2P_HDLC3:
667 case UNI_IE_BLLI_L2P_LLC:
668 case UNI_IE_BLLI_L2P_X75:
669 case UNI_IE_BLLI_L2P_Q922:
670 case UNI_IE_BLLI_L2P_ISO7776:
671 ap->blli.tag_l2 = T_ATM_PRESENT;
672 ap->blli.v.layer_2_protocol.ID_type =
673 T_ATM_SIMPLE_ID;
674 ap->blli.v.layer_2_protocol.ID.simple_ID =
675 msg->msg_ie_blli->ie_blli_l2_id;
676 break;
677 case UNI_IE_BLLI_L2P_USER:
678 ap->blli.tag_l2 = T_ATM_PRESENT;
679 ap->blli.v.layer_2_protocol.ID_type =
680 T_ATM_USER_ID;
681 ap->blli.v.layer_2_protocol.ID.user_defined_ID =
682 msg->msg_ie_blli->ie_blli_l2_user_proto;
683 break;
684 default:
685 ap->blli.tag_l2 = T_ATM_ABSENT;
687 if (ap->blli.tag_l2 == T_ATM_PRESENT) {
688 ap->blli.v.layer_2_protocol.mode =
689 msg->msg_ie_blli->ie_blli_l2_mode;
690 ap->blli.v.layer_2_protocol.window_size =
691 msg->msg_ie_blli->ie_blli_l2_window;
695 * Layer 3 parameters
697 switch(msg->msg_ie_blli->ie_blli_l3_id) {
698 case UNI_IE_BLLI_L3P_X25:
699 case UNI_IE_BLLI_L3P_ISO8208:
700 case UNI_IE_BLLI_L3P_ISO8878:
701 case UNI_IE_BLLI_L3P_ISO8473:
702 case UNI_IE_BLLI_L3P_T70:
703 ap->blli.tag_l3 = T_ATM_PRESENT;
704 ap->blli.v.layer_3_protocol.ID_type =
705 T_ATM_SIMPLE_ID;
706 ap->blli.v.layer_3_protocol.ID.simple_ID =
707 msg->msg_ie_blli->ie_blli_l3_id;
708 break;
709 case UNI_IE_BLLI_L3P_ISO9577:
710 ap->blli.tag_l3 = T_ATM_PRESENT;
711 ap->blli.v.layer_3_protocol.ID_type =
712 T_ATM_SIMPLE_ID;
713 ap->blli.v.layer_3_protocol.ID.simple_ID =
714 msg->msg_ie_blli->ie_blli_l3_id;
715 if (msg->msg_ie_blli->ie_blli_l3_ipi ==
716 UNI_IE_BLLI_L3IPI_SNAP) {
717 KM_COPY(msg->msg_ie_blli->ie_blli_l3_oui,
718 ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI,
719 sizeof(ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI));
720 KM_COPY(msg->msg_ie_blli->ie_blli_l3_pid,
721 ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID,
722 sizeof(ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID));
723 } else {
724 ap->blli.v.layer_3_protocol.ID.IPI_ID =
725 msg->msg_ie_blli->ie_blli_l3_ipi;
727 break;
728 case UNI_IE_BLLI_L3P_USER:
729 ap->blli.tag_l3 = T_ATM_PRESENT;
730 ap->blli.v.layer_3_protocol.ID_type =
731 T_ATM_USER_ID;
732 ap->blli.v.layer_3_protocol.ID.user_defined_ID =
733 msg->msg_ie_blli->ie_blli_l3_user_proto;
734 break;
735 default:
736 ap->blli.tag_l3 = T_ATM_ABSENT;
738 if (ap->blli.tag_l3 == T_ATM_PRESENT) {
739 ap->blli.v.layer_3_protocol.mode =
740 msg->msg_ie_blli->ie_blli_l3_mode;
741 ap->blli.v.layer_3_protocol.packet_size =
742 msg->msg_ie_blli->ie_blli_l3_packet_size;
743 ap->blli.v.layer_3_protocol.window_size =
744 msg->msg_ie_blli->ie_blli_l3_window;
749 * Save the called party address and subaddress
751 if (msg->msg_ie_cdad) {
752 ap->called.tag = T_ATM_PRESENT;
753 ATM_ADDR_COPY(&msg->msg_ie_cdad->ie_cdad_addr,
754 &ap->called.addr);
755 ap->called.subaddr.address_format = T_ATM_ABSENT;
756 ap->called.subaddr.address_length = 0;
758 if (msg->msg_ie_cdsa) {
759 ATM_ADDR_COPY(&msg->msg_ie_cdsa->ie_cdsa_addr,
760 &ap->called.subaddr);
764 * Save the calling party address and subaddress
766 if (msg->msg_ie_cgad) {
767 ap->calling.tag = T_ATM_PRESENT;
768 ATM_ADDR_COPY(&msg->msg_ie_cgad->ie_cgad_addr,
769 &ap->calling.addr);
770 ap->calling.subaddr.address_format = T_ATM_ABSENT;
771 ap->calling.subaddr.address_length = 0;
774 if (msg->msg_ie_cgsa) {
775 ATM_ADDR_COPY(&msg->msg_ie_cgsa->ie_cgsa_addr,
776 &ap->calling.subaddr);
780 * Save quality of service attributes
782 if (msg->msg_ie_qosp) {
783 ap->qos.tag = T_ATM_PRESENT;
784 ap->qos.v.coding_standard = msg->msg_ie_qosp->ie_coding;
785 ap->qos.v.forward.qos_class = msg->msg_ie_qosp->ie_qosp_fwd_class;
786 ap->qos.v.forward.qos_class =
787 msg->msg_ie_qosp->ie_qosp_bkwd_class;
791 * Save transit network attributes
793 if (msg->msg_ie_trnt) {
794 ap->transit.tag = T_ATM_PRESENT;
795 ap->transit.v.length =
796 MIN(msg->msg_ie_trnt->ie_trnt_id_len,
797 sizeof(ap->transit.v.network_id));
798 KM_COPY(msg->msg_ie_trnt->ie_trnt_id,
799 ap->transit.v.network_id,
800 ap->transit.v.length);
804 * Save cause code
806 if (msg->msg_ie_caus) {
807 ap->cause.tag = T_ATM_PRESENT;
808 ap->cause.v.coding_standard =
809 msg->msg_ie_caus->ie_coding;
810 ap->cause.v.location =
811 msg->msg_ie_caus->ie_caus_loc;
812 ap->cause.v.cause_value =
813 msg->msg_ie_caus->ie_caus_cause;
814 KM_ZERO(ap->cause.v.diagnostics,
815 sizeof(ap->cause.v.diagnostics));
816 #ifdef NOTDEF
817 KM_COPY(msg->msg_ie_caus->ie_caus_diagnostic,
818 ap->transit.v.diagnostics,
819 MIN(sizeof(ap->transit.v.diagnostics),
820 msg->msg_ie_caus->ie_caus_diag_len));
821 #endif
827 * Copy connection parameters from an attribute block into
828 * UNI 3.0 message IEs
830 * Arguments:
831 * usp pointer to UNISIG protocol instance
832 * msg pointer to the SETUP message
833 * ap pointer to the attribute block
835 * Returns:
836 * 0 everything OK
837 * else error encountered
841 unisig_set_attrs(struct unisig *usp, struct unisig_msg *msg,
842 Atm_attributes *ap)
844 int err = 0;
847 * Sanity check
849 if (!msg || !ap)
850 return(EINVAL);
853 * Set the AAL parameters (AAL 3/4 and AAL 5 only)
855 if (ap->aal.tag == T_ATM_PRESENT) {
856 if (!msg->msg_ie_aalp) {
857 msg->msg_ie_aalp = (struct ie_generic *)
858 atm_allocate(&unisig_iepool);
859 if (msg->msg_ie_aalp == NULL) {
860 err = ENOMEM;
861 goto done;
864 KM_COPY(&ie_aalp_absent,
865 &msg->msg_ie_aalp->ie_u.ie_aalp,
866 sizeof(ie_aalp_absent));
867 msg->msg_ie_aalp->ie_ident = UNI_IE_AALP;
868 msg->msg_ie_aalp->ie_aalp_aal_type = ap->aal.type;
869 switch(ap->aal.type) {
870 case ATM_AAL3_4:
871 msg->msg_ie_aalp->ie_aalp_4_fwd_max_sdu =
872 ap->aal.v.aal4.forward_max_SDU_size;
873 msg->msg_ie_aalp->ie_aalp_4_bkwd_max_sdu =
874 ap->aal.v.aal4.backward_max_SDU_size;
875 msg->msg_ie_aalp->ie_aalp_4_mode = UNI_IE_AALP_A5_M_MSG;
876 msg->msg_ie_aalp->ie_aalp_4_sscs_type =
877 ap->aal.v.aal4.SSCS_type;
878 if (ap->aal.v.aal4.mid_low == T_ATM_ABSENT) {
879 msg->msg_ie_aalp->ie_aalp_4_mid_range =
880 T_ATM_ABSENT;
881 } else {
882 if (usp->us_proto == ATM_SIG_UNI30) {
883 msg->msg_ie_aalp->ie_aalp_4_mid_range =
884 ap->aal.v.aal4.mid_high &
885 UNI_IE_AALP_A3_R_MASK;
886 } else {
887 msg->msg_ie_aalp->ie_aalp_4_mid_range =
888 ((ap->aal.v.aal4.mid_low &
889 UNI_IE_AALP_A3_R_MASK)
890 << UNI_IE_AALP_A3_R_SHIFT)
892 (ap->aal.v.aal4.mid_high &
893 UNI_IE_AALP_A3_R_MASK);
896 break;
897 case ATM_AAL5:
898 msg->msg_ie_aalp->ie_aalp_5_fwd_max_sdu =
899 ap->aal.v.aal5.forward_max_SDU_size;
900 msg->msg_ie_aalp->ie_aalp_5_bkwd_max_sdu =
901 ap->aal.v.aal5.backward_max_SDU_size;
902 msg->msg_ie_aalp->ie_aalp_5_mode =
903 UNI_IE_AALP_A5_M_MSG;
904 msg->msg_ie_aalp->ie_aalp_5_sscs_type =
905 ap->aal.v.aal5.SSCS_type;
906 break;
911 * Set traffic descriptor attributes
913 if (ap->traffic.tag == T_ATM_PRESENT) {
914 if (!msg->msg_ie_clrt) {
915 msg->msg_ie_clrt = (struct ie_generic *)
916 atm_allocate(&unisig_iepool);
917 if (msg->msg_ie_clrt == NULL) {
918 err = ENOMEM;
919 goto done;
922 KM_COPY(&ie_clrt_absent,
923 &msg->msg_ie_clrt->ie_u.ie_clrt,
924 sizeof(ie_clrt_absent));
925 msg->msg_ie_clrt->ie_ident = UNI_IE_CLRT;
926 msg->msg_ie_clrt->ie_clrt_fwd_peak =
927 ap->traffic.v.forward.PCR_high_priority;
928 msg->msg_ie_clrt->ie_clrt_fwd_peak_01 =
929 ap->traffic.v.forward.PCR_all_traffic;
930 msg->msg_ie_clrt->ie_clrt_fwd_sust =
931 ap->traffic.v.forward.SCR_high_priority;
932 msg->msg_ie_clrt->ie_clrt_fwd_sust_01 =
933 ap->traffic.v.forward.SCR_all_traffic;
934 msg->msg_ie_clrt->ie_clrt_fwd_burst =
935 ap->traffic.v.forward.MBS_high_priority;
936 msg->msg_ie_clrt->ie_clrt_fwd_burst_01 =
937 ap->traffic.v.forward.MBS_all_traffic;
938 msg->msg_ie_clrt->ie_clrt_bkwd_peak =
939 ap->traffic.v.backward.PCR_high_priority;
940 msg->msg_ie_clrt->ie_clrt_bkwd_peak_01 =
941 ap->traffic.v.backward.PCR_all_traffic;
942 msg->msg_ie_clrt->ie_clrt_bkwd_sust =
943 ap->traffic.v.backward.SCR_high_priority;
944 msg->msg_ie_clrt->ie_clrt_bkwd_sust_01 =
945 ap->traffic.v.backward.SCR_all_traffic;
946 msg->msg_ie_clrt->ie_clrt_bkwd_burst =
947 ap->traffic.v.backward.MBS_high_priority;
948 msg->msg_ie_clrt->ie_clrt_bkwd_burst_01 =
949 ap->traffic.v.backward.MBS_all_traffic;
950 msg->msg_ie_clrt->ie_clrt_best_effort =
951 ap->traffic.v.best_effort;
952 msg->msg_ie_clrt->ie_clrt_tm_options = 0;
953 if (ap->traffic.v.forward.tagging) {
954 msg->msg_ie_clrt->ie_clrt_tm_options |=
955 UNI_IE_CLRT_TM_FWD_TAG;
957 if (ap->traffic.v.backward.tagging) {
958 msg->msg_ie_clrt->ie_clrt_tm_options |=
959 UNI_IE_CLRT_TM_BKWD_TAG;
961 if (msg->msg_ie_clrt->ie_clrt_tm_options == 0) {
962 msg->msg_ie_clrt->ie_clrt_tm_options =
963 T_ATM_ABSENT;
968 * Set broadband bearer attributes
970 if (ap->bearer.tag == T_ATM_PRESENT) {
971 if (!msg->msg_ie_bbcp) {
972 msg->msg_ie_bbcp = (struct ie_generic *)
973 atm_allocate(&unisig_iepool);
974 if (msg->msg_ie_bbcp == NULL) {
975 err = ENOMEM;
976 goto done;
979 KM_COPY(&ie_bbcp_absent,
980 &msg->msg_ie_bbcp->ie_u.ie_bbcp,
981 sizeof(ie_bbcp_absent));
982 msg->msg_ie_bbcp->ie_ident = UNI_IE_BBCP;
983 msg->msg_ie_bbcp->ie_bbcp_bearer_class =
984 ap->bearer.v.bearer_class;
985 msg->msg_ie_bbcp->ie_bbcp_traffic_type =
986 ap->bearer.v.traffic_type;
987 msg->msg_ie_bbcp->ie_bbcp_timing_req =
988 ap->bearer.v.timing_requirements;
989 msg->msg_ie_bbcp->ie_bbcp_clipping =
990 ap->bearer.v.clipping_susceptibility;
991 msg->msg_ie_bbcp->ie_bbcp_conn_config =
992 ap->bearer.v.connection_configuration;
996 * Set broadband high layer attributes
998 if (ap->bhli.tag == T_ATM_PRESENT) {
999 if (!msg->msg_ie_bhli) {
1000 msg->msg_ie_bhli = (struct ie_generic *)
1001 atm_allocate(&unisig_iepool);
1002 if (msg->msg_ie_bhli == NULL) {
1003 err = ENOMEM;
1004 goto done;
1007 KM_COPY(&ie_bhli_absent,
1008 &msg->msg_ie_bhli->ie_u.ie_bhli,
1009 sizeof(ie_bhli_absent));
1010 msg->msg_ie_bhli->ie_ident = UNI_IE_BHLI;
1011 msg->msg_ie_bhli->ie_bhli_type = ap->bhli.v.ID_type;
1012 switch (ap->bhli.v.ID_type) {
1013 case T_ATM_ISO_APP_ID:
1014 KM_COPY(ap->bhli.v.ID.ISO_ID,
1015 msg->msg_ie_bhli->ie_bhli_info,
1016 sizeof(ap->bhli.v.ID.ISO_ID));
1017 break;
1018 case T_ATM_USER_APP_ID:
1019 KM_COPY(ap->bhli.v.ID.user_defined_ID,
1020 msg->msg_ie_bhli->ie_bhli_info,
1021 sizeof(ap->bhli.v.ID.user_defined_ID));
1022 break;
1023 case T_ATM_VENDOR_APP_ID:
1024 KM_COPY(ap->bhli.v.ID.vendor_ID.OUI,
1025 msg->msg_ie_bhli->ie_bhli_info,
1026 sizeof(ap->bhli.v.ID.vendor_ID.OUI));
1027 KM_COPY(ap->bhli.v.ID.vendor_ID.app_ID,
1028 &msg->msg_ie_bhli->ie_bhli_info[sizeof(ap->bhli.v.ID.vendor_ID.OUI)-1],
1029 sizeof(ap->bhli.v.ID.vendor_ID.app_ID));
1030 break;
1035 * Set Broadband low layer, user layer 2 and 3 attributes
1037 if (ap->blli.tag_l2 == T_ATM_PRESENT ||
1038 ap->blli.tag_l3 == T_ATM_PRESENT) {
1039 if (!msg->msg_ie_blli) {
1040 msg->msg_ie_blli = (struct ie_generic *)
1041 atm_allocate(&unisig_iepool);
1042 if (msg->msg_ie_blli == NULL) {
1043 err = ENOMEM;
1044 goto done;
1047 KM_COPY(&ie_blli_absent,
1048 &msg->msg_ie_blli->ie_u.ie_blli,
1049 sizeof(ie_blli_absent));
1050 msg->msg_ie_blli->ie_ident = UNI_IE_BLLI;
1052 if (ap->blli.tag_l2 == T_ATM_PRESENT) {
1053 switch(ap->blli.v.layer_2_protocol.ID_type) {
1054 case T_ATM_SIMPLE_ID:
1055 msg->msg_ie_blli->ie_blli_l2_id =
1056 ap->blli.v.layer_2_protocol.ID.simple_ID;
1057 break;
1058 case T_ATM_USER_ID:
1059 msg->msg_ie_blli->ie_blli_l2_id =
1060 UNI_IE_BLLI_L2P_USER;
1061 msg->msg_ie_blli->ie_blli_l2_user_proto =
1062 ap->blli.v.layer_2_protocol.ID.user_defined_ID;
1063 break;
1065 if (ap->blli.v.layer_2_protocol.ID_type !=
1066 T_ATM_ABSENT) {
1067 msg->msg_ie_blli->ie_blli_l2_mode =
1068 ap->blli.v.layer_2_protocol.mode;
1069 msg->msg_ie_blli->ie_blli_l2_window =
1070 ap->blli.v.layer_2_protocol.window_size;
1074 if (ap->blli.tag_l3 == T_ATM_PRESENT) {
1075 switch (ap->blli.v.layer_3_protocol.ID_type) {
1076 case T_ATM_SIMPLE_ID:
1077 msg->msg_ie_blli->ie_blli_l3_id =
1078 ap->blli.v.layer_3_protocol.ID.simple_ID;
1079 break;
1081 case T_ATM_IPI_ID:
1082 msg->msg_ie_blli->ie_blli_l3_id =
1083 UNI_IE_BLLI_L3P_ISO9577;
1084 msg->msg_ie_blli->ie_blli_l3_ipi =
1085 ap->blli.v.layer_3_protocol.ID.IPI_ID;
1086 break;
1088 case T_ATM_SNAP_ID:
1089 msg->msg_ie_blli->ie_blli_l3_id =
1090 UNI_IE_BLLI_L3P_ISO9577;
1091 msg->msg_ie_blli->ie_blli_l3_ipi =
1092 UNI_IE_BLLI_L3IPI_SNAP;
1093 KM_COPY(ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI,
1094 msg->msg_ie_blli->ie_blli_l3_oui,
1095 sizeof(msg->msg_ie_blli->ie_blli_l3_oui));
1096 KM_COPY(ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID,
1097 msg->msg_ie_blli->ie_blli_l3_pid,
1098 sizeof(msg->msg_ie_blli->ie_blli_l3_pid));
1099 break;
1101 case T_ATM_USER_ID:
1102 msg->msg_ie_blli->ie_blli_l3_id =
1103 UNI_IE_BLLI_L3P_USER;
1104 msg->msg_ie_blli->ie_blli_l3_user_proto =
1105 ap->blli.v.layer_3_protocol.ID.user_defined_ID;
1106 break;
1108 if (ap->blli.v.layer_3_protocol.ID_type
1109 != T_ATM_ABSENT) {
1110 msg->msg_ie_blli->ie_blli_l3_mode =
1111 ap->blli.v.layer_3_protocol.mode;
1112 msg->msg_ie_blli->ie_blli_l3_packet_size =
1113 ap->blli.v.layer_3_protocol.packet_size;
1114 msg->msg_ie_blli->ie_blli_l3_window =
1115 ap->blli.v.layer_3_protocol.window_size;
1121 * Set the called party address and subaddress
1123 if (ap->called.tag == T_ATM_PRESENT) {
1124 if (!msg->msg_ie_cdad) {
1125 msg->msg_ie_cdad = (struct ie_generic *)
1126 atm_allocate(&unisig_iepool);
1127 if (msg->msg_ie_cdad == NULL) {
1128 err = ENOMEM;
1129 goto done;
1132 KM_COPY(&ie_cdad_absent,
1133 &msg->msg_ie_cdad->ie_u.ie_cdad,
1134 sizeof(ie_cdad_absent));
1135 msg->msg_ie_cdad->ie_ident = UNI_IE_CDAD;
1136 ATM_ADDR_COPY(&ap->called.addr,
1137 &msg->msg_ie_cdad->ie_cdad_addr);
1139 if (ap->called.subaddr.address_format != T_ATM_ABSENT) {
1140 if (!msg->msg_ie_cdsa) {
1141 msg->msg_ie_cdsa = (struct ie_generic *)
1142 atm_allocate(&unisig_iepool);
1143 if (msg->msg_ie_cdsa == NULL) {
1144 err = ENOMEM;
1145 goto done;
1148 KM_COPY(&ie_cdsa_absent,
1149 &msg->msg_ie_cdsa->ie_u.ie_cdsa,
1150 sizeof(ie_cdsa_absent));
1151 msg->msg_ie_cdsa->ie_ident = UNI_IE_CDSA;
1152 ATM_ADDR_COPY(&ap->called.subaddr,
1153 &msg->msg_ie_cdsa->ie_cdsa_addr);
1158 * Set the calling party address and subaddress
1161 if (ap->calling.tag == T_ATM_PRESENT) {
1162 if (!msg->msg_ie_cgad) {
1163 msg->msg_ie_cgad = (struct ie_generic *)
1164 atm_allocate(&unisig_iepool);
1165 if (msg->msg_ie_cgad == NULL) {
1166 err = ENOMEM;
1167 goto done;
1170 KM_COPY(&ie_cgad_absent,
1171 &msg->msg_ie_cgad->ie_u.ie_cgad,
1172 sizeof(ie_cgad_absent));
1173 msg->msg_ie_cgsa->ie_ident = UNI_IE_CGSA;
1174 ATM_ADDR_COPY(&ap->calling.addr,
1175 &msg->msg_ie_cgad->ie_cgad_addr);
1177 if (ap->calling.subaddr.address_format !=
1178 T_ATM_ABSENT) {
1179 if (!msg->msg_ie_cgsa) {
1180 msg->msg_ie_cgsa = (struct ie_generic *)
1181 atm_allocate(&unisig_iepool);
1182 if (msg->msg_ie_cgsa == NULL) {
1183 err = ENOMEM;
1184 goto done;
1187 KM_COPY(&ie_cgsa_absent,
1188 &msg->msg_ie_cgsa->ie_u.ie_cgsa,
1189 sizeof(ie_cgsa_absent));
1190 msg->msg_ie_cgsa->ie_ident = UNI_IE_CGSA;
1191 ATM_ADDR_COPY(&ap->calling.subaddr,
1192 &msg->msg_ie_cgsa->ie_cgsa_addr);
1197 * Set quality of service attributes
1199 if (ap->qos.tag == T_ATM_PRESENT) {
1200 if (!msg->msg_ie_qosp) {
1201 msg->msg_ie_qosp = (struct ie_generic *)
1202 atm_allocate(&unisig_iepool);
1203 if (msg->msg_ie_qosp == NULL) {
1204 err = ENOMEM;
1205 goto done;
1208 KM_COPY(&ie_qosp_absent,
1209 &msg->msg_ie_qosp->ie_u.ie_qosp,
1210 sizeof(ie_qosp_absent));
1211 msg->msg_ie_qosp->ie_ident = UNI_IE_QOSP;
1212 if (usp->us_proto == ATM_SIG_UNI30)
1213 msg->msg_ie_qosp->ie_coding = UNI_IE_CODE_STD;
1214 else if ((ap->qos.v.forward.qos_class ==
1215 T_ATM_QOS_CLASS_0) ||
1216 (ap->qos.v.backward.qos_class ==
1217 T_ATM_QOS_CLASS_0))
1218 msg->msg_ie_qosp->ie_coding = UNI_IE_CODE_CCITT;
1219 else
1220 msg->msg_ie_qosp->ie_coding = ap->qos.v.coding_standard;
1221 msg->msg_ie_qosp->ie_qosp_fwd_class =
1222 ap->qos.v.forward.qos_class;
1223 msg->msg_ie_qosp->ie_qosp_bkwd_class =
1224 ap->qos.v.backward.qos_class;
1228 * Set transit network attributes
1230 if (ap->transit.tag == T_ATM_PRESENT &&
1231 ap->transit.v.length != 0) {
1232 if (!msg->msg_ie_trnt) {
1233 msg->msg_ie_trnt = (struct ie_generic *)
1234 atm_allocate(&unisig_iepool);
1235 if (msg->msg_ie_trnt == NULL) {
1236 err = ENOMEM;
1237 goto done;
1240 KM_COPY(&ie_trnt_absent,
1241 &msg->msg_ie_trnt->ie_u.ie_trnt,
1242 sizeof(ie_trnt_absent));
1243 msg->msg_ie_trnt->ie_ident = UNI_IE_TRNT;
1244 msg->msg_ie_trnt->ie_trnt_id_type =
1245 UNI_IE_TRNT_IDT_NATL;
1246 msg->msg_ie_trnt->ie_trnt_id_plan =
1247 UNI_IE_TRNT_IDP_CIC;
1248 KM_COPY(ap->transit.v.network_id,
1249 msg->msg_ie_trnt->ie_trnt_id,
1250 ap->transit.v.length);
1254 * Set cause code
1256 if (ap->cause.tag == T_ATM_PRESENT) {
1257 if (!msg->msg_ie_caus) {
1258 msg->msg_ie_caus = (struct ie_generic *)
1259 atm_allocate(&unisig_iepool);
1260 if (msg->msg_ie_caus == NULL) {
1261 err = ENOMEM;
1262 goto done;
1265 KM_COPY(&ie_caus_absent,
1266 &msg->msg_ie_caus->ie_u.ie_caus,
1267 sizeof(ie_caus_absent));
1268 msg->msg_ie_caus->ie_ident = UNI_IE_CAUS;
1269 msg->msg_ie_caus->ie_coding =
1270 ap->cause.v.coding_standard;
1271 msg->msg_ie_caus->ie_caus_loc =
1272 ap->cause.v.location;
1273 msg->msg_ie_caus->ie_caus_cause =
1274 ap->cause.v.cause_value;
1277 * Don't copy the diagnostics from the attribute
1278 * block, as there's no way to tell how much of
1279 * the diagnostic field is relevant
1281 msg->msg_ie_caus->ie_caus_diag_len = 0;
1284 done:
1285 return(err);