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, NULL);
286 * On error, delete the VCCB
288 DEQUEUE(uvp, struct unisig_vccb, uv_sigelem,
290 atm_free((caddr_t)uvp);
296 * Link VCCB to VCC connection block
298 cvp->cvc_vcc = (struct vccb *) uvp;
307 * Called when a user wants to close a VCC. This function will clean
308 * up the VCCB and, for an SVC, send a close request.
310 * Must be called from a critical section.
313 * usp pointer to UNISIG protocol instance
314 * uvp pointer to VCCB for the VCC to be closed
317 * 0 VCC is now closed
318 * errno error encountered
321 unisig_close_vcc(struct unisig *usp, struct unisig_vccb *uvp)
325 ATM_DEBUG2("unisig_close_vcc: uvp=%p, state=%d\n", uvp,
329 * Check that this is for the same interface UNISIG uses
331 if (uvp->uv_pif != usp->us_pif) {
336 * Mark the close time.
338 uvp->uv_tstamp = time_second;
341 * Process based on the connection type
343 if (uvp->uv_type & VCC_PVC) {
344 uvp->uv_sstate = UNI_FREE;
345 uvp->uv_ustate = VCCU_CLOSED;
346 } else if (uvp->uv_type & VCC_SVC) {
348 * Call the VC state machine
350 uvp->uv_ustate = VCCU_CLOSED;
351 err = unisig_vc_state(usp, uvp, UNI_VC_RELEASE_CALL, NULL);
355 * Wait for user to free resources
364 * Called to internally clear a VCC. No external protocol is
365 * initiated, the VCC is just closed and the owner is notified.
367 * Must be called from a critical section.
370 * usp pointer to UNISIG protocol instance
371 * uvp pointer to VCCB for the VCC to be closed
372 * cause cause code giving the reason for the close
376 * errno error encountered
379 unisig_clear_vcc(struct unisig *usp, struct unisig_vccb *uvp, int cause)
383 ATM_DEBUG3("unisig_clear_vcc: uvp=%p, state=%d, cause=%d\n",
384 uvp, uvp->uv_sstate, cause);
387 * Check that this is for the same interface UNISIG uses
389 if (uvp->uv_pif != usp->us_pif) {
394 * Kill any possible timer
396 UNISIG_VC_CANCEL((struct vccb *) uvp);
399 * Mark the close time.
401 uvp->uv_tstamp = time_second;
404 * Close the VCC and notify the user
406 outstate = uvp->uv_sstate;
407 uvp->uv_sstate = UNI_FREE;
408 uvp->uv_ustate = VCCU_CLOSED;
409 if (outstate == UNI_ACTIVE ||
410 outstate == UNI_CALL_INITIATED ||
411 outstate == UNI_CALL_OUT_PROC ||
412 outstate == UNI_CONNECT_REQUEST ||
413 outstate == UNI_RELEASE_REQUEST ||
414 outstate == UNI_RELEASE_IND ||
415 outstate == UNI_SSCF_RECOV ||
416 outstate == UNI_PVC_ACT_DOWN ||
417 outstate == UNI_PVC_ACTIVE) {
418 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr, cause);
419 atm_cm_cleared(uvp->uv_connvc);
423 * Wait for user to free resources
431 * Reset the switch state
434 * usp pointer to UNISIG protocol instance
441 unisig_switch_reset(struct unisig *usp, int cause)
443 struct unisig_vccb *uvp, *vnext;
445 ATM_DEBUG2("unisig_switch_reset: usp=%p, cause=%d\n",
449 * Terminate all of our VCCs
452 for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp;
454 vnext = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem);
456 if (uvp->uv_type & VCC_SVC) {
458 * Close the SVC and notify the owner
460 unisig_clear_vcc(usp, uvp,
461 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
462 } else if (uvp->uv_type & VCC_PVC) {
464 * Notify PVC owner of the state change
468 uvp->uv_sstate = UNI_PVC_ACT_DOWN;
471 uvp->uv_sstate = UNI_PVC_ACTIVE;
474 atm_cm_cleared(uvp->uv_connvc, cause);
476 log(LOG_ERR, "unisig: invalid VCC type: vccb=%p, type=%d\n",
486 * Copy connection parameters from UNI 3.0 message IEs into
490 * usp pointer to UNISIG protocol instance
491 * msg pointer to the SETUP message
492 * ap pointer to the attribute block
499 unisig_save_attrs(struct unisig *usp, struct unisig_msg *msg,
509 * Save the AAL parameters (AAL 3/4 and AAL 5 only)
511 if (msg->msg_ie_aalp) {
512 struct ie_generic *aalp = msg->msg_ie_aalp;
514 switch(msg->msg_ie_aalp->ie_aalp_aal_type) {
515 case UNI_IE_AALP_AT_AAL3:
516 ap->aal.tag = T_ATM_PRESENT;
518 msg->msg_ie_aalp->ie_aalp_aal_type;
519 ap->aal.v.aal4.forward_max_SDU_size =
520 msg->msg_ie_aalp->ie_aalp_4_fwd_max_sdu;
521 ap->aal.v.aal4.backward_max_SDU_size =
522 msg->msg_ie_aalp->ie_aalp_4_bkwd_max_sdu;
523 ap->aal.v.aal4.SSCS_type =
524 msg->msg_ie_aalp->ie_aalp_4_sscs_type;
525 if (aalp->ie_aalp_4_mid_range == T_ATM_ABSENT) {
526 ap->aal.v.aal4.mid_low = T_ATM_ABSENT;
527 ap->aal.v.aal4.mid_high = T_ATM_ABSENT;
529 if (usp->us_proto == ATM_SIG_UNI30) {
530 ap->aal.v.aal4.mid_low = 0;
531 ap->aal.v.aal4.mid_high =
532 aalp->ie_aalp_4_mid_range
533 & UNI_IE_AALP_A3_R_MASK;
535 ap->aal.v.aal4.mid_low =
536 (aalp->ie_aalp_4_mid_range >>
537 UNI_IE_AALP_A3_R_SHIFT)
538 & UNI_IE_AALP_A3_R_MASK;
539 ap->aal.v.aal4.mid_high =
540 aalp->ie_aalp_4_mid_range
541 & UNI_IE_AALP_A3_R_MASK;
545 case UNI_IE_AALP_AT_AAL5:
546 ap->aal.tag = T_ATM_PRESENT;
548 msg->msg_ie_aalp->ie_aalp_aal_type;
549 ap->aal.v.aal5.forward_max_SDU_size =
550 msg->msg_ie_aalp->ie_aalp_5_fwd_max_sdu;
551 ap->aal.v.aal5.backward_max_SDU_size =
552 msg->msg_ie_aalp->ie_aalp_5_bkwd_max_sdu;
553 ap->aal.v.aal5.SSCS_type =
554 msg->msg_ie_aalp->ie_aalp_5_sscs_type;
560 * Save traffic descriptor attributes
562 if (msg->msg_ie_clrt) {
563 ap->traffic.tag = T_ATM_PRESENT;
564 ap->traffic.v.forward.PCR_high_priority =
565 msg->msg_ie_clrt->ie_clrt_fwd_peak;
566 ap->traffic.v.forward.PCR_all_traffic =
567 msg->msg_ie_clrt->ie_clrt_fwd_peak_01;
568 ap->traffic.v.forward.SCR_high_priority =
569 msg->msg_ie_clrt->ie_clrt_fwd_sust;
570 ap->traffic.v.forward.SCR_all_traffic =
571 msg->msg_ie_clrt->ie_clrt_fwd_sust_01;
572 ap->traffic.v.forward.MBS_high_priority =
573 msg->msg_ie_clrt->ie_clrt_fwd_burst;
574 ap->traffic.v.forward.MBS_all_traffic =
575 msg->msg_ie_clrt->ie_clrt_fwd_burst_01;
576 ap->traffic.v.backward.PCR_high_priority =
577 msg->msg_ie_clrt->ie_clrt_bkwd_peak;
578 ap->traffic.v.backward.PCR_all_traffic =
579 msg->msg_ie_clrt->ie_clrt_bkwd_peak_01;
580 ap->traffic.v.backward.SCR_high_priority =
581 msg->msg_ie_clrt->ie_clrt_bkwd_sust;
582 ap->traffic.v.backward.SCR_all_traffic =
583 msg->msg_ie_clrt->ie_clrt_bkwd_sust_01;
584 ap->traffic.v.backward.MBS_high_priority =
585 msg->msg_ie_clrt->ie_clrt_bkwd_burst;
586 ap->traffic.v.backward.MBS_all_traffic =
587 msg->msg_ie_clrt->ie_clrt_bkwd_burst_01;
588 ap->traffic.v.best_effort =
589 msg->msg_ie_clrt->ie_clrt_best_effort;
590 if (msg->msg_ie_clrt->ie_clrt_tm_options ==
592 ap->traffic.v.forward.tagging = T_NO;
593 ap->traffic.v.backward.tagging = T_NO;
595 ap->traffic.v.forward.tagging =
596 (msg->msg_ie_clrt->ie_clrt_tm_options &
597 UNI_IE_CLRT_TM_FWD_TAG) != 0;
598 ap->traffic.v.backward.tagging =
599 (msg->msg_ie_clrt->ie_clrt_tm_options &
600 UNI_IE_CLRT_TM_BKWD_TAG) != 0;
605 * Save broadband bearer attributes
607 if (msg->msg_ie_bbcp) {
608 ap->bearer.tag = T_ATM_PRESENT;
609 ap->bearer.v.bearer_class =
610 msg->msg_ie_bbcp->ie_bbcp_bearer_class;
611 ap->bearer.v.traffic_type =
612 msg->msg_ie_bbcp->ie_bbcp_traffic_type;
613 ap->bearer.v.timing_requirements =
614 msg->msg_ie_bbcp->ie_bbcp_timing_req;
615 ap->bearer.v.clipping_susceptibility =
616 msg->msg_ie_bbcp->ie_bbcp_clipping;
617 ap->bearer.v.connection_configuration =
618 msg->msg_ie_bbcp->ie_bbcp_conn_config;
622 * Save broadband high layer attributes
624 if (msg->msg_ie_bhli) {
625 ap->bhli.tag = T_ATM_PRESENT;
626 ap->bhli.v.ID_type = msg->msg_ie_bhli->ie_bhli_type;
627 switch(ap->bhli.v.ID_type) {
628 case T_ATM_ISO_APP_ID:
629 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
630 ap->bhli.v.ID.ISO_ID,
631 sizeof(ap->bhli.v.ID.ISO_ID));
633 case T_ATM_USER_APP_ID:
634 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
635 ap->bhli.v.ID.user_defined_ID,
636 sizeof(ap->bhli.v.ID.user_defined_ID));
638 case T_ATM_VENDOR_APP_ID:
639 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
640 ap->bhli.v.ID.vendor_ID.OUI,
641 sizeof(ap->bhli.v.ID.vendor_ID.OUI));
642 KM_COPY(&msg->msg_ie_bhli->ie_bhli_info[sizeof(ap->bhli.v.ID.vendor_ID.OUI)-1],
643 ap->bhli.v.ID.vendor_ID.app_ID,
644 sizeof(ap->bhli.v.ID.vendor_ID.app_ID));
650 * Save Broadband low layer, user layer 2 and 3 attributes
652 if (msg->msg_ie_blli) {
656 switch(msg->msg_ie_blli->ie_blli_l2_id) {
657 case UNI_IE_BLLI_L2P_ISO1745:
658 case UNI_IE_BLLI_L2P_Q921:
659 case UNI_IE_BLLI_L2P_X25L:
660 case UNI_IE_BLLI_L2P_X25M:
661 case UNI_IE_BLLI_L2P_LAPB:
662 case UNI_IE_BLLI_L2P_HDLC1:
663 case UNI_IE_BLLI_L2P_HDLC2:
664 case UNI_IE_BLLI_L2P_HDLC3:
665 case UNI_IE_BLLI_L2P_LLC:
666 case UNI_IE_BLLI_L2P_X75:
667 case UNI_IE_BLLI_L2P_Q922:
668 case UNI_IE_BLLI_L2P_ISO7776:
669 ap->blli.tag_l2 = T_ATM_PRESENT;
670 ap->blli.v.layer_2_protocol.ID_type =
672 ap->blli.v.layer_2_protocol.ID.simple_ID =
673 msg->msg_ie_blli->ie_blli_l2_id;
675 case UNI_IE_BLLI_L2P_USER:
676 ap->blli.tag_l2 = T_ATM_PRESENT;
677 ap->blli.v.layer_2_protocol.ID_type =
679 ap->blli.v.layer_2_protocol.ID.user_defined_ID =
680 msg->msg_ie_blli->ie_blli_l2_user_proto;
683 ap->blli.tag_l2 = T_ATM_ABSENT;
685 if (ap->blli.tag_l2 == T_ATM_PRESENT) {
686 ap->blli.v.layer_2_protocol.mode =
687 msg->msg_ie_blli->ie_blli_l2_mode;
688 ap->blli.v.layer_2_protocol.window_size =
689 msg->msg_ie_blli->ie_blli_l2_window;
695 switch(msg->msg_ie_blli->ie_blli_l3_id) {
696 case UNI_IE_BLLI_L3P_X25:
697 case UNI_IE_BLLI_L3P_ISO8208:
698 case UNI_IE_BLLI_L3P_ISO8878:
699 case UNI_IE_BLLI_L3P_ISO8473:
700 case UNI_IE_BLLI_L3P_T70:
701 ap->blli.tag_l3 = T_ATM_PRESENT;
702 ap->blli.v.layer_3_protocol.ID_type =
704 ap->blli.v.layer_3_protocol.ID.simple_ID =
705 msg->msg_ie_blli->ie_blli_l3_id;
707 case UNI_IE_BLLI_L3P_ISO9577:
708 ap->blli.tag_l3 = T_ATM_PRESENT;
709 ap->blli.v.layer_3_protocol.ID_type =
711 ap->blli.v.layer_3_protocol.ID.simple_ID =
712 msg->msg_ie_blli->ie_blli_l3_id;
713 if (msg->msg_ie_blli->ie_blli_l3_ipi ==
714 UNI_IE_BLLI_L3IPI_SNAP) {
715 KM_COPY(msg->msg_ie_blli->ie_blli_l3_oui,
716 ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI,
717 sizeof(ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI));
718 KM_COPY(msg->msg_ie_blli->ie_blli_l3_pid,
719 ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID,
720 sizeof(ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID));
722 ap->blli.v.layer_3_protocol.ID.IPI_ID =
723 msg->msg_ie_blli->ie_blli_l3_ipi;
726 case UNI_IE_BLLI_L3P_USER:
727 ap->blli.tag_l3 = T_ATM_PRESENT;
728 ap->blli.v.layer_3_protocol.ID_type =
730 ap->blli.v.layer_3_protocol.ID.user_defined_ID =
731 msg->msg_ie_blli->ie_blli_l3_user_proto;
734 ap->blli.tag_l3 = T_ATM_ABSENT;
736 if (ap->blli.tag_l3 == T_ATM_PRESENT) {
737 ap->blli.v.layer_3_protocol.mode =
738 msg->msg_ie_blli->ie_blli_l3_mode;
739 ap->blli.v.layer_3_protocol.packet_size =
740 msg->msg_ie_blli->ie_blli_l3_packet_size;
741 ap->blli.v.layer_3_protocol.window_size =
742 msg->msg_ie_blli->ie_blli_l3_window;
747 * Save the called party address and subaddress
749 if (msg->msg_ie_cdad) {
750 ap->called.tag = T_ATM_PRESENT;
751 ATM_ADDR_COPY(&msg->msg_ie_cdad->ie_cdad_addr,
753 ap->called.subaddr.address_format = T_ATM_ABSENT;
754 ap->called.subaddr.address_length = 0;
756 if (msg->msg_ie_cdsa) {
757 ATM_ADDR_COPY(&msg->msg_ie_cdsa->ie_cdsa_addr,
758 &ap->called.subaddr);
762 * Save the calling party address and subaddress
764 if (msg->msg_ie_cgad) {
765 ap->calling.tag = T_ATM_PRESENT;
766 ATM_ADDR_COPY(&msg->msg_ie_cgad->ie_cgad_addr,
768 ap->calling.subaddr.address_format = T_ATM_ABSENT;
769 ap->calling.subaddr.address_length = 0;
772 if (msg->msg_ie_cgsa) {
773 ATM_ADDR_COPY(&msg->msg_ie_cgsa->ie_cgsa_addr,
774 &ap->calling.subaddr);
778 * Save quality of service attributes
780 if (msg->msg_ie_qosp) {
781 ap->qos.tag = T_ATM_PRESENT;
782 ap->qos.v.coding_standard = msg->msg_ie_qosp->ie_coding;
783 ap->qos.v.forward.qos_class = msg->msg_ie_qosp->ie_qosp_fwd_class;
784 ap->qos.v.forward.qos_class =
785 msg->msg_ie_qosp->ie_qosp_bkwd_class;
789 * Save transit network attributes
791 if (msg->msg_ie_trnt) {
792 ap->transit.tag = T_ATM_PRESENT;
793 ap->transit.v.length =
794 MIN(msg->msg_ie_trnt->ie_trnt_id_len,
795 sizeof(ap->transit.v.network_id));
796 KM_COPY(msg->msg_ie_trnt->ie_trnt_id,
797 ap->transit.v.network_id,
798 ap->transit.v.length);
804 if (msg->msg_ie_caus) {
805 ap->cause.tag = T_ATM_PRESENT;
806 ap->cause.v.coding_standard =
807 msg->msg_ie_caus->ie_coding;
808 ap->cause.v.location =
809 msg->msg_ie_caus->ie_caus_loc;
810 ap->cause.v.cause_value =
811 msg->msg_ie_caus->ie_caus_cause;
812 KM_ZERO(ap->cause.v.diagnostics,
813 sizeof(ap->cause.v.diagnostics));
815 KM_COPY(msg->msg_ie_caus->ie_caus_diagnostic,
816 ap->transit.v.diagnostics,
817 MIN(sizeof(ap->transit.v.diagnostics),
818 msg->msg_ie_caus->ie_caus_diag_len));
825 * Copy connection parameters from an attribute block into
826 * UNI 3.0 message IEs
829 * usp pointer to UNISIG protocol instance
830 * msg pointer to the SETUP message
831 * ap pointer to the attribute block
835 * else error encountered
839 unisig_set_attrs(struct unisig *usp, struct unisig_msg *msg,
851 * Set the AAL parameters (AAL 3/4 and AAL 5 only)
853 if (ap->aal.tag == T_ATM_PRESENT) {
854 if (!msg->msg_ie_aalp) {
855 msg->msg_ie_aalp = (struct ie_generic *)
856 atm_allocate(&unisig_iepool);
857 if (msg->msg_ie_aalp == NULL) {
862 KM_COPY(&ie_aalp_absent,
863 &msg->msg_ie_aalp->ie_u.ie_aalp,
864 sizeof(ie_aalp_absent));
865 msg->msg_ie_aalp->ie_ident = UNI_IE_AALP;
866 msg->msg_ie_aalp->ie_aalp_aal_type = ap->aal.type;
867 switch(ap->aal.type) {
869 msg->msg_ie_aalp->ie_aalp_4_fwd_max_sdu =
870 ap->aal.v.aal4.forward_max_SDU_size;
871 msg->msg_ie_aalp->ie_aalp_4_bkwd_max_sdu =
872 ap->aal.v.aal4.backward_max_SDU_size;
873 msg->msg_ie_aalp->ie_aalp_4_mode = UNI_IE_AALP_A5_M_MSG;
874 msg->msg_ie_aalp->ie_aalp_4_sscs_type =
875 ap->aal.v.aal4.SSCS_type;
876 if (ap->aal.v.aal4.mid_low == T_ATM_ABSENT) {
877 msg->msg_ie_aalp->ie_aalp_4_mid_range =
880 if (usp->us_proto == ATM_SIG_UNI30) {
881 msg->msg_ie_aalp->ie_aalp_4_mid_range =
882 ap->aal.v.aal4.mid_high &
883 UNI_IE_AALP_A3_R_MASK;
885 msg->msg_ie_aalp->ie_aalp_4_mid_range =
886 ((ap->aal.v.aal4.mid_low &
887 UNI_IE_AALP_A3_R_MASK)
888 << UNI_IE_AALP_A3_R_SHIFT)
890 (ap->aal.v.aal4.mid_high &
891 UNI_IE_AALP_A3_R_MASK);
896 msg->msg_ie_aalp->ie_aalp_5_fwd_max_sdu =
897 ap->aal.v.aal5.forward_max_SDU_size;
898 msg->msg_ie_aalp->ie_aalp_5_bkwd_max_sdu =
899 ap->aal.v.aal5.backward_max_SDU_size;
900 msg->msg_ie_aalp->ie_aalp_5_mode =
901 UNI_IE_AALP_A5_M_MSG;
902 msg->msg_ie_aalp->ie_aalp_5_sscs_type =
903 ap->aal.v.aal5.SSCS_type;
909 * Set traffic descriptor attributes
911 if (ap->traffic.tag == T_ATM_PRESENT) {
912 if (!msg->msg_ie_clrt) {
913 msg->msg_ie_clrt = (struct ie_generic *)
914 atm_allocate(&unisig_iepool);
915 if (msg->msg_ie_clrt == NULL) {
920 KM_COPY(&ie_clrt_absent,
921 &msg->msg_ie_clrt->ie_u.ie_clrt,
922 sizeof(ie_clrt_absent));
923 msg->msg_ie_clrt->ie_ident = UNI_IE_CLRT;
924 msg->msg_ie_clrt->ie_clrt_fwd_peak =
925 ap->traffic.v.forward.PCR_high_priority;
926 msg->msg_ie_clrt->ie_clrt_fwd_peak_01 =
927 ap->traffic.v.forward.PCR_all_traffic;
928 msg->msg_ie_clrt->ie_clrt_fwd_sust =
929 ap->traffic.v.forward.SCR_high_priority;
930 msg->msg_ie_clrt->ie_clrt_fwd_sust_01 =
931 ap->traffic.v.forward.SCR_all_traffic;
932 msg->msg_ie_clrt->ie_clrt_fwd_burst =
933 ap->traffic.v.forward.MBS_high_priority;
934 msg->msg_ie_clrt->ie_clrt_fwd_burst_01 =
935 ap->traffic.v.forward.MBS_all_traffic;
936 msg->msg_ie_clrt->ie_clrt_bkwd_peak =
937 ap->traffic.v.backward.PCR_high_priority;
938 msg->msg_ie_clrt->ie_clrt_bkwd_peak_01 =
939 ap->traffic.v.backward.PCR_all_traffic;
940 msg->msg_ie_clrt->ie_clrt_bkwd_sust =
941 ap->traffic.v.backward.SCR_high_priority;
942 msg->msg_ie_clrt->ie_clrt_bkwd_sust_01 =
943 ap->traffic.v.backward.SCR_all_traffic;
944 msg->msg_ie_clrt->ie_clrt_bkwd_burst =
945 ap->traffic.v.backward.MBS_high_priority;
946 msg->msg_ie_clrt->ie_clrt_bkwd_burst_01 =
947 ap->traffic.v.backward.MBS_all_traffic;
948 msg->msg_ie_clrt->ie_clrt_best_effort =
949 ap->traffic.v.best_effort;
950 msg->msg_ie_clrt->ie_clrt_tm_options = 0;
951 if (ap->traffic.v.forward.tagging) {
952 msg->msg_ie_clrt->ie_clrt_tm_options |=
953 UNI_IE_CLRT_TM_FWD_TAG;
955 if (ap->traffic.v.backward.tagging) {
956 msg->msg_ie_clrt->ie_clrt_tm_options |=
957 UNI_IE_CLRT_TM_BKWD_TAG;
959 if (msg->msg_ie_clrt->ie_clrt_tm_options == 0) {
960 msg->msg_ie_clrt->ie_clrt_tm_options =
966 * Set broadband bearer attributes
968 if (ap->bearer.tag == T_ATM_PRESENT) {
969 if (!msg->msg_ie_bbcp) {
970 msg->msg_ie_bbcp = (struct ie_generic *)
971 atm_allocate(&unisig_iepool);
972 if (msg->msg_ie_bbcp == NULL) {
977 KM_COPY(&ie_bbcp_absent,
978 &msg->msg_ie_bbcp->ie_u.ie_bbcp,
979 sizeof(ie_bbcp_absent));
980 msg->msg_ie_bbcp->ie_ident = UNI_IE_BBCP;
981 msg->msg_ie_bbcp->ie_bbcp_bearer_class =
982 ap->bearer.v.bearer_class;
983 msg->msg_ie_bbcp->ie_bbcp_traffic_type =
984 ap->bearer.v.traffic_type;
985 msg->msg_ie_bbcp->ie_bbcp_timing_req =
986 ap->bearer.v.timing_requirements;
987 msg->msg_ie_bbcp->ie_bbcp_clipping =
988 ap->bearer.v.clipping_susceptibility;
989 msg->msg_ie_bbcp->ie_bbcp_conn_config =
990 ap->bearer.v.connection_configuration;
994 * Set broadband high layer attributes
996 if (ap->bhli.tag == T_ATM_PRESENT) {
997 if (!msg->msg_ie_bhli) {
998 msg->msg_ie_bhli = (struct ie_generic *)
999 atm_allocate(&unisig_iepool);
1000 if (msg->msg_ie_bhli == NULL) {
1005 KM_COPY(&ie_bhli_absent,
1006 &msg->msg_ie_bhli->ie_u.ie_bhli,
1007 sizeof(ie_bhli_absent));
1008 msg->msg_ie_bhli->ie_ident = UNI_IE_BHLI;
1009 msg->msg_ie_bhli->ie_bhli_type = ap->bhli.v.ID_type;
1010 switch (ap->bhli.v.ID_type) {
1011 case T_ATM_ISO_APP_ID:
1012 KM_COPY(ap->bhli.v.ID.ISO_ID,
1013 msg->msg_ie_bhli->ie_bhli_info,
1014 sizeof(ap->bhli.v.ID.ISO_ID));
1016 case T_ATM_USER_APP_ID:
1017 KM_COPY(ap->bhli.v.ID.user_defined_ID,
1018 msg->msg_ie_bhli->ie_bhli_info,
1019 sizeof(ap->bhli.v.ID.user_defined_ID));
1021 case T_ATM_VENDOR_APP_ID:
1022 KM_COPY(ap->bhli.v.ID.vendor_ID.OUI,
1023 msg->msg_ie_bhli->ie_bhli_info,
1024 sizeof(ap->bhli.v.ID.vendor_ID.OUI));
1025 KM_COPY(ap->bhli.v.ID.vendor_ID.app_ID,
1026 &msg->msg_ie_bhli->ie_bhli_info[sizeof(ap->bhli.v.ID.vendor_ID.OUI)-1],
1027 sizeof(ap->bhli.v.ID.vendor_ID.app_ID));
1033 * Set Broadband low layer, user layer 2 and 3 attributes
1035 if (ap->blli.tag_l2 == T_ATM_PRESENT ||
1036 ap->blli.tag_l3 == T_ATM_PRESENT) {
1037 if (!msg->msg_ie_blli) {
1038 msg->msg_ie_blli = (struct ie_generic *)
1039 atm_allocate(&unisig_iepool);
1040 if (msg->msg_ie_blli == NULL) {
1045 KM_COPY(&ie_blli_absent,
1046 &msg->msg_ie_blli->ie_u.ie_blli,
1047 sizeof(ie_blli_absent));
1048 msg->msg_ie_blli->ie_ident = UNI_IE_BLLI;
1050 if (ap->blli.tag_l2 == T_ATM_PRESENT) {
1051 switch(ap->blli.v.layer_2_protocol.ID_type) {
1052 case T_ATM_SIMPLE_ID:
1053 msg->msg_ie_blli->ie_blli_l2_id =
1054 ap->blli.v.layer_2_protocol.ID.simple_ID;
1057 msg->msg_ie_blli->ie_blli_l2_id =
1058 UNI_IE_BLLI_L2P_USER;
1059 msg->msg_ie_blli->ie_blli_l2_user_proto =
1060 ap->blli.v.layer_2_protocol.ID.user_defined_ID;
1063 if (ap->blli.v.layer_2_protocol.ID_type !=
1065 msg->msg_ie_blli->ie_blli_l2_mode =
1066 ap->blli.v.layer_2_protocol.mode;
1067 msg->msg_ie_blli->ie_blli_l2_window =
1068 ap->blli.v.layer_2_protocol.window_size;
1072 if (ap->blli.tag_l3 == T_ATM_PRESENT) {
1073 switch (ap->blli.v.layer_3_protocol.ID_type) {
1074 case T_ATM_SIMPLE_ID:
1075 msg->msg_ie_blli->ie_blli_l3_id =
1076 ap->blli.v.layer_3_protocol.ID.simple_ID;
1080 msg->msg_ie_blli->ie_blli_l3_id =
1081 UNI_IE_BLLI_L3P_ISO9577;
1082 msg->msg_ie_blli->ie_blli_l3_ipi =
1083 ap->blli.v.layer_3_protocol.ID.IPI_ID;
1087 msg->msg_ie_blli->ie_blli_l3_id =
1088 UNI_IE_BLLI_L3P_ISO9577;
1089 msg->msg_ie_blli->ie_blli_l3_ipi =
1090 UNI_IE_BLLI_L3IPI_SNAP;
1091 KM_COPY(ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI,
1092 msg->msg_ie_blli->ie_blli_l3_oui,
1093 sizeof(msg->msg_ie_blli->ie_blli_l3_oui));
1094 KM_COPY(ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID,
1095 msg->msg_ie_blli->ie_blli_l3_pid,
1096 sizeof(msg->msg_ie_blli->ie_blli_l3_pid));
1100 msg->msg_ie_blli->ie_blli_l3_id =
1101 UNI_IE_BLLI_L3P_USER;
1102 msg->msg_ie_blli->ie_blli_l3_user_proto =
1103 ap->blli.v.layer_3_protocol.ID.user_defined_ID;
1106 if (ap->blli.v.layer_3_protocol.ID_type
1108 msg->msg_ie_blli->ie_blli_l3_mode =
1109 ap->blli.v.layer_3_protocol.mode;
1110 msg->msg_ie_blli->ie_blli_l3_packet_size =
1111 ap->blli.v.layer_3_protocol.packet_size;
1112 msg->msg_ie_blli->ie_blli_l3_window =
1113 ap->blli.v.layer_3_protocol.window_size;
1119 * Set the called party address and subaddress
1121 if (ap->called.tag == T_ATM_PRESENT) {
1122 if (!msg->msg_ie_cdad) {
1123 msg->msg_ie_cdad = (struct ie_generic *)
1124 atm_allocate(&unisig_iepool);
1125 if (msg->msg_ie_cdad == NULL) {
1130 KM_COPY(&ie_cdad_absent,
1131 &msg->msg_ie_cdad->ie_u.ie_cdad,
1132 sizeof(ie_cdad_absent));
1133 msg->msg_ie_cdad->ie_ident = UNI_IE_CDAD;
1134 ATM_ADDR_COPY(&ap->called.addr,
1135 &msg->msg_ie_cdad->ie_cdad_addr);
1137 if (ap->called.subaddr.address_format != T_ATM_ABSENT) {
1138 if (!msg->msg_ie_cdsa) {
1139 msg->msg_ie_cdsa = (struct ie_generic *)
1140 atm_allocate(&unisig_iepool);
1141 if (msg->msg_ie_cdsa == NULL) {
1146 KM_COPY(&ie_cdsa_absent,
1147 &msg->msg_ie_cdsa->ie_u.ie_cdsa,
1148 sizeof(ie_cdsa_absent));
1149 msg->msg_ie_cdsa->ie_ident = UNI_IE_CDSA;
1150 ATM_ADDR_COPY(&ap->called.subaddr,
1151 &msg->msg_ie_cdsa->ie_cdsa_addr);
1156 * Set the calling party address and subaddress
1159 if (ap->calling.tag == T_ATM_PRESENT) {
1160 if (!msg->msg_ie_cgad) {
1161 msg->msg_ie_cgad = (struct ie_generic *)
1162 atm_allocate(&unisig_iepool);
1163 if (msg->msg_ie_cgad == NULL) {
1168 KM_COPY(&ie_cgad_absent,
1169 &msg->msg_ie_cgad->ie_u.ie_cgad,
1170 sizeof(ie_cgad_absent));
1171 msg->msg_ie_cgsa->ie_ident = UNI_IE_CGSA;
1172 ATM_ADDR_COPY(&ap->calling.addr,
1173 &msg->msg_ie_cgad->ie_cgad_addr);
1175 if (ap->calling.subaddr.address_format !=
1177 if (!msg->msg_ie_cgsa) {
1178 msg->msg_ie_cgsa = (struct ie_generic *)
1179 atm_allocate(&unisig_iepool);
1180 if (msg->msg_ie_cgsa == NULL) {
1185 KM_COPY(&ie_cgsa_absent,
1186 &msg->msg_ie_cgsa->ie_u.ie_cgsa,
1187 sizeof(ie_cgsa_absent));
1188 msg->msg_ie_cgsa->ie_ident = UNI_IE_CGSA;
1189 ATM_ADDR_COPY(&ap->calling.subaddr,
1190 &msg->msg_ie_cgsa->ie_cgsa_addr);
1195 * Set quality of service attributes
1197 if (ap->qos.tag == T_ATM_PRESENT) {
1198 if (!msg->msg_ie_qosp) {
1199 msg->msg_ie_qosp = (struct ie_generic *)
1200 atm_allocate(&unisig_iepool);
1201 if (msg->msg_ie_qosp == NULL) {
1206 KM_COPY(&ie_qosp_absent,
1207 &msg->msg_ie_qosp->ie_u.ie_qosp,
1208 sizeof(ie_qosp_absent));
1209 msg->msg_ie_qosp->ie_ident = UNI_IE_QOSP;
1210 if (usp->us_proto == ATM_SIG_UNI30)
1211 msg->msg_ie_qosp->ie_coding = UNI_IE_CODE_STD;
1212 else if ((ap->qos.v.forward.qos_class ==
1213 T_ATM_QOS_CLASS_0) ||
1214 (ap->qos.v.backward.qos_class ==
1216 msg->msg_ie_qosp->ie_coding = UNI_IE_CODE_CCITT;
1218 msg->msg_ie_qosp->ie_coding = ap->qos.v.coding_standard;
1219 msg->msg_ie_qosp->ie_qosp_fwd_class =
1220 ap->qos.v.forward.qos_class;
1221 msg->msg_ie_qosp->ie_qosp_bkwd_class =
1222 ap->qos.v.backward.qos_class;
1226 * Set transit network attributes
1228 if (ap->transit.tag == T_ATM_PRESENT &&
1229 ap->transit.v.length != 0) {
1230 if (!msg->msg_ie_trnt) {
1231 msg->msg_ie_trnt = (struct ie_generic *)
1232 atm_allocate(&unisig_iepool);
1233 if (msg->msg_ie_trnt == NULL) {
1238 KM_COPY(&ie_trnt_absent,
1239 &msg->msg_ie_trnt->ie_u.ie_trnt,
1240 sizeof(ie_trnt_absent));
1241 msg->msg_ie_trnt->ie_ident = UNI_IE_TRNT;
1242 msg->msg_ie_trnt->ie_trnt_id_type =
1243 UNI_IE_TRNT_IDT_NATL;
1244 msg->msg_ie_trnt->ie_trnt_id_plan =
1245 UNI_IE_TRNT_IDP_CIC;
1246 KM_COPY(ap->transit.v.network_id,
1247 msg->msg_ie_trnt->ie_trnt_id,
1248 ap->transit.v.length);
1254 if (ap->cause.tag == T_ATM_PRESENT) {
1255 if (!msg->msg_ie_caus) {
1256 msg->msg_ie_caus = (struct ie_generic *)
1257 atm_allocate(&unisig_iepool);
1258 if (msg->msg_ie_caus == NULL) {
1263 KM_COPY(&ie_caus_absent,
1264 &msg->msg_ie_caus->ie_u.ie_caus,
1265 sizeof(ie_caus_absent));
1266 msg->msg_ie_caus->ie_ident = UNI_IE_CAUS;
1267 msg->msg_ie_caus->ie_coding =
1268 ap->cause.v.coding_standard;
1269 msg->msg_ie_caus->ie_caus_loc =
1270 ap->cause.v.location;
1271 msg->msg_ie_caus->ie_caus_cause =
1272 ap->cause.v.cause_value;
1275 * Don't copy the diagnostics from the attribute
1276 * block, as there's no way to tell how much of
1277 * the diagnostic field is relevant
1279 msg->msg_ie_caus->ie_caus_diag_len = 0;