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.3 2003/08/07 21:17:36 dillon Exp $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
38 #include <netatm/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(aap, cause)
85 if (cause == T_ATM_ABSENT)
89 * Set the fields in the attribute block
91 aap->cause.tag = T_ATM_PRESENT;
92 aap->cause.v.coding_standard = T_ATM_ITU_CODING;
93 aap->cause.v.location = T_ATM_LOC_USER;
94 aap->cause.v.cause_value = cause;
95 KM_ZERO(aap->cause.v.diagnostics,
96 sizeof(aap->cause.v.diagnostics));
101 * Set a cause code in an ATM attribute block from a Cause IE
104 * aap pointer to attribute block
105 * iep pointer to Cause IE
112 unisig_cause_attr_from_ie(aap, iep)
114 struct ie_generic *iep;
117 * Set the fields in the attribute block
119 aap->cause.tag = T_ATM_PRESENT;
120 aap->cause.v.coding_standard = iep->ie_coding;
121 aap->cause.v.location = iep->ie_caus_loc;
122 aap->cause.v.cause_value = iep->ie_caus_cause;
123 KM_ZERO(aap->cause.v.diagnostics, sizeof(aap->cause.v.diagnostics));
124 KM_COPY(iep->ie_caus_diagnostic, aap->cause.v.diagnostics,
125 MIN(sizeof(aap->cause.v.diagnostics), iep->ie_caus_diag_len));
132 * Called when a user wants to open a VC. This function will construct
133 * a VCCB and, if we are opening an SVC, call the Q.2931 VC state
134 * machine. The user will have to wait for a notify event to be sure
135 * the SVC is fully open.
137 * Must be called at splnet.
140 * usp pointer to UNISIG protocol instance
141 * cvp pointer to connection parameters for the VCC
144 * 0 VCC creation successful
145 * errno VCC setup failed - reason indicated
149 unisig_open_vcc(usp, cvp)
153 struct atm_pif *pip = usp->us_pif;
154 struct unisig_vccb *uvp;
158 ATM_DEBUG2("unisig_open_vcc: usp=%p, cvp=%p\n", usp, cvp);
161 * Validate user parameters. AAL and encapsulation are
162 * checked by the connection manager
166 * Check called party address(es)
168 if(cvp->cvc_attr.called.tag != T_ATM_PRESENT ||
169 cvp->cvc_attr.called.addr.address_format ==
173 switch (cvp->cvc_attr.called.addr.address_format) {
176 * Make sure VPI/VCI is valid
179 pvp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
180 if ((ATM_PVC_GET_VPI(pvp) > pip->pif_maxvpi) ||
181 (ATM_PVC_GET_VCI(pvp) == 0) ||
182 (ATM_PVC_GET_VCI(pvp) > pip->pif_maxvci)) {
187 * Make sure VPI/VCI is not already in use
189 if (unisig_find_vpvc(usp,
190 ATM_PVC_GET_VPI(pvp),
191 ATM_PVC_GET_VCI(pvp), 0)) {
194 ATM_DEBUG2("unisig_open_vcc: VPI.VCI=%d.%d\n",
195 ATM_PVC_GET_VPI(pvp),
196 ATM_PVC_GET_VCI(pvp));
199 case T_ATM_ENDSYS_ADDR:
201 * Check signalling state
205 if (usp->us_state != UNISIG_ACTIVE) {
210 * Make sure there's no subaddress
212 if (cvp->cvc_attr.called.subaddr.address_format !=
218 case T_ATM_E164_ADDR:
220 * Check signalling state
224 if (usp->us_state != UNISIG_ACTIVE) {
229 * Check destination address format
231 if (cvp->cvc_attr.called.subaddr.address_format !=
233 cvp->cvc_attr.called.subaddr.address_format !=
240 return(EPROTONOSUPPORT);
244 * Check that this is for the same interface UNISIG uses
246 if (!cvp->cvc_attr.nif ||
247 cvp->cvc_attr.nif->nif_pif != usp->us_pif) {
252 * Allocate control block for VCC
254 uvp = (struct unisig_vccb *)atm_allocate(&unisig_vcpool);
263 uvp->uv_type = VCC_PVC | VCC_IN | VCC_OUT;
264 uvp->uv_vpi = ATM_PVC_GET_VPI(pvp);
265 uvp->uv_vci = ATM_PVC_GET_VCI(pvp);
266 uvp->uv_sstate = (usp->us_state == UNISIG_ACTIVE ?
267 UNI_PVC_ACTIVE : UNI_PVC_ACT_DOWN);
268 uvp->uv_ustate = VCCU_OPEN;
270 uvp->uv_type = VCC_SVC | VCC_IN | VCC_OUT;
271 uvp->uv_sstate = UNI_NULL;
272 uvp->uv_ustate = VCCU_POPEN;
274 uvp->uv_proto = usp->us_pif->pif_sigmgr->sm_proto;
275 uvp->uv_pif = usp->us_pif;
276 uvp->uv_nif = cvp->cvc_attr.nif;
277 uvp->uv_connvc = cvp;
278 uvp->uv_tstamp = time_second;
281 * Put VCCB on UNISIG queue
283 ENQUEUE(uvp, struct unisig_vccb, uv_sigelem, usp->us_vccq);
286 * Call the VC state machine if this is an SVC
289 err = unisig_vc_state(usp, uvp, UNI_VC_SETUP_CALL,
290 (struct unisig_msg *) 0);
293 * On error, delete the VCCB
295 DEQUEUE(uvp, struct unisig_vccb, uv_sigelem,
297 atm_free((caddr_t)uvp);
303 * Link VCCB to VCC connection block
305 cvp->cvc_vcc = (struct vccb *) uvp;
314 * Called when a user wants to close a VCC. This function will clean
315 * up the VCCB and, for an SVC, send a close request.
317 * Must be called at splnet.
320 * usp pointer to UNISIG protocol instance
321 * uvp pointer to VCCB for the VCC to be closed
324 * 0 VCC is now closed
325 * errno error encountered
328 unisig_close_vcc(usp, uvp)
330 struct unisig_vccb *uvp;
334 ATM_DEBUG2("unisig_close_vcc: uvp=%p, state=%d\n", uvp,
338 * Check that this is for the same interface UNISIG uses
340 if (uvp->uv_pif != usp->us_pif) {
345 * Mark the close time.
347 uvp->uv_tstamp = time_second;
350 * Process based on the connection type
352 if (uvp->uv_type & VCC_PVC) {
353 uvp->uv_sstate = UNI_FREE;
354 uvp->uv_ustate = VCCU_CLOSED;
355 } else if (uvp->uv_type & VCC_SVC) {
357 * Call the VC state machine
359 uvp->uv_ustate = VCCU_CLOSED;
360 err = unisig_vc_state(usp, uvp, UNI_VC_RELEASE_CALL,
361 (struct unisig_msg *) 0);
365 * Wait for user to free resources
374 * Called to internally clear a VCC. No external protocol is
375 * initiated, the VCC is just closed and the owner is notified.
377 * Must be called at splnet.
380 * usp pointer to UNISIG protocol instance
381 * uvp pointer to VCCB for the VCC to be closed
382 * cause cause code giving the reason for the close
386 * errno error encountered
389 unisig_clear_vcc(usp, uvp, cause)
391 struct unisig_vccb *uvp;
396 ATM_DEBUG3("unisig_clear_vcc: uvp=%p, state=%d, cause=%d\n",
397 uvp, uvp->uv_sstate, cause);
400 * Check that this is for the same interface UNISIG uses
402 if (uvp->uv_pif != usp->us_pif) {
407 * Kill any possible timer
409 UNISIG_VC_CANCEL((struct vccb *) uvp);
412 * Mark the close time.
414 uvp->uv_tstamp = time_second;
417 * Close the VCC and notify the user
419 outstate = uvp->uv_sstate;
420 uvp->uv_sstate = UNI_FREE;
421 uvp->uv_ustate = VCCU_CLOSED;
422 if (outstate == UNI_ACTIVE ||
423 outstate == UNI_CALL_INITIATED ||
424 outstate == UNI_CALL_OUT_PROC ||
425 outstate == UNI_CONNECT_REQUEST ||
426 outstate == UNI_RELEASE_REQUEST ||
427 outstate == UNI_RELEASE_IND ||
428 outstate == UNI_SSCF_RECOV ||
429 outstate == UNI_PVC_ACT_DOWN ||
430 outstate == UNI_PVC_ACTIVE) {
431 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr, cause);
432 atm_cm_cleared(uvp->uv_connvc);
436 * Wait for user to free resources
444 * Reset the switch state
447 * usp pointer to UNISIG protocol instance
454 unisig_switch_reset(usp, cause)
459 struct unisig_vccb *uvp, *vnext;
461 ATM_DEBUG2("unisig_switch_reset: usp=%p, cause=%d\n",
465 * Terminate all of our VCCs
468 for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp;
470 vnext = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem);
472 if (uvp->uv_type & VCC_SVC) {
474 * Close the SVC and notify the owner
476 (void)unisig_clear_vcc(usp, uvp,
477 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
478 } else if (uvp->uv_type & VCC_PVC) {
480 * Notify PVC owner of the state change
484 uvp->uv_sstate = UNI_PVC_ACT_DOWN;
487 uvp->uv_sstate = UNI_PVC_ACTIVE;
490 atm_cm_cleared(uvp->uv_connvc, cause);
492 log(LOG_ERR, "unisig: invalid VCC type: vccb=%p, type=%d\n",
502 * Copy connection parameters from UNI 3.0 message IEs into
506 * usp pointer to UNISIG protocol instance
507 * msg pointer to the SETUP message
508 * ap pointer to the attribute block
515 unisig_save_attrs(usp, msg, ap)
517 struct unisig_msg *msg;
527 * Save the AAL parameters (AAL 3/4 and AAL 5 only)
529 if (msg->msg_ie_aalp) {
530 struct ie_generic *aalp = msg->msg_ie_aalp;
532 switch(msg->msg_ie_aalp->ie_aalp_aal_type) {
533 case UNI_IE_AALP_AT_AAL3:
534 ap->aal.tag = T_ATM_PRESENT;
536 msg->msg_ie_aalp->ie_aalp_aal_type;
537 ap->aal.v.aal4.forward_max_SDU_size =
538 msg->msg_ie_aalp->ie_aalp_4_fwd_max_sdu;
539 ap->aal.v.aal4.backward_max_SDU_size =
540 msg->msg_ie_aalp->ie_aalp_4_bkwd_max_sdu;
541 ap->aal.v.aal4.SSCS_type =
542 msg->msg_ie_aalp->ie_aalp_4_sscs_type;
543 if (aalp->ie_aalp_4_mid_range == T_ATM_ABSENT) {
544 ap->aal.v.aal4.mid_low = T_ATM_ABSENT;
545 ap->aal.v.aal4.mid_high = T_ATM_ABSENT;
547 if (usp->us_proto == ATM_SIG_UNI30) {
548 ap->aal.v.aal4.mid_low = 0;
549 ap->aal.v.aal4.mid_high =
550 aalp->ie_aalp_4_mid_range
551 & UNI_IE_AALP_A3_R_MASK;
553 ap->aal.v.aal4.mid_low =
554 (aalp->ie_aalp_4_mid_range >>
555 UNI_IE_AALP_A3_R_SHIFT)
556 & UNI_IE_AALP_A3_R_MASK;
557 ap->aal.v.aal4.mid_high =
558 aalp->ie_aalp_4_mid_range
559 & UNI_IE_AALP_A3_R_MASK;
563 case UNI_IE_AALP_AT_AAL5:
564 ap->aal.tag = T_ATM_PRESENT;
566 msg->msg_ie_aalp->ie_aalp_aal_type;
567 ap->aal.v.aal5.forward_max_SDU_size =
568 msg->msg_ie_aalp->ie_aalp_5_fwd_max_sdu;
569 ap->aal.v.aal5.backward_max_SDU_size =
570 msg->msg_ie_aalp->ie_aalp_5_bkwd_max_sdu;
571 ap->aal.v.aal5.SSCS_type =
572 msg->msg_ie_aalp->ie_aalp_5_sscs_type;
578 * Save traffic descriptor attributes
580 if (msg->msg_ie_clrt) {
581 ap->traffic.tag = T_ATM_PRESENT;
582 ap->traffic.v.forward.PCR_high_priority =
583 msg->msg_ie_clrt->ie_clrt_fwd_peak;
584 ap->traffic.v.forward.PCR_all_traffic =
585 msg->msg_ie_clrt->ie_clrt_fwd_peak_01;
586 ap->traffic.v.forward.SCR_high_priority =
587 msg->msg_ie_clrt->ie_clrt_fwd_sust;
588 ap->traffic.v.forward.SCR_all_traffic =
589 msg->msg_ie_clrt->ie_clrt_fwd_sust_01;
590 ap->traffic.v.forward.MBS_high_priority =
591 msg->msg_ie_clrt->ie_clrt_fwd_burst;
592 ap->traffic.v.forward.MBS_all_traffic =
593 msg->msg_ie_clrt->ie_clrt_fwd_burst_01;
594 ap->traffic.v.backward.PCR_high_priority =
595 msg->msg_ie_clrt->ie_clrt_bkwd_peak;
596 ap->traffic.v.backward.PCR_all_traffic =
597 msg->msg_ie_clrt->ie_clrt_bkwd_peak_01;
598 ap->traffic.v.backward.SCR_high_priority =
599 msg->msg_ie_clrt->ie_clrt_bkwd_sust;
600 ap->traffic.v.backward.SCR_all_traffic =
601 msg->msg_ie_clrt->ie_clrt_bkwd_sust_01;
602 ap->traffic.v.backward.MBS_high_priority =
603 msg->msg_ie_clrt->ie_clrt_bkwd_burst;
604 ap->traffic.v.backward.MBS_all_traffic =
605 msg->msg_ie_clrt->ie_clrt_bkwd_burst_01;
606 ap->traffic.v.best_effort =
607 msg->msg_ie_clrt->ie_clrt_best_effort;
608 if (msg->msg_ie_clrt->ie_clrt_tm_options ==
610 ap->traffic.v.forward.tagging = T_NO;
611 ap->traffic.v.backward.tagging = T_NO;
613 ap->traffic.v.forward.tagging =
614 (msg->msg_ie_clrt->ie_clrt_tm_options &
615 UNI_IE_CLRT_TM_FWD_TAG) != 0;
616 ap->traffic.v.backward.tagging =
617 (msg->msg_ie_clrt->ie_clrt_tm_options &
618 UNI_IE_CLRT_TM_BKWD_TAG) != 0;
623 * Save broadband bearer attributes
625 if (msg->msg_ie_bbcp) {
626 ap->bearer.tag = T_ATM_PRESENT;
627 ap->bearer.v.bearer_class =
628 msg->msg_ie_bbcp->ie_bbcp_bearer_class;
629 ap->bearer.v.traffic_type =
630 msg->msg_ie_bbcp->ie_bbcp_traffic_type;
631 ap->bearer.v.timing_requirements =
632 msg->msg_ie_bbcp->ie_bbcp_timing_req;
633 ap->bearer.v.clipping_susceptibility =
634 msg->msg_ie_bbcp->ie_bbcp_clipping;
635 ap->bearer.v.connection_configuration =
636 msg->msg_ie_bbcp->ie_bbcp_conn_config;
640 * Save broadband high layer attributes
642 if (msg->msg_ie_bhli) {
643 ap->bhli.tag = T_ATM_PRESENT;
644 ap->bhli.v.ID_type = msg->msg_ie_bhli->ie_bhli_type;
645 switch(ap->bhli.v.ID_type) {
646 case T_ATM_ISO_APP_ID:
647 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
648 ap->bhli.v.ID.ISO_ID,
649 sizeof(ap->bhli.v.ID.ISO_ID));
651 case T_ATM_USER_APP_ID:
652 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
653 ap->bhli.v.ID.user_defined_ID,
654 sizeof(ap->bhli.v.ID.user_defined_ID));
656 case T_ATM_VENDOR_APP_ID:
657 KM_COPY(msg->msg_ie_bhli->ie_bhli_info,
658 ap->bhli.v.ID.vendor_ID.OUI,
659 sizeof(ap->bhli.v.ID.vendor_ID.OUI));
660 KM_COPY(&msg->msg_ie_bhli->ie_bhli_info[sizeof(ap->bhli.v.ID.vendor_ID.OUI)-1],
661 ap->bhli.v.ID.vendor_ID.app_ID,
662 sizeof(ap->bhli.v.ID.vendor_ID.app_ID));
668 * Save Broadband low layer, user layer 2 and 3 attributes
670 if (msg->msg_ie_blli) {
674 switch(msg->msg_ie_blli->ie_blli_l2_id) {
675 case UNI_IE_BLLI_L2P_ISO1745:
676 case UNI_IE_BLLI_L2P_Q921:
677 case UNI_IE_BLLI_L2P_X25L:
678 case UNI_IE_BLLI_L2P_X25M:
679 case UNI_IE_BLLI_L2P_LAPB:
680 case UNI_IE_BLLI_L2P_HDLC1:
681 case UNI_IE_BLLI_L2P_HDLC2:
682 case UNI_IE_BLLI_L2P_HDLC3:
683 case UNI_IE_BLLI_L2P_LLC:
684 case UNI_IE_BLLI_L2P_X75:
685 case UNI_IE_BLLI_L2P_Q922:
686 case UNI_IE_BLLI_L2P_ISO7776:
687 ap->blli.tag_l2 = T_ATM_PRESENT;
688 ap->blli.v.layer_2_protocol.ID_type =
690 ap->blli.v.layer_2_protocol.ID.simple_ID =
691 msg->msg_ie_blli->ie_blli_l2_id;
693 case UNI_IE_BLLI_L2P_USER:
694 ap->blli.tag_l2 = T_ATM_PRESENT;
695 ap->blli.v.layer_2_protocol.ID_type =
697 ap->blli.v.layer_2_protocol.ID.user_defined_ID =
698 msg->msg_ie_blli->ie_blli_l2_user_proto;
701 ap->blli.tag_l2 = T_ATM_ABSENT;
703 if (ap->blli.tag_l2 == T_ATM_PRESENT) {
704 ap->blli.v.layer_2_protocol.mode =
705 msg->msg_ie_blli->ie_blli_l2_mode;
706 ap->blli.v.layer_2_protocol.window_size =
707 msg->msg_ie_blli->ie_blli_l2_window;
713 switch(msg->msg_ie_blli->ie_blli_l3_id) {
714 case UNI_IE_BLLI_L3P_X25:
715 case UNI_IE_BLLI_L3P_ISO8208:
716 case UNI_IE_BLLI_L3P_ISO8878:
717 case UNI_IE_BLLI_L3P_ISO8473:
718 case UNI_IE_BLLI_L3P_T70:
719 ap->blli.tag_l3 = T_ATM_PRESENT;
720 ap->blli.v.layer_3_protocol.ID_type =
722 ap->blli.v.layer_3_protocol.ID.simple_ID =
723 msg->msg_ie_blli->ie_blli_l3_id;
725 case UNI_IE_BLLI_L3P_ISO9577:
726 ap->blli.tag_l3 = T_ATM_PRESENT;
727 ap->blli.v.layer_3_protocol.ID_type =
729 ap->blli.v.layer_3_protocol.ID.simple_ID =
730 msg->msg_ie_blli->ie_blli_l3_id;
731 if (msg->msg_ie_blli->ie_blli_l3_ipi ==
732 UNI_IE_BLLI_L3IPI_SNAP) {
733 KM_COPY(msg->msg_ie_blli->ie_blli_l3_oui,
734 ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI,
735 sizeof(ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI));
736 KM_COPY(msg->msg_ie_blli->ie_blli_l3_pid,
737 ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID,
738 sizeof(ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID));
740 ap->blli.v.layer_3_protocol.ID.IPI_ID =
741 msg->msg_ie_blli->ie_blli_l3_ipi;
744 case UNI_IE_BLLI_L3P_USER:
745 ap->blli.tag_l3 = T_ATM_PRESENT;
746 ap->blli.v.layer_3_protocol.ID_type =
748 ap->blli.v.layer_3_protocol.ID.user_defined_ID =
749 msg->msg_ie_blli->ie_blli_l3_user_proto;
752 ap->blli.tag_l3 = T_ATM_ABSENT;
754 if (ap->blli.tag_l3 == T_ATM_PRESENT) {
755 ap->blli.v.layer_3_protocol.mode =
756 msg->msg_ie_blli->ie_blli_l3_mode;
757 ap->blli.v.layer_3_protocol.packet_size =
758 msg->msg_ie_blli->ie_blli_l3_packet_size;
759 ap->blli.v.layer_3_protocol.window_size =
760 msg->msg_ie_blli->ie_blli_l3_window;
765 * Save the called party address and subaddress
767 if (msg->msg_ie_cdad) {
768 ap->called.tag = T_ATM_PRESENT;
769 ATM_ADDR_COPY(&msg->msg_ie_cdad->ie_cdad_addr,
771 ap->called.subaddr.address_format = T_ATM_ABSENT;
772 ap->called.subaddr.address_length = 0;
774 if (msg->msg_ie_cdsa) {
775 ATM_ADDR_COPY(&msg->msg_ie_cdsa->ie_cdsa_addr,
776 &ap->called.subaddr);
780 * Save the calling party address and subaddress
782 if (msg->msg_ie_cgad) {
783 ap->calling.tag = T_ATM_PRESENT;
784 ATM_ADDR_COPY(&msg->msg_ie_cgad->ie_cgad_addr,
786 ap->calling.subaddr.address_format = T_ATM_ABSENT;
787 ap->calling.subaddr.address_length = 0;
790 if (msg->msg_ie_cgsa) {
791 ATM_ADDR_COPY(&msg->msg_ie_cgsa->ie_cgsa_addr,
792 &ap->calling.subaddr);
796 * Save quality of service attributes
798 if (msg->msg_ie_qosp) {
799 ap->qos.tag = T_ATM_PRESENT;
800 ap->qos.v.coding_standard = msg->msg_ie_qosp->ie_coding;
801 ap->qos.v.forward.qos_class = msg->msg_ie_qosp->ie_qosp_fwd_class;
802 ap->qos.v.forward.qos_class =
803 msg->msg_ie_qosp->ie_qosp_bkwd_class;
807 * Save transit network attributes
809 if (msg->msg_ie_trnt) {
810 ap->transit.tag = T_ATM_PRESENT;
811 ap->transit.v.length =
812 MIN(msg->msg_ie_trnt->ie_trnt_id_len,
813 sizeof(ap->transit.v.network_id));
814 KM_COPY(msg->msg_ie_trnt->ie_trnt_id,
815 ap->transit.v.network_id,
816 ap->transit.v.length);
822 if (msg->msg_ie_caus) {
823 ap->cause.tag = T_ATM_PRESENT;
824 ap->cause.v.coding_standard =
825 msg->msg_ie_caus->ie_coding;
826 ap->cause.v.location =
827 msg->msg_ie_caus->ie_caus_loc;
828 ap->cause.v.cause_value =
829 msg->msg_ie_caus->ie_caus_cause;
830 KM_ZERO(ap->cause.v.diagnostics,
831 sizeof(ap->cause.v.diagnostics));
833 KM_COPY(msg->msg_ie_caus->ie_caus_diagnostic,
834 ap->transit.v.diagnostics,
835 MIN(sizeof(ap->transit.v.diagnostics),
836 msg->msg_ie_caus->ie_caus_diag_len));
843 * Copy connection parameters from an attribute block into
844 * UNI 3.0 message IEs
847 * usp pointer to UNISIG protocol instance
848 * msg pointer to the SETUP message
849 * ap pointer to the attribute block
853 * else error encountered
857 unisig_set_attrs(usp, msg, ap)
859 struct unisig_msg *msg;
871 * Set the AAL parameters (AAL 3/4 and AAL 5 only)
873 if (ap->aal.tag == T_ATM_PRESENT) {
874 if (!msg->msg_ie_aalp) {
875 msg->msg_ie_aalp = (struct ie_generic *)
876 atm_allocate(&unisig_iepool);
877 if (msg->msg_ie_aalp == NULL) {
882 KM_COPY(&ie_aalp_absent,
883 &msg->msg_ie_aalp->ie_u.ie_aalp,
884 sizeof(ie_aalp_absent));
885 msg->msg_ie_aalp->ie_ident = UNI_IE_AALP;
886 msg->msg_ie_aalp->ie_aalp_aal_type = ap->aal.type;
887 switch(ap->aal.type) {
889 msg->msg_ie_aalp->ie_aalp_4_fwd_max_sdu =
890 ap->aal.v.aal4.forward_max_SDU_size;
891 msg->msg_ie_aalp->ie_aalp_4_bkwd_max_sdu =
892 ap->aal.v.aal4.backward_max_SDU_size;
893 msg->msg_ie_aalp->ie_aalp_4_mode = UNI_IE_AALP_A5_M_MSG;
894 msg->msg_ie_aalp->ie_aalp_4_sscs_type =
895 ap->aal.v.aal4.SSCS_type;
896 if (ap->aal.v.aal4.mid_low == T_ATM_ABSENT) {
897 msg->msg_ie_aalp->ie_aalp_4_mid_range =
900 if (usp->us_proto == ATM_SIG_UNI30) {
901 msg->msg_ie_aalp->ie_aalp_4_mid_range =
902 ap->aal.v.aal4.mid_high &
903 UNI_IE_AALP_A3_R_MASK;
905 msg->msg_ie_aalp->ie_aalp_4_mid_range =
906 ((ap->aal.v.aal4.mid_low &
907 UNI_IE_AALP_A3_R_MASK)
908 << UNI_IE_AALP_A3_R_SHIFT)
910 (ap->aal.v.aal4.mid_high &
911 UNI_IE_AALP_A3_R_MASK);
916 msg->msg_ie_aalp->ie_aalp_5_fwd_max_sdu =
917 ap->aal.v.aal5.forward_max_SDU_size;
918 msg->msg_ie_aalp->ie_aalp_5_bkwd_max_sdu =
919 ap->aal.v.aal5.backward_max_SDU_size;
920 msg->msg_ie_aalp->ie_aalp_5_mode =
921 UNI_IE_AALP_A5_M_MSG;
922 msg->msg_ie_aalp->ie_aalp_5_sscs_type =
923 ap->aal.v.aal5.SSCS_type;
929 * Set traffic descriptor attributes
931 if (ap->traffic.tag == T_ATM_PRESENT) {
932 if (!msg->msg_ie_clrt) {
933 msg->msg_ie_clrt = (struct ie_generic *)
934 atm_allocate(&unisig_iepool);
935 if (msg->msg_ie_clrt == NULL) {
940 KM_COPY(&ie_clrt_absent,
941 &msg->msg_ie_clrt->ie_u.ie_clrt,
942 sizeof(ie_clrt_absent));
943 msg->msg_ie_clrt->ie_ident = UNI_IE_CLRT;
944 msg->msg_ie_clrt->ie_clrt_fwd_peak =
945 ap->traffic.v.forward.PCR_high_priority;
946 msg->msg_ie_clrt->ie_clrt_fwd_peak_01 =
947 ap->traffic.v.forward.PCR_all_traffic;
948 msg->msg_ie_clrt->ie_clrt_fwd_sust =
949 ap->traffic.v.forward.SCR_high_priority;
950 msg->msg_ie_clrt->ie_clrt_fwd_sust_01 =
951 ap->traffic.v.forward.SCR_all_traffic;
952 msg->msg_ie_clrt->ie_clrt_fwd_burst =
953 ap->traffic.v.forward.MBS_high_priority;
954 msg->msg_ie_clrt->ie_clrt_fwd_burst_01 =
955 ap->traffic.v.forward.MBS_all_traffic;
956 msg->msg_ie_clrt->ie_clrt_bkwd_peak =
957 ap->traffic.v.backward.PCR_high_priority;
958 msg->msg_ie_clrt->ie_clrt_bkwd_peak_01 =
959 ap->traffic.v.backward.PCR_all_traffic;
960 msg->msg_ie_clrt->ie_clrt_bkwd_sust =
961 ap->traffic.v.backward.SCR_high_priority;
962 msg->msg_ie_clrt->ie_clrt_bkwd_sust_01 =
963 ap->traffic.v.backward.SCR_all_traffic;
964 msg->msg_ie_clrt->ie_clrt_bkwd_burst =
965 ap->traffic.v.backward.MBS_high_priority;
966 msg->msg_ie_clrt->ie_clrt_bkwd_burst_01 =
967 ap->traffic.v.backward.MBS_all_traffic;
968 msg->msg_ie_clrt->ie_clrt_best_effort =
969 ap->traffic.v.best_effort;
970 msg->msg_ie_clrt->ie_clrt_tm_options = 0;
971 if (ap->traffic.v.forward.tagging) {
972 msg->msg_ie_clrt->ie_clrt_tm_options |=
973 UNI_IE_CLRT_TM_FWD_TAG;
975 if (ap->traffic.v.backward.tagging) {
976 msg->msg_ie_clrt->ie_clrt_tm_options |=
977 UNI_IE_CLRT_TM_BKWD_TAG;
979 if (msg->msg_ie_clrt->ie_clrt_tm_options == 0) {
980 msg->msg_ie_clrt->ie_clrt_tm_options =
986 * Set broadband bearer attributes
988 if (ap->bearer.tag == T_ATM_PRESENT) {
989 if (!msg->msg_ie_bbcp) {
990 msg->msg_ie_bbcp = (struct ie_generic *)
991 atm_allocate(&unisig_iepool);
992 if (msg->msg_ie_bbcp == NULL) {
997 KM_COPY(&ie_bbcp_absent,
998 &msg->msg_ie_bbcp->ie_u.ie_bbcp,
999 sizeof(ie_bbcp_absent));
1000 msg->msg_ie_bbcp->ie_ident = UNI_IE_BBCP;
1001 msg->msg_ie_bbcp->ie_bbcp_bearer_class =
1002 ap->bearer.v.bearer_class;
1003 msg->msg_ie_bbcp->ie_bbcp_traffic_type =
1004 ap->bearer.v.traffic_type;
1005 msg->msg_ie_bbcp->ie_bbcp_timing_req =
1006 ap->bearer.v.timing_requirements;
1007 msg->msg_ie_bbcp->ie_bbcp_clipping =
1008 ap->bearer.v.clipping_susceptibility;
1009 msg->msg_ie_bbcp->ie_bbcp_conn_config =
1010 ap->bearer.v.connection_configuration;
1014 * Set broadband high layer attributes
1016 if (ap->bhli.tag == T_ATM_PRESENT) {
1017 if (!msg->msg_ie_bhli) {
1018 msg->msg_ie_bhli = (struct ie_generic *)
1019 atm_allocate(&unisig_iepool);
1020 if (msg->msg_ie_bhli == NULL) {
1025 KM_COPY(&ie_bhli_absent,
1026 &msg->msg_ie_bhli->ie_u.ie_bhli,
1027 sizeof(ie_bhli_absent));
1028 msg->msg_ie_bhli->ie_ident = UNI_IE_BHLI;
1029 msg->msg_ie_bhli->ie_bhli_type = ap->bhli.v.ID_type;
1030 switch (ap->bhli.v.ID_type) {
1031 case T_ATM_ISO_APP_ID:
1032 KM_COPY(ap->bhli.v.ID.ISO_ID,
1033 msg->msg_ie_bhli->ie_bhli_info,
1034 sizeof(ap->bhli.v.ID.ISO_ID));
1036 case T_ATM_USER_APP_ID:
1037 KM_COPY(ap->bhli.v.ID.user_defined_ID,
1038 msg->msg_ie_bhli->ie_bhli_info,
1039 sizeof(ap->bhli.v.ID.user_defined_ID));
1041 case T_ATM_VENDOR_APP_ID:
1042 KM_COPY(ap->bhli.v.ID.vendor_ID.OUI,
1043 msg->msg_ie_bhli->ie_bhli_info,
1044 sizeof(ap->bhli.v.ID.vendor_ID.OUI));
1045 KM_COPY(ap->bhli.v.ID.vendor_ID.app_ID,
1046 &msg->msg_ie_bhli->ie_bhli_info[sizeof(ap->bhli.v.ID.vendor_ID.OUI)-1],
1047 sizeof(ap->bhli.v.ID.vendor_ID.app_ID));
1053 * Set Broadband low layer, user layer 2 and 3 attributes
1055 if (ap->blli.tag_l2 == T_ATM_PRESENT ||
1056 ap->blli.tag_l3 == T_ATM_PRESENT) {
1057 if (!msg->msg_ie_blli) {
1058 msg->msg_ie_blli = (struct ie_generic *)
1059 atm_allocate(&unisig_iepool);
1060 if (msg->msg_ie_blli == NULL) {
1065 KM_COPY(&ie_blli_absent,
1066 &msg->msg_ie_blli->ie_u.ie_blli,
1067 sizeof(ie_blli_absent));
1068 msg->msg_ie_blli->ie_ident = UNI_IE_BLLI;
1070 if (ap->blli.tag_l2 == T_ATM_PRESENT) {
1071 switch(ap->blli.v.layer_2_protocol.ID_type) {
1072 case T_ATM_SIMPLE_ID:
1073 msg->msg_ie_blli->ie_blli_l2_id =
1074 ap->blli.v.layer_2_protocol.ID.simple_ID;
1077 msg->msg_ie_blli->ie_blli_l2_id =
1078 UNI_IE_BLLI_L2P_USER;
1079 msg->msg_ie_blli->ie_blli_l2_user_proto =
1080 ap->blli.v.layer_2_protocol.ID.user_defined_ID;
1083 if (ap->blli.v.layer_2_protocol.ID_type !=
1085 msg->msg_ie_blli->ie_blli_l2_mode =
1086 ap->blli.v.layer_2_protocol.mode;
1087 msg->msg_ie_blli->ie_blli_l2_window =
1088 ap->blli.v.layer_2_protocol.window_size;
1092 if (ap->blli.tag_l3 == T_ATM_PRESENT) {
1093 switch (ap->blli.v.layer_3_protocol.ID_type) {
1094 case T_ATM_SIMPLE_ID:
1095 msg->msg_ie_blli->ie_blli_l3_id =
1096 ap->blli.v.layer_3_protocol.ID.simple_ID;
1100 msg->msg_ie_blli->ie_blli_l3_id =
1101 UNI_IE_BLLI_L3P_ISO9577;
1102 msg->msg_ie_blli->ie_blli_l3_ipi =
1103 ap->blli.v.layer_3_protocol.ID.IPI_ID;
1107 msg->msg_ie_blli->ie_blli_l3_id =
1108 UNI_IE_BLLI_L3P_ISO9577;
1109 msg->msg_ie_blli->ie_blli_l3_ipi =
1110 UNI_IE_BLLI_L3IPI_SNAP;
1111 KM_COPY(ap->blli.v.layer_3_protocol.ID.SNAP_ID.OUI,
1112 msg->msg_ie_blli->ie_blli_l3_oui,
1113 sizeof(msg->msg_ie_blli->ie_blli_l3_oui));
1114 KM_COPY(ap->blli.v.layer_3_protocol.ID.SNAP_ID.PID,
1115 msg->msg_ie_blli->ie_blli_l3_pid,
1116 sizeof(msg->msg_ie_blli->ie_blli_l3_pid));
1120 msg->msg_ie_blli->ie_blli_l3_id =
1121 UNI_IE_BLLI_L3P_USER;
1122 msg->msg_ie_blli->ie_blli_l3_user_proto =
1123 ap->blli.v.layer_3_protocol.ID.user_defined_ID;
1126 if (ap->blli.v.layer_3_protocol.ID_type
1128 msg->msg_ie_blli->ie_blli_l3_mode =
1129 ap->blli.v.layer_3_protocol.mode;
1130 msg->msg_ie_blli->ie_blli_l3_packet_size =
1131 ap->blli.v.layer_3_protocol.packet_size;
1132 msg->msg_ie_blli->ie_blli_l3_window =
1133 ap->blli.v.layer_3_protocol.window_size;
1139 * Set the called party address and subaddress
1141 if (ap->called.tag == T_ATM_PRESENT) {
1142 if (!msg->msg_ie_cdad) {
1143 msg->msg_ie_cdad = (struct ie_generic *)
1144 atm_allocate(&unisig_iepool);
1145 if (msg->msg_ie_cdad == NULL) {
1150 KM_COPY(&ie_cdad_absent,
1151 &msg->msg_ie_cdad->ie_u.ie_cdad,
1152 sizeof(ie_cdad_absent));
1153 msg->msg_ie_cdad->ie_ident = UNI_IE_CDAD;
1154 ATM_ADDR_COPY(&ap->called.addr,
1155 &msg->msg_ie_cdad->ie_cdad_addr);
1157 if (ap->called.subaddr.address_format != T_ATM_ABSENT) {
1158 if (!msg->msg_ie_cdsa) {
1159 msg->msg_ie_cdsa = (struct ie_generic *)
1160 atm_allocate(&unisig_iepool);
1161 if (msg->msg_ie_cdsa == NULL) {
1166 KM_COPY(&ie_cdsa_absent,
1167 &msg->msg_ie_cdsa->ie_u.ie_cdsa,
1168 sizeof(ie_cdsa_absent));
1169 msg->msg_ie_cdsa->ie_ident = UNI_IE_CDSA;
1170 ATM_ADDR_COPY(&ap->called.subaddr,
1171 &msg->msg_ie_cdsa->ie_cdsa_addr);
1176 * Set the calling party address and subaddress
1179 if (ap->calling.tag == T_ATM_PRESENT) {
1180 if (!msg->msg_ie_cgad) {
1181 msg->msg_ie_cgad = (struct ie_generic *)
1182 atm_allocate(&unisig_iepool);
1183 if (msg->msg_ie_cgad == NULL) {
1188 KM_COPY(&ie_cgad_absent,
1189 &msg->msg_ie_cgad->ie_u.ie_cgad,
1190 sizeof(ie_cgad_absent));
1191 msg->msg_ie_cgsa->ie_ident = UNI_IE_CGSA;
1192 ATM_ADDR_COPY(&ap->calling.addr,
1193 &msg->msg_ie_cgad->ie_cgad_addr);
1195 if (ap->calling.subaddr.address_format !=
1197 if (!msg->msg_ie_cgsa) {
1198 msg->msg_ie_cgsa = (struct ie_generic *)
1199 atm_allocate(&unisig_iepool);
1200 if (msg->msg_ie_cgsa == NULL) {
1205 KM_COPY(&ie_cgsa_absent,
1206 &msg->msg_ie_cgsa->ie_u.ie_cgsa,
1207 sizeof(ie_cgsa_absent));
1208 msg->msg_ie_cgsa->ie_ident = UNI_IE_CGSA;
1209 ATM_ADDR_COPY(&ap->calling.subaddr,
1210 &msg->msg_ie_cgsa->ie_cgsa_addr);
1215 * Set quality of service attributes
1217 if (ap->qos.tag == T_ATM_PRESENT) {
1218 if (!msg->msg_ie_qosp) {
1219 msg->msg_ie_qosp = (struct ie_generic *)
1220 atm_allocate(&unisig_iepool);
1221 if (msg->msg_ie_qosp == NULL) {
1226 KM_COPY(&ie_qosp_absent,
1227 &msg->msg_ie_qosp->ie_u.ie_qosp,
1228 sizeof(ie_qosp_absent));
1229 msg->msg_ie_qosp->ie_ident = UNI_IE_QOSP;
1230 if (usp->us_proto == ATM_SIG_UNI30)
1231 msg->msg_ie_qosp->ie_coding = UNI_IE_CODE_STD;
1232 else if ((ap->qos.v.forward.qos_class ==
1233 T_ATM_QOS_CLASS_0) ||
1234 (ap->qos.v.backward.qos_class ==
1236 msg->msg_ie_qosp->ie_coding = UNI_IE_CODE_CCITT;
1238 msg->msg_ie_qosp->ie_coding = ap->qos.v.coding_standard;
1239 msg->msg_ie_qosp->ie_qosp_fwd_class =
1240 ap->qos.v.forward.qos_class;
1241 msg->msg_ie_qosp->ie_qosp_bkwd_class =
1242 ap->qos.v.backward.qos_class;
1246 * Set transit network attributes
1248 if (ap->transit.tag == T_ATM_PRESENT &&
1249 ap->transit.v.length != 0) {
1250 if (!msg->msg_ie_trnt) {
1251 msg->msg_ie_trnt = (struct ie_generic *)
1252 atm_allocate(&unisig_iepool);
1253 if (msg->msg_ie_trnt == NULL) {
1258 KM_COPY(&ie_trnt_absent,
1259 &msg->msg_ie_trnt->ie_u.ie_trnt,
1260 sizeof(ie_trnt_absent));
1261 msg->msg_ie_trnt->ie_ident = UNI_IE_TRNT;
1262 msg->msg_ie_trnt->ie_trnt_id_type =
1263 UNI_IE_TRNT_IDT_NATL;
1264 msg->msg_ie_trnt->ie_trnt_id_plan =
1265 UNI_IE_TRNT_IDP_CIC;
1266 KM_COPY(ap->transit.v.network_id,
1267 msg->msg_ie_trnt->ie_trnt_id,
1268 ap->transit.v.length);
1274 if (ap->cause.tag == T_ATM_PRESENT) {
1275 if (!msg->msg_ie_caus) {
1276 msg->msg_ie_caus = (struct ie_generic *)
1277 atm_allocate(&unisig_iepool);
1278 if (msg->msg_ie_caus == NULL) {
1283 KM_COPY(&ie_caus_absent,
1284 &msg->msg_ie_caus->ie_u.ie_caus,
1285 sizeof(ie_caus_absent));
1286 msg->msg_ie_caus->ie_ident = UNI_IE_CAUS;
1287 msg->msg_ie_caus->ie_coding =
1288 ap->cause.v.coding_standard;
1289 msg->msg_ie_caus->ie_caus_loc =
1290 ap->cause.v.location;
1291 msg->msg_ie_caus->ie_caus_cause =
1292 ap->cause.v.cause_value;
1295 * Don't copy the diagnostics from the attribute
1296 * block, as there's no way to tell how much of
1297 * the diagnostic field is relevant
1299 msg->msg_ie_caus->ie_caus_diag_len = 0;