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_vc_state.c,v 1.6.2.1 2001/07/25 20:53:44 pirzyk Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/unisig_vc_state.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 static int unisig_vc_invalid (struct unisig *, struct unisig_vccb *,
48 static int unisig_vc_act01 (struct unisig *, struct unisig_vccb *,
50 static int unisig_vc_act02 (struct unisig *, struct unisig_vccb *,
52 static int unisig_vc_act03 (struct unisig *, struct unisig_vccb *,
54 static int unisig_vc_act04 (struct unisig *, struct unisig_vccb *,
56 static int unisig_vc_act05 (struct unisig *, struct unisig_vccb *,
58 static int unisig_vc_act06 (struct unisig *, struct unisig_vccb *,
60 static int unisig_vc_act07 (struct unisig *, struct unisig_vccb *,
62 static int unisig_vc_act08 (struct unisig *, struct unisig_vccb *,
64 static int unisig_vc_act09 (struct unisig *, struct unisig_vccb *,
66 static int unisig_vc_act10 (struct unisig *, struct unisig_vccb *,
68 static int unisig_vc_act11 (struct unisig *, struct unisig_vccb *,
70 static int unisig_vc_act12 (struct unisig *, struct unisig_vccb *,
72 static int unisig_vc_act13 (struct unisig *, struct unisig_vccb *,
74 static int unisig_vc_act14 (struct unisig *, struct unisig_vccb *,
76 static int unisig_vc_act15 (struct unisig *, struct unisig_vccb *,
78 static int unisig_vc_act16 (struct unisig *, struct unisig_vccb *,
80 static int unisig_vc_act17 (struct unisig *, struct unisig_vccb *,
82 static int unisig_vc_act18 (struct unisig *, struct unisig_vccb *,
84 static int unisig_vc_act19 (struct unisig *, struct unisig_vccb *,
86 static int unisig_vc_act20 (struct unisig *, struct unisig_vccb *,
88 static int unisig_vc_act21 (struct unisig *, struct unisig_vccb *,
90 static int unisig_vc_act22 (struct unisig *, struct unisig_vccb *,
92 static int unisig_vc_act23 (struct unisig *, struct unisig_vccb *,
94 static int unisig_vc_act24 (struct unisig *, struct unisig_vccb *,
96 static int unisig_vc_act25 (struct unisig *, struct unisig_vccb *,
98 static int unisig_vc_act26 (struct unisig *, struct unisig_vccb *,
100 static int unisig_vc_act27 (struct unisig *, struct unisig_vccb *,
101 struct unisig_msg *);
102 static int unisig_vc_act28 (struct unisig *, struct unisig_vccb *,
103 struct unisig_msg *);
104 static int unisig_vc_act29 (struct unisig *, struct unisig_vccb *,
105 struct unisig_msg *);
106 static int unisig_vc_act30 (struct unisig *, struct unisig_vccb *,
107 struct unisig_msg *);
108 static int unisig_vc_act31 (struct unisig *, struct unisig_vccb *,
109 struct unisig_msg *);
110 static int unisig_vc_clear_call (struct unisig *,
111 struct unisig_vccb *,
119 static int unisig_vc_states[21][17] = {
120 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
121 { 0, 2, 99, 5, 99, 99, 0, 99, 12, 99, 0, 14, 0, 3, 0, 0, 0 },
122 { 29, 4, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
123 { 29, 6, 99, 6, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
124 { 29, 17, 99, 17, 99, 99, 17, 99, 10, 99, 17, 17, 17, 0, 0, 0, 0 },
125 { 8, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
126 { 29, 7, 99, 15, 99, 99, 15, 99, 15, 99, 15, 16, 17, 0, 0, 0, 0 },
127 { 19, 3, 99, 3, 99, 99, 3, 99, 3, 99, 3, 13, 3, 0, 0, 0, 0 },
128 { 21, 21, 99, 21, 99, 99, 21, 99, 21, 99, 21, 21, 21, 0, 0, 0, 0 },
129 { 22, 22, 99, 22, 99, 99, 22, 99, 22, 99, 22, 22, 22, 0, 0, 0, 0 },
130 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 23, 17, 17, 0, 0, 0, 0 },
131 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
132 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
133 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
134 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
135 { 1, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 },
136 { 99, 25, 99, 25, 99, 99, 9, 99, 25, 99, 25, 25, 25, 25, 31, 25, 25 },
137 { 99, 25, 99, 25, 99, 99, 11, 99, 25, 99, 25, 25, 25, 25, 19, 25, 25 },
138 { 99, 12, 99, 12, 99, 99, 25, 99, 12, 99, 12, 19, 19, 30, 19, 99, 99 },
139 { 99, 12, 99, 12, 99, 99, 12, 99, 12, 99, 12, 3, 3, 3, 24, 26, 26 },
140 { 99, 3, 99, 3, 99, 99, 30, 99, 3, 99, 18, 3, 3, 0, 19, 27, 19 },
141 { 99, 7, 99, 7, 99, 99, 30, 99, 7, 99, 19, 19, 19, 20, 19, 19, 28 }
148 * A given state, action pair selects an action number from the
149 * state table. This vector holds the address of the action routine
150 * for each action number.
152 #define MAX_ACTION 32
153 static int (*unisig_vc_act_vec[MAX_ACTION])
154 (struct unisig *, struct unisig_vccb *,
155 struct unisig_msg *) = {
192 * Process an event on a VC
195 * usp pointer to the UNISIG instance
196 * uvp pointer to the VCCB for the affected VCC
197 * event a numeric indication of which event has occured
198 * msg pointer to a signalling message structure
202 * errno error encountered
206 unisig_vc_state(struct unisig *usp, struct unisig_vccb *uvp, int event,
207 struct unisig_msg *msg)
209 int action, rc, state;
212 * Select an action from the state table
215 state = uvp->uv_sstate;
218 action = unisig_vc_states[event][state];
219 if (action >= MAX_ACTION || action < 0)
220 panic("unisig_vc_state: invalid action\n");
223 * Perform the requested action
225 ATM_DEBUG4("unisig_vc_state: uvp=%p, state=%d, event=%d, action=%d\n",
226 uvp, state, event, action);
227 rc = unisig_vc_act_vec[action](usp, uvp, msg);
234 * VC state machine action 0
235 * Unexpected action - log an error message
238 * usp pointer to protocol instance block
239 * uvp pointer to the VCCB for the affected connection (may
241 * msg pointer to a UNISIG message structure
245 * errno error encountered
249 unisig_vc_invalid(struct unisig *usp, struct unisig_vccb *uvp,
250 struct unisig_msg *msg)
252 log(LOG_ERR, "unisig_vc_state: unexpected action\n");
258 * VC state machine action 1
259 * Setup handler called
261 * Send SETUP, start timer T303, go to UNI_CALL_INITIATED state
264 * usp pointer to protocol instance block
265 * uvp pointer to the VCCB for the affected connection
266 * msg pointer to a UNISIG message structure
270 * errno error encountered
274 unisig_vc_act01(struct unisig *usp, struct unisig_vccb *uvp,
275 struct unisig_msg *msg)
280 * Send the setup message
282 rc = unisig_send_setup(usp, uvp);
290 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T303);
295 uvp->uv_sstate = UNI_CALL_INITIATED;
300 uvp->uv_tstamp = time_second;
307 * VC state machine action 2
308 * Timeout while waiting for CALL PROCEEDING or CONNECT
310 * If this is the second expiration, clear the call. Otherwise,
311 * retransmit the SETUP message and restart T303.
314 * usp pointer to protocol instance block
315 * uvp pointer to the VCCB for the affected connection
316 * msg pointer to a UNISIG message structure
320 * errno error encountered
324 unisig_vc_act02(struct unisig *usp, struct unisig_vccb *uvp,
325 struct unisig_msg *msg)
333 rc = unisig_clear_vcc(usp, uvp,
334 T_ATM_CAUSE_NO_ROUTE_TO_DESTINATION);
337 unisig_send_setup(usp, uvp);
338 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T303);
346 * VC state machine action 3
348 * Clear the call internally
351 * usp pointer to protocol instance block
352 * uvp pointer to the VCCB for the affected connection
353 * msg pointer to a UNISIG message structure
357 * errno error encountered
361 unisig_vc_act03(struct unisig *usp, struct unisig_vccb *uvp,
362 struct unisig_msg *msg)
369 if ((msg != NULL) && (msg->msg_ie_caus != NULL)) {
370 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
372 cause = T_ATM_ABSENT;
374 cause = T_ATM_CAUSE_DESTINATION_OUT_OF_ORDER;
379 rc = unisig_clear_vcc(usp, uvp, cause);
386 * VC state machine action 4
387 * Received CALL PROCEEDING
389 * Start timer T310, go to UNI_CALL_OUT_PROC
392 * usp pointer to protocol instance block
393 * uvp pointer to the VCCB for the affected connection
394 * msg pointer to a UNISIG message structure
398 * errno error encountered
402 unisig_vc_act04(struct unisig *usp, struct unisig_vccb *uvp,
403 struct unisig_msg *msg)
405 int cause, rc, vpi, vci;
406 struct atm_pif *pip = usp->us_pif;
407 struct ie_generic *iep;
410 * Clear any running timer
412 UNISIG_VC_CANCEL((struct vccb *) uvp);
415 * Make sure a Connection ID is part of the message
417 if (msg->msg_ie_cnid) {
418 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
419 vci = msg->msg_ie_cnid->ie_cnid_vci;
421 iep = (struct ie_generic *)atm_allocate(&unisig_iepool);
424 iep->ie_ident = UNI_IE_CNID;
425 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
426 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
427 cause = UNI_IE_CAUS_MISSING;
428 ATM_DEBUG0("unisig_vc_act04: no CNID in Call Proc\n");
433 * Make sure we can handle the specified VPI and VCI
435 if (vpi > pip->pif_maxvpi || vci > pip->pif_maxvci ||
436 vci < UNI_IE_CNID_MIN_VCI) {
437 cause = UNI_IE_CAUS_BAD_VCC;
438 ATM_DEBUG0("unisig_vc_act04: VPI/VCI invalid\n");
443 * Make sure the specified VPI and VCI are not in use
445 if (unisig_find_vpvc(usp, vpi, vci, VCC_OUT)) {
446 cause = UNI_IE_CAUS_NA_VCC;
447 ATM_DEBUG0("unisig_vc_act04: VPI/VCI in use\n");
454 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T310);
457 * Save the specified VPI and VCI
465 uvp->uv_sstate = UNI_CALL_OUT_PROC;
470 uvp->uv_tstamp = time_second;
476 * Initiate call clearing
478 rc = unisig_vc_clear_call(usp, uvp, msg, cause);
485 * VC state machine action 5
486 * Timeout in UNI_CALL_OUT_PROC
488 * Clear call towards network
491 * usp pointer to protocol instance block
492 * uvp pointer to the VCCB for the affected connection
493 * msg pointer to a UNISIG message structure
497 * errno error encountered
501 unisig_vc_act05(struct unisig *usp, struct unisig_vccb *uvp,
502 struct unisig_msg *msg)
505 struct unisig_msg *rls_msg;
506 struct ie_generic *cause_ie;
509 * Send a RELEASE message
511 rls_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
514 cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
515 if (cause_ie == NULL) {
521 * Fill out the RELEASE message
523 rls_msg->msg_call_ref = uvp->uv_call_ref;
524 rls_msg->msg_type = UNI_MSG_RLSE;
525 rls_msg->msg_type_flag = 0;
526 rls_msg->msg_type_action = 0;
527 rls_msg->msg_ie_caus = cause_ie;
530 * Fill out the cause IE
532 cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
533 cause_ie->ie_caus_cause = UNI_IE_CAUS_TIMER;
534 KM_COPY("310", cause_ie->ie_caus_diagnostic, 3);
537 * Send the RELEASE message.
539 rc = unisig_send_msg(usp, rls_msg);
540 unisig_free_msg(rls_msg);
545 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
550 uvp->uv_sstate = UNI_RELEASE_REQUEST;
551 uvp->uv_ustate = VCCU_CLOSED;
556 uvp->uv_tstamp = time_second;
563 * VC state machine action 6
566 * Send CONNECT ACK, go to UNI_ACTIVE state
569 * usp pointer to protocol instance block
570 * uvp pointer to the VCCB for the affected connection
571 * msg pointer to a UNISIG message structure
575 * errno error encountered
579 unisig_vc_act06(struct unisig *usp, struct unisig_vccb *uvp,
580 struct unisig_msg *msg)
582 int cause, rc, vci, vpi;
583 struct atm_pif *pip = usp->us_pif;
584 struct unisig_msg *cack_msg;
585 struct ie_generic *iep;
589 * Clear any running timer
591 UNISIG_VC_CANCEL((struct vccb *) uvp);
593 ap = &uvp->uv_connvc->cvc_attr;
596 * See if a VPI/VCI is specified
598 if (msg->msg_ie_cnid) {
600 * Yes--VPI/VCI must be the first specification or must
601 * match what was specified before
603 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
604 vci = msg->msg_ie_cnid->ie_cnid_vci;
605 if ((uvp->uv_vpi || uvp->uv_vci) &&
606 (vpi != uvp->uv_vpi ||
607 vci != uvp->uv_vci)) {
608 cause = UNI_IE_CAUS_BAD_VCC;
609 ATM_DEBUG0("unisig_vc_act06: VPI/VCI invalid\n");
614 * Specified VPI/VCI must be within range
616 if (vpi > pip->pif_maxvpi || vci > pip->pif_maxvci ||
617 vci < UNI_IE_CNID_MIN_VCI) {
618 cause = UNI_IE_CAUS_BAD_VCC;
619 ATM_DEBUG0("unisig_vc_act06: VPI/VCI invalid\n");
626 * No--VCI must have been specified earlier
629 iep = (struct ie_generic *)atm_allocate(
633 iep->ie_ident = UNI_IE_CNID;
634 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
635 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
636 cause = UNI_IE_CAUS_MISSING;
637 ATM_DEBUG0("unisig_vc_act06: CNID missing\n");
643 * Handle AAL parameters negotiation
645 if (msg->msg_ie_aalp) {
646 struct ie_generic *aalp = msg->msg_ie_aalp;
649 * AAL parameters must have been sent in SETUP
651 if ((ap->aal.tag != T_ATM_PRESENT) ||
652 (ap->aal.type != aalp->ie_aalp_aal_type)) {
653 cause = UNI_IE_CAUS_IECONTENT;
657 switch (aalp->ie_aalp_aal_type) {
659 case UNI_IE_AALP_AT_AAL3:
661 * Maximum SDU size negotiation
663 if (aalp->ie_aalp_4_fwd_max_sdu == T_ATM_ABSENT)
665 if ((ap->aal.v.aal4.forward_max_SDU_size <
666 aalp->ie_aalp_4_fwd_max_sdu) ||
667 (ap->aal.v.aal4.backward_max_SDU_size <
668 aalp->ie_aalp_4_bkwd_max_sdu)) {
669 cause = UNI_IE_CAUS_IECONTENT;
672 ap->aal.v.aal4.forward_max_SDU_size =
673 aalp->ie_aalp_4_fwd_max_sdu;
674 ap->aal.v.aal4.backward_max_SDU_size =
675 aalp->ie_aalp_4_bkwd_max_sdu;
679 case UNI_IE_AALP_AT_AAL5:
681 * Maximum SDU size negotiation
683 if (aalp->ie_aalp_5_fwd_max_sdu == T_ATM_ABSENT)
685 if ((ap->aal.v.aal5.forward_max_SDU_size <
686 aalp->ie_aalp_5_fwd_max_sdu) ||
687 (ap->aal.v.aal5.backward_max_SDU_size <
688 aalp->ie_aalp_5_bkwd_max_sdu)) {
689 cause = UNI_IE_CAUS_IECONTENT;
692 ap->aal.v.aal5.forward_max_SDU_size =
693 aalp->ie_aalp_5_fwd_max_sdu;
694 ap->aal.v.aal5.backward_max_SDU_size =
695 aalp->ie_aalp_5_bkwd_max_sdu;
702 * Get memory for a CONNECT ACK message
704 cack_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
705 if (cack_msg == NULL)
709 * Fill out the CONNECT ACK message
711 cack_msg->msg_call_ref = uvp->uv_call_ref;
712 cack_msg->msg_type = UNI_MSG_CACK;
713 cack_msg->msg_type_flag = 0;
714 cack_msg->msg_type_action = 0;
717 * Send the CONNECT ACK message
719 rc = unisig_send_msg(usp, cack_msg);
720 unisig_free_msg(cack_msg);
725 uvp->uv_sstate = UNI_ACTIVE;
726 uvp->uv_ustate = VCCU_OPEN;
731 uvp->uv_tstamp = time_second;
734 * Notify the user that the connection is now active
736 atm_cm_connected(uvp->uv_connvc);
742 * Initiate call clearing
744 rc = unisig_vc_clear_call(usp, uvp, msg, cause);
751 * VC state machine action 7
752 * Abort routine called or signalling SAAL session reset while in
753 * one of the call setup states
755 * Clear the call, send RELEASE COMPLETE, notify the user.
758 * usp pointer to protocol instance block
759 * uvp pointer to the VCCB for the affected connection
760 * msg pointer to a UNISIG message structure
764 * errno error encountered
768 unisig_vc_act07(struct unisig *usp, struct unisig_vccb *uvp,
769 struct unisig_msg *msg)
774 * Clear any running timer
776 UNISIG_VC_CANCEL((struct vccb *) uvp);
779 * Send a RELEASE COMPLETE message rejecting the connection
781 rc = unisig_send_release_complete(usp, uvp, msg,
785 * Clear the call VCCB
787 uvp->uv_sstate = UNI_FREE;
788 uvp->uv_ustate = VCCU_CLOSED;
793 uvp->uv_tstamp = time_second;
798 if ((msg != NULL) && (msg->msg_ie_caus != NULL))
799 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
802 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
803 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
804 atm_cm_cleared(uvp->uv_connvc);
811 * VC state machine action 8
814 * Check call paramaters, notify user that a call has been received,
815 * set UNI_CALL_PRESENT state
818 * usp pointer to protocol instance block
819 * uvp pointer to the VCCB for the affected connection
820 * msg pointer to a UNISIG message structure
824 * errno error encountered
828 unisig_vc_act08(struct unisig *usp, struct unisig_vccb *uvp,
829 struct unisig_msg *msg)
831 int cause = 0, rc, vpi, vci;
832 struct atm_pif *pip = usp->us_pif;
837 ATM_DEBUG3("unisig_vc_act08: usp=%p, uvp=%p, msg=%p\n",
841 * Make sure that the called address is the right format
843 if (msg->msg_ie_cdad->ie_cdad_plan != UNI_IE_CDAD_PLAN_NSAP) {
844 cause = UNI_IE_CAUS_IECONTENT;
845 ATM_DEBUG0("unisig_vc_act08: bad address format\n");
850 * Make sure that the called address is ours
852 nap = (Atm_addr_nsap *) msg->msg_ie_cdad->ie_cdad_addr.address;
853 if (bcmp(usp->us_addr.address, nap, /* XXX */
854 sizeof(Atm_addr_nsap)-1)) {
855 cause = UNI_IE_CAUS_IECONTENT;
856 ATM_DEBUG0("unisig_vc_act08: address not mine\n");
861 * Find the right NIF for the given selector byte
864 while (nip && nip->nif_sel != nap->aan_sel) {
865 nip = nip->nif_pnext;
868 cause = UNI_IE_CAUS_IECONTENT;
869 ATM_DEBUG0("unisig_vc_act08: bad selector byte\n");
874 * See if we recognize the specified AAL
876 if (msg->msg_ie_aalp->ie_aalp_aal_type != UNI_IE_AALP_AT_AAL3 &&
877 msg->msg_ie_aalp->ie_aalp_aal_type !=
878 UNI_IE_AALP_AT_AAL5) {
879 cause = UNI_IE_CAUS_UAAL;
880 ATM_DEBUG0("unisig_vc_act08: bad AAL\n");
885 * Should verify that we can handle requested
890 * Make sure the specified VPI/VCI is valid
892 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
893 vci = msg->msg_ie_cnid->ie_cnid_vci;
894 if (vpi > pip->pif_maxvpi ||
895 vci > pip->pif_maxvci ||
896 vci < UNI_IE_CNID_MIN_VCI) {
897 cause = UNI_IE_CAUS_BAD_VCC;
898 ATM_DEBUG0("unisig_vc_act08: VPI/VCI invalid\n");
903 * Make sure the specified VPI/VCI isn't in use already
905 if (unisig_find_vpvc(usp, vpi, vci, VCC_IN)) {
906 cause = UNI_IE_CAUS_NA_VCC;
907 ATM_DEBUG0("unisig_vc_act08: VPI/VCI in use\n");
912 * Make sure it's a point-to-point connection
914 if (msg->msg_ie_bbcp->ie_bbcp_conn_config !=
916 cause = UNI_IE_CAUS_NI_BC;
917 ATM_DEBUG0("unisig_vc_act08: conn not pt-pt\n");
922 * Fill in the VCCB fields that we can at this point
924 uvp->uv_type = VCC_SVC | VCC_IN | VCC_OUT;
925 uvp->uv_proto = pip->pif_sigmgr->sm_proto;
926 uvp->uv_sstate = UNI_CALL_PRESENT;
927 uvp->uv_ustate = VCCU_POPEN;
930 uvp->uv_vpi = msg->msg_ie_cnid->ie_cnid_vpci;
931 uvp->uv_vci = msg->msg_ie_cnid->ie_cnid_vci;
932 uvp->uv_tstamp = time_second;
935 * Copy the connection attributes from the SETUP message
936 * to an attribute block
938 KM_ZERO(&attr, sizeof(attr));
940 attr.aal.tag = T_ATM_ABSENT;
941 attr.traffic.tag = T_ATM_ABSENT;
942 attr.bearer.tag = T_ATM_ABSENT;
943 attr.bhli.tag = T_ATM_ABSENT;
944 attr.blli.tag_l2 = T_ATM_ABSENT;
945 attr.blli.tag_l3 = T_ATM_ABSENT;
946 attr.llc.tag = T_ATM_ABSENT;
947 attr.called.tag = T_ATM_ABSENT;
948 attr.calling.tag = T_ATM_ABSENT;
949 attr.qos.tag = T_ATM_ABSENT;
950 attr.transit.tag = T_ATM_ABSENT;
951 attr.cause.tag = T_ATM_ABSENT;
952 unisig_save_attrs(usp, msg, &attr);
955 * Notify the connection manager of the new VCC
957 ATM_DEBUG0("unisig_vc_act08: notifying user of connection\n");
958 rc = atm_cm_incoming((struct vccb *)uvp, &attr);
963 * Wait for the connection recipient to issue an accept
969 ATM_DEBUG1("unisig_vc_act08: reject with cause=%d\n", cause);
972 * Clear the VCCB state
974 uvp->uv_sstate = UNI_NULL;
979 uvp->uv_tstamp = time_second;
982 * Some problem was detected with the request. Send a Q.2931
983 * message rejecting the connection.
985 rc = unisig_send_release_complete(usp, uvp, msg, cause);
992 * VC state machine action 9
993 * Accept routine called by user
995 * Send CONNECT, start timer T313, go to UNI_CONNECT_REQUEST state
998 * usp pointer to protocol instance block
999 * uvp pointer to the VCCB for the affected connection
1000 * msg pointer to a UNISIG message structure
1004 * errno error encountered
1008 unisig_vc_act09(struct unisig *usp, struct unisig_vccb *uvp,
1009 struct unisig_msg *msg)
1012 struct unisig_msg *conn_msg;
1014 conn_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1015 if (conn_msg == NULL)
1019 * Fill out the response
1021 conn_msg->msg_call_ref = uvp->uv_call_ref;
1022 conn_msg->msg_type = UNI_MSG_CONN;
1023 conn_msg->msg_type_flag = 0;
1024 conn_msg->msg_type_action = 0;
1027 * Send the CONNECT message. If the send fails, the other
1028 * side will eventually time out and close the connection.
1030 rc = unisig_send_msg(usp, conn_msg);
1031 unisig_free_msg(conn_msg);
1039 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T313);
1044 uvp->uv_sstate = UNI_CONNECT_REQUEST;
1049 uvp->uv_tstamp = time_second;
1056 * VC state machine action 10
1057 * Received CONNECT ACK
1059 * Go to UNI_ACTIVE state
1062 * usp pointer to protocol instance block
1063 * uvp pointer to the VCCB for the affected connection
1064 * msg pointer to a UNISIG message structure
1068 * errno error encountered
1072 unisig_vc_act10(struct unisig *usp, struct unisig_vccb *uvp,
1073 struct unisig_msg *msg)
1076 * Clear any running timer
1078 UNISIG_VC_CANCEL((struct vccb *) uvp);
1083 uvp->uv_sstate = UNI_ACTIVE;
1084 uvp->uv_ustate = VCCU_OPEN;
1089 uvp->uv_tstamp = time_second;
1092 * Notify the user that the call is up
1094 atm_cm_connected(uvp->uv_connvc);
1101 * VC state machine action 11
1102 * Reject handler called
1104 * Send RELEASE COMPLETE, clear the call
1107 * usp pointer to protocol instance block
1108 * uvp pointer to the VCCB for the affected connection
1109 * msg pointer to a UNISIG message structure
1113 * errno error encountered
1117 unisig_vc_act11(struct unisig *usp, struct unisig_vccb *uvp,
1118 struct unisig_msg *msg)
1123 * Send generic cause code if one is not already set
1125 if (uvp->uv_connvc->cvc_attr.cause.tag == T_ATM_PRESENT)
1126 cause = T_ATM_ABSENT;
1128 cause = T_ATM_CAUSE_CALL_REJECTED;
1131 * Send a RELEASE COMPLETE message
1133 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1136 * Clear the call VCCB
1138 uvp->uv_sstate = UNI_FREE;
1139 uvp->uv_ustate = VCCU_CLOSED;
1144 uvp->uv_tstamp = time_second;
1151 * VC state machine action 12
1152 * Release or abort routine called
1154 * Send RELEASE, start timer T308, go to UNI_RELEASE_REQUEST state
1157 * usp pointer to protocol instance block
1158 * uvp pointer to the VCCB for the affected connection
1159 * msg pointer to a UNISIG message structure
1163 * errno error encountered
1167 unisig_vc_act12(struct unisig *usp, struct unisig_vccb *uvp,
1168 struct unisig_msg *msg)
1173 * Clear any running timer
1175 UNISIG_VC_CANCEL((struct vccb *) uvp);
1178 * Send the RELEASE message
1180 rc = unisig_vc_clear_call(usp, uvp, (struct unisig_msg *)NULL,
1188 * VC state machine action 13
1189 * RELEASE COMPLETE received
1194 * usp pointer to protocol instance block
1195 * uvp pointer to the VCCB for the affected connection
1196 * msg pointer to a UNISIG message structure
1200 * errno error encountered
1204 unisig_vc_act13(struct unisig *usp, struct unisig_vccb *uvp,
1205 struct unisig_msg *msg)
1208 * Clear any running timer
1210 UNISIG_VC_CANCEL((struct vccb *) uvp);
1215 uvp->uv_sstate = UNI_FREE;
1216 if (uvp->uv_ustate != VCCU_ABORT)
1217 uvp->uv_ustate = VCCU_CLOSED;
1222 uvp->uv_tstamp = time_second;
1225 * Notify the user that the call is now closed
1227 if (msg->msg_ie_caus != NULL)
1228 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
1230 atm_cm_cleared(uvp->uv_connvc);
1237 * VC state machine action 14
1238 * Timer expired while waiting for RELEASE COMPLETE
1240 * If this is the second expiration, just clear the call. Otherwise,
1241 * retransmit the RELEASE message and restart timer T308.
1244 * usp pointer to protocol instance block
1245 * uvp pointer to the VCCB for the affected connection
1246 * msg pointer to a UNISIG message structure
1250 * errno error encountered
1254 unisig_vc_act14(struct unisig *usp, struct unisig_vccb *uvp,
1255 struct unisig_msg *msg)
1260 * Check the retry count
1262 if (uvp->uv_retry) {
1264 * Clear the connection
1266 rc = unisig_clear_vcc(usp, uvp,
1267 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
1270 * Increment the retry count
1275 * Resend the RELEASE message
1277 rc = unisig_send_release(usp, uvp,
1278 (struct unisig_msg *)0, T_ATM_ABSENT);
1283 * Restart timer T308
1285 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
1293 * VC state machine action 15
1294 * RELEASE received in UNI_ACTIVE state
1296 * Send RELEASE COMPLETE, go to UNI_FREE, notify the user
1299 * usp pointer to protocol instance block
1300 * uvp pointer to the VCCB for the affected connection
1301 * msg pointer to a UNISIG message structure
1305 * errno error encountered
1309 unisig_vc_act15(struct unisig *usp, struct unisig_vccb *uvp,
1310 struct unisig_msg *msg)
1313 struct ie_generic *iep;
1316 * Clear any running timer
1318 UNISIG_VC_CANCEL((struct vccb *) uvp);
1321 * If there was no Cause IE, flag an error
1323 if (!msg->msg_ie_caus) {
1324 cause = UNI_IE_CAUS_MISSING;
1325 for (iep=msg->msg_ie_err; iep; iep=iep->ie_next) {
1326 if (iep->ie_ident == UNI_IE_CAUS &&
1327 iep->ie_err_cause ==
1328 UNI_IE_CAUS_IECONTENT) {
1329 cause = UNI_IE_CAUS_IECONTENT;
1332 if (cause == UNI_IE_CAUS_MISSING) {
1333 iep = (struct ie_generic *)atm_allocate(
1337 iep->ie_ident = UNI_IE_CNID;
1338 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
1339 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
1342 cause = UNI_IE_CAUS_NORM_UNSP;
1346 * Send a RELEASE COMPLETE message
1348 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1353 uvp->uv_sstate = UNI_FREE;
1354 uvp->uv_ustate = VCCU_CLOSED;
1359 uvp->uv_tstamp = time_second;
1362 * Notify the user that the call is cleared
1364 if (msg->msg_ie_caus != NULL)
1365 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
1368 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
1369 T_ATM_CAUSE_UNSPECIFIED_NORMAL);
1370 atm_cm_cleared(uvp->uv_connvc);
1377 * VC state machine action 16
1378 * RELEASE received in UNI_RELEASE_REQUEST state
1383 * usp pointer to protocol instance block
1384 * uvp pointer to the VCCB for the affected connection
1385 * msg pointer to a UNISIG message structure
1389 * errno error encountered
1393 unisig_vc_act16(struct unisig *usp, struct unisig_vccb *uvp,
1394 struct unisig_msg *msg)
1399 * Clear any running timer
1401 UNISIG_VC_CANCEL((struct vccb *) uvp);
1406 rc = unisig_clear_vcc(usp, uvp, T_ATM_ABSENT);
1413 * VC state machine action 17
1416 * Send a STATUS message with cause 101, "message not compatible with
1420 * usp pointer to protocol instance block
1421 * uvp pointer to the VCCB for the affected connection
1422 * msg pointer to a UNISIG message structure
1426 * errno error encountered
1430 unisig_vc_act17(struct unisig *usp, struct unisig_vccb *uvp,
1431 struct unisig_msg *msg)
1435 ATM_DEBUG3("unisig_vc_perror: usp=%p, uvp=%p, msg=%p\n",
1439 * Clear any running timer
1441 UNISIG_VC_CANCEL((struct vccb *) uvp);
1444 * Send a STATUS message
1446 rc = unisig_send_status(usp, uvp, msg, UNI_IE_CAUS_STATE);
1448 return(rc ? rc : EINVAL);
1453 * VC state machine action 18
1454 * Signalling AAL connection has been lost
1456 * Start timer T309. If the timer expires before the SAAL connection
1457 * comes back, the VCC will be cleared.
1460 * usp pointer to protocol instance block
1461 * uvp pointer to the VCCB for the affected connection
1462 * msg pointer to a UNISIG message structure
1466 * errno error encountered
1470 unisig_vc_act18(struct unisig *usp, struct unisig_vccb *uvp,
1471 struct unisig_msg *msg)
1474 * Clear any running timer
1476 UNISIG_VC_CANCEL((struct vccb *) uvp);
1481 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T309);
1486 uvp->uv_sstate = UNI_SSCF_RECOV;
1493 * VC state machine action 19
1497 * usp pointer to protocol instance block
1498 * uvp pointer to the VCCB for the affected connection
1499 * msg pointer to a UNISIG message structure
1503 * errno error encountered
1507 unisig_vc_act19(struct unisig *usp, struct unisig_vccb *uvp,
1508 struct unisig_msg *msg)
1515 * VC state machine action 20
1516 * SSCF establish indication in UNI_SSCF_RECOV state -- signalling
1517 * AAL has come up after an outage
1519 * Send STATUS ENQ to make sure we're in compatible state with other end
1522 * usp pointer to protocol instance block
1523 * uvp pointer to the VCCB for the affected connection
1524 * msg pointer to a UNISIG message structure
1528 * errno error encountered
1532 unisig_vc_act20(struct unisig *usp, struct unisig_vccb *uvp,
1533 struct unisig_msg *msg)
1536 struct unisig_msg *stat_msg;
1539 * Clear any running timer
1541 UNISIG_VC_CANCEL((struct vccb *) uvp);
1544 * Get memory for a STATUS ENQUIRY message
1546 stat_msg = (struct unisig_msg *)atm_allocate(&unisig_msgpool);
1547 if (stat_msg == NULL)
1551 * Fill out the message
1553 stat_msg->msg_call_ref = uvp->uv_call_ref;
1554 stat_msg->msg_type = UNI_MSG_SENQ;
1555 stat_msg->msg_type_flag = 0;
1556 stat_msg->msg_type_action = 0;
1559 * Send the STATUS ENQUIRY message
1561 rc = unisig_send_msg(usp, stat_msg);
1562 unisig_free_msg(stat_msg);
1565 * Return to active state
1567 uvp->uv_sstate = UNI_ACTIVE;
1574 * VC state machine action 21
1578 * usp pointer to protocol instance block
1579 * uvp pointer to the VCCB for the affected connection (may
1581 * msg pointer to a UNISIG message structure
1585 * errno error encountered
1589 unisig_vc_act21(struct unisig *usp, struct unisig_vccb *uvp,
1590 struct unisig_msg *msg)
1595 * Ignore a STATUS message with the global call reference
1597 if (GLOBAL_CREF(msg->msg_call_ref)) {
1602 * If the network thinks we're in NULL state, clear the VCC
1604 if (msg->msg_ie_clst->ie_clst_state == UNI_NULL) {
1606 unisig_clear_vcc(usp, uvp,
1607 T_ATM_CAUSE_DESTINATION_OUT_OF_ORDER);
1613 * If we are in NULL state, send a RELEASE COMPLETE
1615 if (!uvp || (uvp->uv_sstate == UNI_FREE) ||
1616 (uvp->uv_sstate == UNI_NULL)) {
1617 rc = unisig_send_release_complete(usp,
1618 uvp, msg, UNI_IE_CAUS_STATE);
1623 * If the reported state doesn't match our state, close the VCC
1624 * unless we're in UNI_RELEASE_REQUEST or UNI_RELEASE_IND
1626 if (msg->msg_ie_clst->ie_clst_state != uvp->uv_sstate) {
1627 if (uvp->uv_sstate == UNI_RELEASE_REQUEST ||
1628 uvp->uv_sstate == UNI_RELEASE_IND) {
1631 rc = unisig_clear_vcc(usp, uvp,
1632 T_ATM_CAUSE_MESSAGE_INCOMPATIBLE_WITH_CALL_STATE);
1636 * States match, check for an error on one of our messages
1638 cause = msg->msg_ie_caus->ie_caus_cause;
1639 if (cause == UNI_IE_CAUS_MISSING ||
1640 cause == UNI_IE_CAUS_MTEXIST ||
1641 cause == UNI_IE_CAUS_IEEXIST ||
1642 cause == UNI_IE_CAUS_IECONTENT ||
1643 cause == UNI_IE_CAUS_STATE) {
1644 ATM_DEBUG2("unisig_vc_act21: error %d on message 0x%x\n",
1646 msg->msg_ie_caus->ie_caus_diagnostic[0]);
1648 unisig_clear_vcc(usp, uvp, cause);
1657 * VC state machine action 22
1658 * Received STATUS ENQ
1660 * Send STATUS with cause 30 "response to STATUS ENQUIRY" and
1664 * usp pointer to protocol instance block
1665 * uvp pointer to the VCCB for the affected connection (may
1667 * msg pointer to a UNISIG message structure
1671 * errno error encountered
1675 unisig_vc_act22(struct unisig *usp, struct unisig_vccb *uvp,
1676 struct unisig_msg *msg)
1679 struct unisig_msg *status;
1680 struct ie_generic *callst_ie, *cause_ie;
1682 ATM_DEBUG3("unisig_vc_perror: usp=%p, uvp=%p, msg=%p\n",
1686 * Get memory for a STATUS message
1688 status = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1691 callst_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
1692 if (callst_ie == NULL) {
1696 cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
1697 if (cause_ie == NULL) {
1699 atm_free(callst_ie);
1704 * Fill out the response
1707 status->msg_call_ref = uvp->uv_call_ref;
1709 if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
1710 status->msg_call_ref = msg->msg_call_ref &
1711 UNI_MSG_CALL_REF_MASK;
1713 status->msg_call_ref = msg->msg_call_ref |
1714 UNI_MSG_CALL_REF_RMT;
1716 status->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL;
1718 status->msg_type = UNI_MSG_STAT;
1719 status->msg_type_flag = 0;
1720 status->msg_type_action = 0;
1721 status->msg_ie_clst = callst_ie;
1722 status->msg_ie_caus = cause_ie;
1725 * Fill out the call state IE
1727 callst_ie->ie_ident = UNI_IE_CLST;
1728 callst_ie->ie_coding = 0;
1729 callst_ie->ie_flag = 0;
1730 callst_ie->ie_action = 0;
1732 switch(uvp->uv_sstate) {
1734 callst_ie->ie_clst_state = UNI_NULL;
1737 callst_ie->ie_clst_state = uvp->uv_sstate;
1740 callst_ie->ie_clst_state = UNI_NULL;
1744 * Fill out the cause IE
1746 cause_ie->ie_ident = UNI_IE_CAUS;
1747 cause_ie->ie_coding = 0;
1748 cause_ie->ie_flag = 0;
1749 cause_ie->ie_action = 0;
1750 cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
1751 cause_ie->ie_caus_cause = UNI_IE_CAUS_SENQ;
1754 * Send the STATUS message
1756 rc = unisig_send_msg(usp, status);
1757 unisig_free_msg(status);
1763 * VC state machine action 23
1764 * Received ADD PARTY
1766 * We don't support multipoint connections, so send an ADD PARTY REJECT
1769 * usp pointer to protocol instance block
1770 * uvp pointer to the VCCB for the affected connection
1771 * msg pointer to a UNISIG message structure
1775 * errno error encountered
1779 unisig_vc_act23(struct unisig *usp, struct unisig_vccb *uvp,
1780 struct unisig_msg *msg)
1783 struct unisig_msg *apr_msg;
1786 * Get memory for the ADD PARTY REJECT message
1788 apr_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1789 if (apr_msg == NULL)
1793 * Fill out the message
1795 if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
1796 apr_msg->msg_call_ref = msg->msg_call_ref &
1797 UNI_MSG_CALL_REF_MASK;
1799 apr_msg->msg_call_ref = msg->msg_call_ref |
1800 UNI_MSG_CALL_REF_RMT;
1801 apr_msg->msg_type = UNI_MSG_ADPR;
1802 apr_msg->msg_type_flag = 0;
1803 apr_msg->msg_type_action = 0;
1806 * Use the endpoint reference IE from the received message
1808 apr_msg->msg_ie_eprf = msg->msg_ie_eprf;
1811 * Send the ADD PARTY REJECT message
1813 rc = unisig_send_msg(usp, apr_msg);
1814 apr_msg->msg_ie_eprf = NULL;
1815 unisig_free_msg(apr_msg);
1822 * VC state machine action 24
1828 * usp pointer to protocol instance block
1829 * uvp pointer to the VCCB for the affected connection
1830 * msg pointer to a UNISIG message structure
1834 * errno error encountered
1838 unisig_vc_act24(struct unisig *usp, struct unisig_vccb *uvp,
1839 struct unisig_msg *msg)
1846 * VC state machine action 25
1852 * usp pointer to protocol instance block
1853 * uvp pointer to the VCCB for the affected connection
1854 * msg pointer to a UNISIG message structure
1858 * errno error encountered
1862 unisig_vc_act25(struct unisig *usp, struct unisig_vccb *uvp,
1863 struct unisig_msg *msg)
1870 * VC state machine action 26
1873 * The abort handler was called to abort a PVC. Clear the VCCB and
1877 * usp pointer to protocol instance block
1878 * uvp pointer to the VCCB for the affected connection
1879 * msg pointer to a UNISIG message structure
1883 * errno error encountered
1887 unisig_vc_act26(struct unisig *usp, struct unisig_vccb *uvp,
1888 struct unisig_msg *msg)
1893 * Clear any running timer
1895 UNISIG_VC_CANCEL((struct vccb *) uvp);
1900 rc = unisig_close_vcc(usp, uvp);
1907 if (uvp->uv_connvc->cvc_attr.cause.tag != T_ATM_PRESENT)
1908 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
1909 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
1911 atm_cm_cleared(uvp->uv_connvc);
1918 * VC state machine action 27
1919 * Signalling AAL failure
1921 * Change PVC state to UNI_PVC_ACT_DOWN.
1924 * usp pointer to protocol instance block
1925 * uvp pointer to the VCCB for the affected connection
1926 * msg pointer to a UNISIG message structure
1930 * errno error encountered
1934 unisig_vc_act27(struct unisig *usp, struct unisig_vccb *uvp,
1935 struct unisig_msg *msg)
1940 uvp->uv_sstate = UNI_PVC_ACT_DOWN;
1945 uvp->uv_tstamp = time_second;
1952 * VC state machine action 28
1953 * Signalling AAL established
1955 * Set PVC state to UNI_PVC_ACTIVE.
1958 * usp pointer to protocol instance block
1959 * uvp pointer to the VCCB for the affected connection
1960 * msg pointer to a UNISIG message structure
1964 * errno error encountered
1968 unisig_vc_act28(struct unisig *usp, struct unisig_vccb *uvp,
1969 struct unisig_msg *msg)
1974 uvp->uv_sstate = UNI_PVC_ACTIVE;
1979 uvp->uv_tstamp = time_second;
1986 * VC state machine action 29
1989 * Send a RELEASE COMPLETE message with cause 81, "invalid call
1993 * usp pointer to protocol instance block
1994 * uvp pointer to the VCCB for the affected connection (may
1996 * msg pointer to a UNISIG message structure
2000 * errno error encountered
2004 unisig_vc_act29(struct unisig *usp, struct unisig_vccb *uvp,
2005 struct unisig_msg *msg)
2010 * Send a RELEASE COMPLETE message
2012 rc = unisig_send_release_complete(usp, uvp, msg,
2020 * VC state machine action 30
2021 * Release routine called while SSCF session down, or SSCF session
2022 * reset or lost while in UNI_CALL_PRESENT
2024 * Go to UNI_FREE state
2027 * usp pointer to protocol instance block
2028 * uvp pointer to the VCCB for the affected connection
2029 * msg pointer to a UNISIG message structure
2033 * errno error encountered
2037 unisig_vc_act30(struct unisig *usp, struct unisig_vccb *uvp,
2038 struct unisig_msg *msg)
2041 * Clear any running timer
2043 UNISIG_VC_CANCEL((struct vccb *) uvp);
2046 * Clear the call state
2048 uvp->uv_sstate = UNI_FREE;
2049 uvp->uv_ustate = VCCU_CLOSED;
2054 uvp->uv_tstamp = time_second;
2061 * VC state machine action 31
2062 * Accept handler called in UNI_FREE state.
2064 * The call was in UNI_CALL_PRESENT state when it was closed because
2065 * of an SSCF failure. Return an error indication. The accept
2066 * handler will free the VCCB and return the proper code to the
2070 * usp pointer to protocol instance block
2071 * uvp pointer to the VCCB for the affected connection
2072 * msg pointer to a UNISIG message structure
2076 * errno error encountered
2080 unisig_vc_act31(struct unisig *usp, struct unisig_vccb *uvp,
2081 struct unisig_msg *msg)
2088 * Initiate clearing a call by sending a RELEASE message.
2091 * usp pointer to protocol instance block
2092 * uvp pointer to the VCCB for the affected connection
2093 * msg pointer to UNI signalling message that the RELEASE
2094 * responds to (may be NULL)
2095 * cause the reason for clearing the call; a value of
2096 * T_ATM_ABSENT indicates that the cause code is
2097 * in the VCC's ATM attributes block
2101 * errno error encountered
2105 unisig_vc_clear_call(struct unisig *usp, struct unisig_vccb *uvp,
2106 struct unisig_msg *msg, int cause)
2111 * Clear the retry count
2116 * Make sure the ATM attributes block has a valid cause code,
2119 if (cause == T_ATM_ABSENT &&
2120 uvp->uv_connvc->cvc_attr.cause.tag !=
2122 uvp->uv_connvc->cvc_attr.cause.tag = T_ATM_PRESENT;
2123 uvp->uv_connvc->cvc_attr.cause.v.coding_standard =
2125 uvp->uv_connvc->cvc_attr.cause.v.location =
2127 uvp->uv_connvc->cvc_attr.cause.v.cause_value =
2128 usp->us_proto == ATM_SIG_UNI30 ?
2129 T_ATM_CAUSE_UNSPECIFIED_NORMAL :
2130 T_ATM_CAUSE_NORMAL_CALL_CLEARING;
2134 * Send a RELEASE message
2136 rc = unisig_send_release(usp, uvp, msg, cause);
2143 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
2146 * Set the VCCB state
2148 uvp->uv_sstate = UNI_RELEASE_REQUEST;
2149 if (uvp->uv_ustate != VCCU_ABORT)
2150 uvp->uv_ustate = VCCU_CLOSED;
2155 uvp->uv_tstamp = time_second;