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 * ----------------------------------------
38 #include <netproto/atm/kern_include.h>
40 #include "unisig_var.h"
41 #include "unisig_msg.h"
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
73 * aap pointer to attribute block
81 unisig_cause_attr_from_user(Atm_attributes
*aap
, int cause
)
83 if (cause
== T_ATM_ABSENT
)
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
102 * aap pointer to attribute block
103 * iep pointer to Cause IE
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
));
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.
136 * usp pointer to UNISIG protocol instance
137 * cvp pointer to connection parameters for the VCC
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
;
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
==
167 switch (cvp
->cvc_attr
.called
.addr
.address_format
) {
170 * Make sure VPI/VCI is valid
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
)) {
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)) {
188 ATM_DEBUG2("unisig_open_vcc: VPI.VCI=%d.%d\n",
189 ATM_PVC_GET_VPI(pvp
),
190 ATM_PVC_GET_VCI(pvp
));
193 case T_ATM_ENDSYS_ADDR
:
195 * Check signalling state
199 if (usp
->us_state
!= UNISIG_ACTIVE
) {
204 * Make sure there's no subaddress
206 if (cvp
->cvc_attr
.called
.subaddr
.address_format
!=
212 case T_ATM_E164_ADDR
:
214 * Check signalling state
218 if (usp
->us_state
!= UNISIG_ACTIVE
) {
223 * Check destination address format
225 if (cvp
->cvc_attr
.called
.subaddr
.address_format
!=
227 cvp
->cvc_attr
.called
.subaddr
.address_format
!=
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
) {
246 * Allocate control block for VCC
248 uvp
= (struct unisig_vccb
*)atm_allocate(&unisig_vcpool
);
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
;
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
283 err
= unisig_vc_state(usp
, uvp
, UNI_VC_SETUP_CALL
,
284 (struct unisig_msg
*) 0);
287 * On error, delete the VCCB
289 DEQUEUE(uvp
, struct unisig_vccb
, uv_sigelem
,
291 atm_free((caddr_t
)uvp
);
297 * Link VCCB to VCC connection block
299 cvp
->cvc_vcc
= (struct vccb
*) uvp
;
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.
314 * usp pointer to UNISIG protocol instance
315 * uvp pointer to VCCB for the VCC to be closed
318 * 0 VCC is now closed
319 * errno error encountered
322 unisig_close_vcc(struct unisig
*usp
, struct unisig_vccb
*uvp
)
326 ATM_DEBUG2("unisig_close_vcc: uvp=%p, state=%d\n", uvp
,
330 * Check that this is for the same interface UNISIG uses
332 if (uvp
->uv_pif
!= usp
->us_pif
) {
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
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.
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
378 * errno error encountered
381 unisig_clear_vcc(struct unisig
*usp
, struct unisig_vccb
*uvp
, int cause
)
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
) {
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
433 * Reset the switch state
436 * usp pointer to UNISIG protocol instance
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",
451 * Terminate all of our VCCs
454 for (uvp
= Q_HEAD(usp
->us_vccq
, struct unisig_vccb
); uvp
;
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
470 uvp
->uv_sstate
= UNI_PVC_ACT_DOWN
;
473 uvp
->uv_sstate
= UNI_PVC_ACTIVE
;
476 atm_cm_cleared(uvp
->uv_connvc
, cause
);
478 log(LOG_ERR
, "unisig: invalid VCC type: vccb=%p, type=%d\n",
488 * Copy connection parameters from UNI 3.0 message IEs into
492 * usp pointer to UNISIG protocol instance
493 * msg pointer to the SETUP message
494 * ap pointer to the attribute block
501 unisig_save_attrs(struct unisig
*usp
, struct unisig_msg
*msg
,
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
;
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
;
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
;
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
;
547 case UNI_IE_AALP_AT_AAL5
:
548 ap
->aal
.tag
= T_ATM_PRESENT
;
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
;
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
==
594 ap
->traffic
.v
.forward
.tagging
= T_NO
;
595 ap
->traffic
.v
.backward
.tagging
= T_NO
;
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
));
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
));
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
));
652 * Save Broadband low layer, user layer 2 and 3 attributes
654 if (msg
->msg_ie_blli
) {
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
=
674 ap
->blli
.v
.layer_2_protocol
.ID
.simple_ID
=
675 msg
->msg_ie_blli
->ie_blli_l2_id
;
677 case UNI_IE_BLLI_L2P_USER
:
678 ap
->blli
.tag_l2
= T_ATM_PRESENT
;
679 ap
->blli
.v
.layer_2_protocol
.ID_type
=
681 ap
->blli
.v
.layer_2_protocol
.ID
.user_defined_ID
=
682 msg
->msg_ie_blli
->ie_blli_l2_user_proto
;
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
;
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
=
706 ap
->blli
.v
.layer_3_protocol
.ID
.simple_ID
=
707 msg
->msg_ie_blli
->ie_blli_l3_id
;
709 case UNI_IE_BLLI_L3P_ISO9577
:
710 ap
->blli
.tag_l3
= T_ATM_PRESENT
;
711 ap
->blli
.v
.layer_3_protocol
.ID_type
=
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
));
724 ap
->blli
.v
.layer_3_protocol
.ID
.IPI_ID
=
725 msg
->msg_ie_blli
->ie_blli_l3_ipi
;
728 case UNI_IE_BLLI_L3P_USER
:
729 ap
->blli
.tag_l3
= T_ATM_PRESENT
;
730 ap
->blli
.v
.layer_3_protocol
.ID_type
=
732 ap
->blli
.v
.layer_3_protocol
.ID
.user_defined_ID
=
733 msg
->msg_ie_blli
->ie_blli_l3_user_proto
;
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
,
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
,
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
);
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
));
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
));
827 * Copy connection parameters from an attribute block into
828 * UNI 3.0 message IEs
831 * usp pointer to UNISIG protocol instance
832 * msg pointer to the SETUP message
833 * ap pointer to the attribute block
837 * else error encountered
841 unisig_set_attrs(struct unisig
*usp
, struct unisig_msg
*msg
,
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
) {
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
) {
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
=
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
;
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
);
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
;
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
) {
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
=
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
) {
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
) {
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
));
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
));
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
));
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
) {
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
;
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
;
1065 if (ap
->blli
.v
.layer_2_protocol
.ID_type
!=
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
;
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
;
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
));
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
;
1108 if (ap
->blli
.v
.layer_3_protocol
.ID_type
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
) {
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
) {
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
) {
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
!=
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
) {
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
) {
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
==
1218 msg
->msg_ie_qosp
->ie_coding
= UNI_IE_CODE_CCITT
;
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
) {
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
);
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
) {
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;