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 $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
38 #include <netatm/kern_include.h>
40 #include <netatm/uni/unisig_var.h>
41 #include <netatm/uni/unisig_msg.h>
44 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/unisig_vc_state.c,v 1.6.2.1 2001/07/25 20:53:44 pirzyk Exp $");
51 static int unisig_vc_invalid __P((struct unisig *, struct unisig_vccb *,
52 struct unisig_msg *));
53 static int unisig_vc_act01 __P((struct unisig *, struct unisig_vccb *,
54 struct unisig_msg *));
55 static int unisig_vc_act02 __P((struct unisig *, struct unisig_vccb *,
56 struct unisig_msg *));
57 static int unisig_vc_act03 __P((struct unisig *, struct unisig_vccb *,
58 struct unisig_msg *));
59 static int unisig_vc_act04 __P((struct unisig *, struct unisig_vccb *,
60 struct unisig_msg *));
61 static int unisig_vc_act05 __P((struct unisig *, struct unisig_vccb *,
62 struct unisig_msg *));
63 static int unisig_vc_act06 __P((struct unisig *, struct unisig_vccb *,
64 struct unisig_msg *));
65 static int unisig_vc_act07 __P((struct unisig *, struct unisig_vccb *,
66 struct unisig_msg *));
67 static int unisig_vc_act08 __P((struct unisig *, struct unisig_vccb *,
68 struct unisig_msg *));
69 static int unisig_vc_act09 __P((struct unisig *, struct unisig_vccb *,
70 struct unisig_msg *));
71 static int unisig_vc_act10 __P((struct unisig *, struct unisig_vccb *,
72 struct unisig_msg *));
73 static int unisig_vc_act11 __P((struct unisig *, struct unisig_vccb *,
74 struct unisig_msg *));
75 static int unisig_vc_act12 __P((struct unisig *, struct unisig_vccb *,
76 struct unisig_msg *));
77 static int unisig_vc_act13 __P((struct unisig *, struct unisig_vccb *,
78 struct unisig_msg *));
79 static int unisig_vc_act14 __P((struct unisig *, struct unisig_vccb *,
80 struct unisig_msg *));
81 static int unisig_vc_act15 __P((struct unisig *, struct unisig_vccb *,
82 struct unisig_msg *));
83 static int unisig_vc_act16 __P((struct unisig *, struct unisig_vccb *,
84 struct unisig_msg *));
85 static int unisig_vc_act17 __P((struct unisig *, struct unisig_vccb *,
86 struct unisig_msg *));
87 static int unisig_vc_act18 __P((struct unisig *, struct unisig_vccb *,
88 struct unisig_msg *));
89 static int unisig_vc_act19 __P((struct unisig *, struct unisig_vccb *,
90 struct unisig_msg *));
91 static int unisig_vc_act20 __P((struct unisig *, struct unisig_vccb *,
92 struct unisig_msg *));
93 static int unisig_vc_act21 __P((struct unisig *, struct unisig_vccb *,
94 struct unisig_msg *));
95 static int unisig_vc_act22 __P((struct unisig *, struct unisig_vccb *,
96 struct unisig_msg *));
97 static int unisig_vc_act23 __P((struct unisig *, struct unisig_vccb *,
98 struct unisig_msg *));
99 static int unisig_vc_act24 __P((struct unisig *, struct unisig_vccb *,
100 struct unisig_msg *));
101 static int unisig_vc_act25 __P((struct unisig *, struct unisig_vccb *,
102 struct unisig_msg *));
103 static int unisig_vc_act26 __P((struct unisig *, struct unisig_vccb *,
104 struct unisig_msg *));
105 static int unisig_vc_act27 __P((struct unisig *, struct unisig_vccb *,
106 struct unisig_msg *));
107 static int unisig_vc_act28 __P((struct unisig *, struct unisig_vccb *,
108 struct unisig_msg *));
109 static int unisig_vc_act29 __P((struct unisig *, struct unisig_vccb *,
110 struct unisig_msg *));
111 static int unisig_vc_act30 __P((struct unisig *, struct unisig_vccb *,
112 struct unisig_msg *));
113 static int unisig_vc_act31 __P((struct unisig *, struct unisig_vccb *,
114 struct unisig_msg *));
115 static int unisig_vc_clear_call __P((struct unisig *,
116 struct unisig_vccb *,
124 static int unisig_vc_states[21][17] = {
125 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
126 { 0, 2, 99, 5, 99, 99, 0, 99, 12, 99, 0, 14, 0, 3, 0, 0, 0 },
127 { 29, 4, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
128 { 29, 6, 99, 6, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
129 { 29, 17, 99, 17, 99, 99, 17, 99, 10, 99, 17, 17, 17, 0, 0, 0, 0 },
130 { 8, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
131 { 29, 7, 99, 15, 99, 99, 15, 99, 15, 99, 15, 16, 17, 0, 0, 0, 0 },
132 { 19, 3, 99, 3, 99, 99, 3, 99, 3, 99, 3, 13, 3, 0, 0, 0, 0 },
133 { 21, 21, 99, 21, 99, 99, 21, 99, 21, 99, 21, 21, 21, 0, 0, 0, 0 },
134 { 22, 22, 99, 22, 99, 99, 22, 99, 22, 99, 22, 22, 22, 0, 0, 0, 0 },
135 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 23, 17, 17, 0, 0, 0, 0 },
136 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
137 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
138 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
139 { 29, 17, 99, 17, 99, 99, 17, 99, 17, 99, 17, 17, 17, 0, 0, 0, 0 },
140 { 1, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 },
141 { 99, 25, 99, 25, 99, 99, 9, 99, 25, 99, 25, 25, 25, 25, 31, 25, 25 },
142 { 99, 25, 99, 25, 99, 99, 11, 99, 25, 99, 25, 25, 25, 25, 19, 25, 25 },
143 { 99, 12, 99, 12, 99, 99, 25, 99, 12, 99, 12, 19, 19, 30, 19, 99, 99 },
144 { 99, 12, 99, 12, 99, 99, 12, 99, 12, 99, 12, 3, 3, 3, 24, 26, 26 },
145 { 99, 3, 99, 3, 99, 99, 30, 99, 3, 99, 18, 3, 3, 0, 19, 27, 19 },
146 { 99, 7, 99, 7, 99, 99, 30, 99, 7, 99, 19, 19, 19, 20, 19, 19, 28 }
153 * A given state, action pair selects an action number from the
154 * state table. This vector holds the address of the action routine
155 * for each action number.
157 #define MAX_ACTION 32
158 static int (*unisig_vc_act_vec[MAX_ACTION])
159 __P((struct unisig *, struct unisig_vccb *,
160 struct unisig_msg *)) = {
197 * Process an event on a VC
200 * usp pointer to the UNISIG instance
201 * uvp pointer to the VCCB for the affected VCC
202 * event a numeric indication of which event has occured
203 * msg pointer to a signalling message structure
207 * errno error encountered
211 unisig_vc_state(usp, uvp, event, msg)
213 struct unisig_vccb *uvp;
215 struct unisig_msg *msg;
217 int action, rc, state;
220 * Select an action from the state table
223 state = uvp->uv_sstate;
226 action = unisig_vc_states[event][state];
227 if (action >= MAX_ACTION || action < 0)
228 panic("unisig_vc_state: invalid action\n");
231 * Perform the requested action
233 ATM_DEBUG4("unisig_vc_state: uvp=%p, state=%d, event=%d, action=%d\n",
234 uvp, state, event, action);
235 rc = unisig_vc_act_vec[action](usp, uvp, msg);
242 * VC state machine action 0
243 * Unexpected action - log an error message
246 * usp pointer to protocol instance block
247 * uvp pointer to the VCCB for the affected connection (may
249 * msg pointer to a UNISIG message structure
253 * errno error encountered
257 unisig_vc_invalid(usp, uvp, msg)
259 struct unisig_vccb *uvp;
260 struct unisig_msg *msg;
262 log(LOG_ERR, "unisig_vc_state: unexpected action\n");
268 * VC state machine action 1
269 * Setup handler called
271 * Send SETUP, start timer T303, go to UNI_CALL_INITIATED state
274 * usp pointer to protocol instance block
275 * uvp pointer to the VCCB for the affected connection
276 * msg pointer to a UNISIG message structure
280 * errno error encountered
284 unisig_vc_act01(usp, uvp, msg)
286 struct unisig_vccb *uvp;
287 struct unisig_msg *msg;
292 * Send the setup message
294 rc = unisig_send_setup(usp, uvp);
302 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T303);
307 uvp->uv_sstate = UNI_CALL_INITIATED;
312 uvp->uv_tstamp = time_second;
319 * VC state machine action 2
320 * Timeout while waiting for CALL PROCEEDING or CONNECT
322 * If this is the second expiration, clear the call. Otherwise,
323 * retransmit the SETUP message and restart T303.
326 * usp pointer to protocol instance block
327 * uvp pointer to the VCCB for the affected connection
328 * msg pointer to a UNISIG message structure
332 * errno error encountered
336 unisig_vc_act02(usp, uvp, msg)
338 struct unisig_vccb *uvp;
339 struct unisig_msg *msg;
347 rc = unisig_clear_vcc(usp, uvp,
348 T_ATM_CAUSE_NO_ROUTE_TO_DESTINATION);
351 (void) unisig_send_setup(usp, uvp);
352 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T303);
360 * VC state machine action 3
362 * Clear the call internally
365 * usp pointer to protocol instance block
366 * uvp pointer to the VCCB for the affected connection
367 * msg pointer to a UNISIG message structure
371 * errno error encountered
375 unisig_vc_act03(usp, uvp, msg)
377 struct unisig_vccb *uvp;
378 struct unisig_msg *msg;
385 if ((msg != NULL) && (msg->msg_ie_caus != NULL)) {
386 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
388 cause = T_ATM_ABSENT;
390 cause = T_ATM_CAUSE_DESTINATION_OUT_OF_ORDER;
395 rc = unisig_clear_vcc(usp, uvp, cause);
402 * VC state machine action 4
403 * Received CALL PROCEEDING
405 * Start timer T310, go to UNI_CALL_OUT_PROC
408 * usp pointer to protocol instance block
409 * uvp pointer to the VCCB for the affected connection
410 * msg pointer to a UNISIG message structure
414 * errno error encountered
418 unisig_vc_act04(usp, uvp, msg)
420 struct unisig_vccb *uvp;
421 struct unisig_msg *msg;
423 int cause, rc, vpi, vci;
424 struct atm_pif *pip = usp->us_pif;
425 struct ie_generic *iep;
428 * Clear any running timer
430 UNISIG_VC_CANCEL((struct vccb *) uvp);
433 * Make sure a Connection ID is part of the message
435 if (msg->msg_ie_cnid) {
436 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
437 vci = msg->msg_ie_cnid->ie_cnid_vci;
439 iep = (struct ie_generic *)atm_allocate(&unisig_iepool);
442 iep->ie_ident = UNI_IE_CNID;
443 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
444 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
445 cause = UNI_IE_CAUS_MISSING;
446 ATM_DEBUG0("unisig_vc_act04: no CNID in Call Proc\n");
451 * Make sure we can handle the specified VPI and VCI
453 if (vpi > pip->pif_maxvpi || vci > pip->pif_maxvci ||
454 vci < UNI_IE_CNID_MIN_VCI) {
455 cause = UNI_IE_CAUS_BAD_VCC;
456 ATM_DEBUG0("unisig_vc_act04: VPI/VCI invalid\n");
461 * Make sure the specified VPI and VCI are not in use
463 if (unisig_find_vpvc(usp, vpi, vci, VCC_OUT)) {
464 cause = UNI_IE_CAUS_NA_VCC;
465 ATM_DEBUG0("unisig_vc_act04: VPI/VCI in use\n");
472 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T310);
475 * Save the specified VPI and VCI
483 uvp->uv_sstate = UNI_CALL_OUT_PROC;
488 uvp->uv_tstamp = time_second;
494 * Initiate call clearing
496 rc = unisig_vc_clear_call(usp, uvp, msg, cause);
503 * VC state machine action 5
504 * Timeout in UNI_CALL_OUT_PROC
506 * Clear call towards network
509 * usp pointer to protocol instance block
510 * uvp pointer to the VCCB for the affected connection
511 * msg pointer to a UNISIG message structure
515 * errno error encountered
519 unisig_vc_act05(usp, uvp, msg)
521 struct unisig_vccb *uvp;
522 struct unisig_msg *msg;
525 struct unisig_msg *rls_msg;
526 struct ie_generic *cause_ie;
529 * Send a RELEASE message
531 rls_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
534 cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
535 if (cause_ie == NULL) {
541 * Fill out the RELEASE message
543 rls_msg->msg_call_ref = uvp->uv_call_ref;
544 rls_msg->msg_type = UNI_MSG_RLSE;
545 rls_msg->msg_type_flag = 0;
546 rls_msg->msg_type_action = 0;
547 rls_msg->msg_ie_caus = cause_ie;
550 * Fill out the cause IE
552 cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
553 cause_ie->ie_caus_cause = UNI_IE_CAUS_TIMER;
554 KM_COPY("310", cause_ie->ie_caus_diagnostic, 3);
557 * Send the RELEASE message.
559 rc = unisig_send_msg(usp, rls_msg);
560 unisig_free_msg(rls_msg);
565 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
570 uvp->uv_sstate = UNI_RELEASE_REQUEST;
571 uvp->uv_ustate = VCCU_CLOSED;
576 uvp->uv_tstamp = time_second;
583 * VC state machine action 6
586 * Send CONNECT ACK, go to UNI_ACTIVE state
589 * usp pointer to protocol instance block
590 * uvp pointer to the VCCB for the affected connection
591 * msg pointer to a UNISIG message structure
595 * errno error encountered
599 unisig_vc_act06(usp, uvp, msg)
601 struct unisig_vccb *uvp;
602 struct unisig_msg *msg;
604 int cause, rc, vci, vpi;
605 struct atm_pif *pip = usp->us_pif;
606 struct unisig_msg *cack_msg;
607 struct ie_generic *iep;
611 * Clear any running timer
613 UNISIG_VC_CANCEL((struct vccb *) uvp);
615 ap = &uvp->uv_connvc->cvc_attr;
618 * See if a VPI/VCI is specified
620 if (msg->msg_ie_cnid) {
622 * Yes--VPI/VCI must be the first specification or must
623 * match what was specified before
625 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
626 vci = msg->msg_ie_cnid->ie_cnid_vci;
627 if ((uvp->uv_vpi || uvp->uv_vci) &&
628 (vpi != uvp->uv_vpi ||
629 vci != uvp->uv_vci)) {
630 cause = UNI_IE_CAUS_BAD_VCC;
631 ATM_DEBUG0("unisig_vc_act06: VPI/VCI invalid\n");
636 * Specified VPI/VCI must be within range
638 if (vpi > pip->pif_maxvpi || vci > pip->pif_maxvci ||
639 vci < UNI_IE_CNID_MIN_VCI) {
640 cause = UNI_IE_CAUS_BAD_VCC;
641 ATM_DEBUG0("unisig_vc_act06: VPI/VCI invalid\n");
648 * No--VCI must have been specified earlier
651 iep = (struct ie_generic *)atm_allocate(
655 iep->ie_ident = UNI_IE_CNID;
656 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
657 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
658 cause = UNI_IE_CAUS_MISSING;
659 ATM_DEBUG0("unisig_vc_act06: CNID missing\n");
665 * Handle AAL parameters negotiation
667 if (msg->msg_ie_aalp) {
668 struct ie_generic *aalp = msg->msg_ie_aalp;
671 * AAL parameters must have been sent in SETUP
673 if ((ap->aal.tag != T_ATM_PRESENT) ||
674 (ap->aal.type != aalp->ie_aalp_aal_type)) {
675 cause = UNI_IE_CAUS_IECONTENT;
679 switch (aalp->ie_aalp_aal_type) {
681 case UNI_IE_AALP_AT_AAL3:
683 * Maximum SDU size negotiation
685 if (aalp->ie_aalp_4_fwd_max_sdu == T_ATM_ABSENT)
687 if ((ap->aal.v.aal4.forward_max_SDU_size <
688 aalp->ie_aalp_4_fwd_max_sdu) ||
689 (ap->aal.v.aal4.backward_max_SDU_size <
690 aalp->ie_aalp_4_bkwd_max_sdu)) {
691 cause = UNI_IE_CAUS_IECONTENT;
694 ap->aal.v.aal4.forward_max_SDU_size =
695 aalp->ie_aalp_4_fwd_max_sdu;
696 ap->aal.v.aal4.backward_max_SDU_size =
697 aalp->ie_aalp_4_bkwd_max_sdu;
701 case UNI_IE_AALP_AT_AAL5:
703 * Maximum SDU size negotiation
705 if (aalp->ie_aalp_5_fwd_max_sdu == T_ATM_ABSENT)
707 if ((ap->aal.v.aal5.forward_max_SDU_size <
708 aalp->ie_aalp_5_fwd_max_sdu) ||
709 (ap->aal.v.aal5.backward_max_SDU_size <
710 aalp->ie_aalp_5_bkwd_max_sdu)) {
711 cause = UNI_IE_CAUS_IECONTENT;
714 ap->aal.v.aal5.forward_max_SDU_size =
715 aalp->ie_aalp_5_fwd_max_sdu;
716 ap->aal.v.aal5.backward_max_SDU_size =
717 aalp->ie_aalp_5_bkwd_max_sdu;
724 * Get memory for a CONNECT ACK message
726 cack_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
727 if (cack_msg == NULL)
731 * Fill out the CONNECT ACK message
733 cack_msg->msg_call_ref = uvp->uv_call_ref;
734 cack_msg->msg_type = UNI_MSG_CACK;
735 cack_msg->msg_type_flag = 0;
736 cack_msg->msg_type_action = 0;
739 * Send the CONNECT ACK message
741 rc = unisig_send_msg(usp, cack_msg);
742 unisig_free_msg(cack_msg);
747 uvp->uv_sstate = UNI_ACTIVE;
748 uvp->uv_ustate = VCCU_OPEN;
753 uvp->uv_tstamp = time_second;
756 * Notify the user that the connection is now active
758 atm_cm_connected(uvp->uv_connvc);
764 * Initiate call clearing
766 rc = unisig_vc_clear_call(usp, uvp, msg, cause);
773 * VC state machine action 7
774 * Abort routine called or signalling SAAL session reset while in
775 * one of the call setup states
777 * Clear the call, send RELEASE COMPLETE, notify the user.
780 * usp pointer to protocol instance block
781 * uvp pointer to the VCCB for the affected connection
782 * msg pointer to a UNISIG message structure
786 * errno error encountered
790 unisig_vc_act07(usp, uvp, msg)
792 struct unisig_vccb *uvp;
793 struct unisig_msg *msg;
798 * Clear any running timer
800 UNISIG_VC_CANCEL((struct vccb *) uvp);
803 * Send a RELEASE COMPLETE message rejecting the connection
805 rc = unisig_send_release_complete(usp, uvp, msg,
809 * Clear the call VCCB
811 uvp->uv_sstate = UNI_FREE;
812 uvp->uv_ustate = VCCU_CLOSED;
817 uvp->uv_tstamp = time_second;
822 if ((msg != NULL) && (msg->msg_ie_caus != NULL))
823 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
826 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
827 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
828 atm_cm_cleared(uvp->uv_connvc);
835 * VC state machine action 8
838 * Check call paramaters, notify user that a call has been received,
839 * set UNI_CALL_PRESENT state
842 * usp pointer to protocol instance block
843 * uvp pointer to the VCCB for the affected connection
844 * msg pointer to a UNISIG message structure
848 * errno error encountered
852 unisig_vc_act08(usp, uvp, msg)
854 struct unisig_vccb *uvp;
855 struct unisig_msg *msg;
857 int cause = 0, rc, vpi, vci;
858 struct atm_pif *pip = usp->us_pif;
863 ATM_DEBUG3("unisig_vc_act08: usp=%p, uvp=%p, msg=%p\n",
867 * Make sure that the called address is the right format
869 if (msg->msg_ie_cdad->ie_cdad_plan != UNI_IE_CDAD_PLAN_NSAP) {
870 cause = UNI_IE_CAUS_IECONTENT;
871 ATM_DEBUG0("unisig_vc_act08: bad address format\n");
876 * Make sure that the called address is ours
878 nap = (Atm_addr_nsap *) msg->msg_ie_cdad->ie_cdad_addr.address;
879 if (bcmp(usp->us_addr.address, nap, /* XXX */
880 sizeof(Atm_addr_nsap)-1)) {
881 cause = UNI_IE_CAUS_IECONTENT;
882 ATM_DEBUG0("unisig_vc_act08: address not mine\n");
887 * Find the right NIF for the given selector byte
890 while (nip && nip->nif_sel != nap->aan_sel) {
891 nip = nip->nif_pnext;
894 cause = UNI_IE_CAUS_IECONTENT;
895 ATM_DEBUG0("unisig_vc_act08: bad selector byte\n");
900 * See if we recognize the specified AAL
902 if (msg->msg_ie_aalp->ie_aalp_aal_type != UNI_IE_AALP_AT_AAL3 &&
903 msg->msg_ie_aalp->ie_aalp_aal_type !=
904 UNI_IE_AALP_AT_AAL5) {
905 cause = UNI_IE_CAUS_UAAL;
906 ATM_DEBUG0("unisig_vc_act08: bad AAL\n");
911 * Should verify that we can handle requested
916 * Make sure the specified VPI/VCI is valid
918 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
919 vci = msg->msg_ie_cnid->ie_cnid_vci;
920 if (vpi > pip->pif_maxvpi ||
921 vci > pip->pif_maxvci ||
922 vci < UNI_IE_CNID_MIN_VCI) {
923 cause = UNI_IE_CAUS_BAD_VCC;
924 ATM_DEBUG0("unisig_vc_act08: VPI/VCI invalid\n");
929 * Make sure the specified VPI/VCI isn't in use already
931 if (unisig_find_vpvc(usp, vpi, vci, VCC_IN)) {
932 cause = UNI_IE_CAUS_NA_VCC;
933 ATM_DEBUG0("unisig_vc_act08: VPI/VCI in use\n");
938 * Make sure it's a point-to-point connection
940 if (msg->msg_ie_bbcp->ie_bbcp_conn_config !=
942 cause = UNI_IE_CAUS_NI_BC;
943 ATM_DEBUG0("unisig_vc_act08: conn not pt-pt\n");
948 * Fill in the VCCB fields that we can at this point
950 uvp->uv_type = VCC_SVC | VCC_IN | VCC_OUT;
951 uvp->uv_proto = pip->pif_sigmgr->sm_proto;
952 uvp->uv_sstate = UNI_CALL_PRESENT;
953 uvp->uv_ustate = VCCU_POPEN;
956 uvp->uv_vpi = msg->msg_ie_cnid->ie_cnid_vpci;
957 uvp->uv_vci = msg->msg_ie_cnid->ie_cnid_vci;
958 uvp->uv_tstamp = time_second;
961 * Copy the connection attributes from the SETUP message
962 * to an attribute block
964 KM_ZERO(&attr, sizeof(attr));
966 attr.aal.tag = T_ATM_ABSENT;
967 attr.traffic.tag = T_ATM_ABSENT;
968 attr.bearer.tag = T_ATM_ABSENT;
969 attr.bhli.tag = T_ATM_ABSENT;
970 attr.blli.tag_l2 = T_ATM_ABSENT;
971 attr.blli.tag_l3 = T_ATM_ABSENT;
972 attr.llc.tag = T_ATM_ABSENT;
973 attr.called.tag = T_ATM_ABSENT;
974 attr.calling.tag = T_ATM_ABSENT;
975 attr.qos.tag = T_ATM_ABSENT;
976 attr.transit.tag = T_ATM_ABSENT;
977 attr.cause.tag = T_ATM_ABSENT;
978 unisig_save_attrs(usp, msg, &attr);
981 * Notify the connection manager of the new VCC
983 ATM_DEBUG0("unisig_vc_act08: notifying user of connection\n");
984 rc = atm_cm_incoming((struct vccb *)uvp, &attr);
989 * Wait for the connection recipient to issue an accept
995 ATM_DEBUG1("unisig_vc_act08: reject with cause=%d\n", cause);
998 * Clear the VCCB state
1000 uvp->uv_sstate = UNI_NULL;
1005 uvp->uv_tstamp = time_second;
1008 * Some problem was detected with the request. Send a Q.2931
1009 * message rejecting the connection.
1011 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1018 * VC state machine action 9
1019 * Accept routine called by user
1021 * Send CONNECT, start timer T313, go to UNI_CONNECT_REQUEST state
1024 * usp pointer to protocol instance block
1025 * uvp pointer to the VCCB for the affected connection
1026 * msg pointer to a UNISIG message structure
1030 * errno error encountered
1034 unisig_vc_act09(usp, uvp, msg)
1036 struct unisig_vccb *uvp;
1037 struct unisig_msg *msg;
1040 struct unisig_msg *conn_msg;
1042 conn_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1043 if (conn_msg == NULL)
1047 * Fill out the response
1049 conn_msg->msg_call_ref = uvp->uv_call_ref;
1050 conn_msg->msg_type = UNI_MSG_CONN;
1051 conn_msg->msg_type_flag = 0;
1052 conn_msg->msg_type_action = 0;
1055 * Send the CONNECT message. If the send fails, the other
1056 * side will eventually time out and close the connection.
1058 rc = unisig_send_msg(usp, conn_msg);
1059 unisig_free_msg(conn_msg);
1067 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T313);
1072 uvp->uv_sstate = UNI_CONNECT_REQUEST;
1077 uvp->uv_tstamp = time_second;
1084 * VC state machine action 10
1085 * Received CONNECT ACK
1087 * Go to UNI_ACTIVE state
1090 * usp pointer to protocol instance block
1091 * uvp pointer to the VCCB for the affected connection
1092 * msg pointer to a UNISIG message structure
1096 * errno error encountered
1100 unisig_vc_act10(usp, uvp, msg)
1102 struct unisig_vccb *uvp;
1103 struct unisig_msg *msg;
1106 * Clear any running timer
1108 UNISIG_VC_CANCEL((struct vccb *) uvp);
1113 uvp->uv_sstate = UNI_ACTIVE;
1114 uvp->uv_ustate = VCCU_OPEN;
1119 uvp->uv_tstamp = time_second;
1122 * Notify the user that the call is up
1124 atm_cm_connected(uvp->uv_connvc);
1131 * VC state machine action 11
1132 * Reject handler called
1134 * Send RELEASE COMPLETE, clear the call
1137 * usp pointer to protocol instance block
1138 * uvp pointer to the VCCB for the affected connection
1139 * msg pointer to a UNISIG message structure
1143 * errno error encountered
1147 unisig_vc_act11(usp, uvp, msg)
1149 struct unisig_vccb *uvp;
1150 struct unisig_msg *msg;
1155 * Send generic cause code if one is not already set
1157 if (uvp->uv_connvc->cvc_attr.cause.tag == T_ATM_PRESENT)
1158 cause = T_ATM_ABSENT;
1160 cause = T_ATM_CAUSE_CALL_REJECTED;
1163 * Send a RELEASE COMPLETE message
1165 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1168 * Clear the call VCCB
1170 uvp->uv_sstate = UNI_FREE;
1171 uvp->uv_ustate = VCCU_CLOSED;
1176 uvp->uv_tstamp = time_second;
1183 * VC state machine action 12
1184 * Release or abort routine called
1186 * Send RELEASE, start timer T308, go to UNI_RELEASE_REQUEST state
1189 * usp pointer to protocol instance block
1190 * uvp pointer to the VCCB for the affected connection
1191 * msg pointer to a UNISIG message structure
1195 * errno error encountered
1199 unisig_vc_act12(usp, uvp, msg)
1201 struct unisig_vccb *uvp;
1202 struct unisig_msg *msg;
1207 * Clear any running timer
1209 UNISIG_VC_CANCEL((struct vccb *) uvp);
1212 * Send the RELEASE message
1214 rc = unisig_vc_clear_call(usp, uvp, (struct unisig_msg *)NULL,
1222 * VC state machine action 13
1223 * RELEASE COMPLETE received
1228 * usp pointer to protocol instance block
1229 * uvp pointer to the VCCB for the affected connection
1230 * msg pointer to a UNISIG message structure
1234 * errno error encountered
1238 unisig_vc_act13(usp, uvp, msg)
1240 struct unisig_vccb *uvp;
1241 struct unisig_msg *msg;
1244 * Clear any running timer
1246 UNISIG_VC_CANCEL((struct vccb *) uvp);
1251 uvp->uv_sstate = UNI_FREE;
1252 if (uvp->uv_ustate != VCCU_ABORT)
1253 uvp->uv_ustate = VCCU_CLOSED;
1258 uvp->uv_tstamp = time_second;
1261 * Notify the user that the call is now closed
1263 if (msg->msg_ie_caus != NULL)
1264 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
1266 atm_cm_cleared(uvp->uv_connvc);
1273 * VC state machine action 14
1274 * Timer expired while waiting for RELEASE COMPLETE
1276 * If this is the second expiration, just clear the call. Otherwise,
1277 * retransmit the RELEASE message and restart timer T308.
1280 * usp pointer to protocol instance block
1281 * uvp pointer to the VCCB for the affected connection
1282 * msg pointer to a UNISIG message structure
1286 * errno error encountered
1290 unisig_vc_act14(usp, uvp, msg)
1292 struct unisig_vccb *uvp;
1293 struct unisig_msg *msg;
1298 * Check the retry count
1300 if (uvp->uv_retry) {
1302 * Clear the connection
1304 rc = unisig_clear_vcc(usp, uvp,
1305 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
1308 * Increment the retry count
1313 * Resend the RELEASE message
1315 rc = unisig_send_release(usp, uvp,
1316 (struct unisig_msg *)0, T_ATM_ABSENT);
1321 * Restart timer T308
1323 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
1331 * VC state machine action 15
1332 * RELEASE received in UNI_ACTIVE state
1334 * Send RELEASE COMPLETE, go to UNI_FREE, notify the user
1337 * usp pointer to protocol instance block
1338 * uvp pointer to the VCCB for the affected connection
1339 * msg pointer to a UNISIG message structure
1343 * errno error encountered
1347 unisig_vc_act15(usp, uvp, msg)
1349 struct unisig_vccb *uvp;
1350 struct unisig_msg *msg;
1353 struct ie_generic *iep;
1356 * Clear any running timer
1358 UNISIG_VC_CANCEL((struct vccb *) uvp);
1361 * If there was no Cause IE, flag an error
1363 if (!msg->msg_ie_caus) {
1364 cause = UNI_IE_CAUS_MISSING;
1365 for (iep=msg->msg_ie_err; iep; iep=iep->ie_next) {
1366 if (iep->ie_ident == UNI_IE_CAUS &&
1367 iep->ie_err_cause ==
1368 UNI_IE_CAUS_IECONTENT) {
1369 cause = UNI_IE_CAUS_IECONTENT;
1372 if (cause == UNI_IE_CAUS_MISSING) {
1373 iep = (struct ie_generic *)atm_allocate(
1377 iep->ie_ident = UNI_IE_CNID;
1378 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
1379 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
1382 cause = UNI_IE_CAUS_NORM_UNSP;
1386 * Send a RELEASE COMPLETE message
1388 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1393 uvp->uv_sstate = UNI_FREE;
1394 uvp->uv_ustate = VCCU_CLOSED;
1399 uvp->uv_tstamp = time_second;
1402 * Notify the user that the call is cleared
1404 if (msg->msg_ie_caus != NULL)
1405 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
1408 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
1409 T_ATM_CAUSE_UNSPECIFIED_NORMAL);
1410 atm_cm_cleared(uvp->uv_connvc);
1417 * VC state machine action 16
1418 * RELEASE received in UNI_RELEASE_REQUEST state
1423 * usp pointer to protocol instance block
1424 * uvp pointer to the VCCB for the affected connection
1425 * msg pointer to a UNISIG message structure
1429 * errno error encountered
1433 unisig_vc_act16(usp, uvp, msg)
1435 struct unisig_vccb *uvp;
1436 struct unisig_msg *msg;
1441 * Clear any running timer
1443 UNISIG_VC_CANCEL((struct vccb *) uvp);
1448 rc = unisig_clear_vcc(usp, uvp, T_ATM_ABSENT);
1455 * VC state machine action 17
1458 * Send a STATUS message with cause 101, "message not compatible with
1462 * usp pointer to protocol instance block
1463 * uvp pointer to the VCCB for the affected connection
1464 * msg pointer to a UNISIG message structure
1468 * errno error encountered
1472 unisig_vc_act17(usp, uvp, msg)
1474 struct unisig_vccb *uvp;
1475 struct unisig_msg *msg;
1479 ATM_DEBUG3("unisig_vc_perror: usp=%p, uvp=%p, msg=%p\n",
1483 * Clear any running timer
1485 UNISIG_VC_CANCEL((struct vccb *) uvp);
1488 * Send a STATUS message
1490 rc = unisig_send_status(usp, uvp, msg, UNI_IE_CAUS_STATE);
1492 return(rc ? rc : EINVAL);
1497 * VC state machine action 18
1498 * Signalling AAL connection has been lost
1500 * Start timer T309. If the timer expires before the SAAL connection
1501 * comes back, the VCC will be cleared.
1504 * usp pointer to protocol instance block
1505 * uvp pointer to the VCCB for the affected connection
1506 * msg pointer to a UNISIG message structure
1510 * errno error encountered
1514 unisig_vc_act18(usp, uvp, msg)
1516 struct unisig_vccb *uvp;
1517 struct unisig_msg *msg;
1520 * Clear any running timer
1522 UNISIG_VC_CANCEL((struct vccb *) uvp);
1527 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T309);
1532 uvp->uv_sstate = UNI_SSCF_RECOV;
1539 * VC state machine action 19
1543 * usp pointer to protocol instance block
1544 * uvp pointer to the VCCB for the affected connection
1545 * msg pointer to a UNISIG message structure
1549 * errno error encountered
1553 unisig_vc_act19(usp, uvp, msg)
1555 struct unisig_vccb *uvp;
1556 struct unisig_msg *msg;
1563 * VC state machine action 20
1564 * SSCF establish indication in UNI_SSCF_RECOV state -- signalling
1565 * AAL has come up after an outage
1567 * Send STATUS ENQ to make sure we're in compatible state with other end
1570 * usp pointer to protocol instance block
1571 * uvp pointer to the VCCB for the affected connection
1572 * msg pointer to a UNISIG message structure
1576 * errno error encountered
1580 unisig_vc_act20(usp, uvp, msg)
1582 struct unisig_vccb *uvp;
1583 struct unisig_msg *msg;
1586 struct unisig_msg *stat_msg;
1589 * Clear any running timer
1591 UNISIG_VC_CANCEL((struct vccb *) uvp);
1594 * Get memory for a STATUS ENQUIRY message
1596 stat_msg = (struct unisig_msg *)atm_allocate(&unisig_msgpool);
1597 if (stat_msg == NULL)
1601 * Fill out the message
1603 stat_msg->msg_call_ref = uvp->uv_call_ref;
1604 stat_msg->msg_type = UNI_MSG_SENQ;
1605 stat_msg->msg_type_flag = 0;
1606 stat_msg->msg_type_action = 0;
1609 * Send the STATUS ENQUIRY message
1611 rc = unisig_send_msg(usp, stat_msg);
1612 unisig_free_msg(stat_msg);
1615 * Return to active state
1617 uvp->uv_sstate = UNI_ACTIVE;
1624 * VC state machine action 21
1628 * usp pointer to protocol instance block
1629 * uvp pointer to the VCCB for the affected connection (may
1631 * msg pointer to a UNISIG message structure
1635 * errno error encountered
1639 unisig_vc_act21(usp, uvp, msg)
1641 struct unisig_vccb *uvp;
1642 struct unisig_msg *msg;
1647 * Ignore a STATUS message with the global call reference
1649 if (GLOBAL_CREF(msg->msg_call_ref)) {
1654 * If the network thinks we're in NULL state, clear the VCC
1656 if (msg->msg_ie_clst->ie_clst_state == UNI_NULL) {
1658 (void)unisig_clear_vcc(usp, uvp,
1659 T_ATM_CAUSE_DESTINATION_OUT_OF_ORDER);
1665 * If we are in NULL state, send a RELEASE COMPLETE
1667 if (!uvp || (uvp->uv_sstate == UNI_FREE) ||
1668 (uvp->uv_sstate == UNI_NULL)) {
1669 rc = unisig_send_release_complete(usp,
1670 uvp, msg, UNI_IE_CAUS_STATE);
1675 * If the reported state doesn't match our state, close the VCC
1676 * unless we're in UNI_RELEASE_REQUEST or UNI_RELEASE_IND
1678 if (msg->msg_ie_clst->ie_clst_state != uvp->uv_sstate) {
1679 if (uvp->uv_sstate == UNI_RELEASE_REQUEST ||
1680 uvp->uv_sstate == UNI_RELEASE_IND) {
1683 rc = unisig_clear_vcc(usp, uvp,
1684 T_ATM_CAUSE_MESSAGE_INCOMPATIBLE_WITH_CALL_STATE);
1688 * States match, check for an error on one of our messages
1690 cause = msg->msg_ie_caus->ie_caus_cause;
1691 if (cause == UNI_IE_CAUS_MISSING ||
1692 cause == UNI_IE_CAUS_MTEXIST ||
1693 cause == UNI_IE_CAUS_IEEXIST ||
1694 cause == UNI_IE_CAUS_IECONTENT ||
1695 cause == UNI_IE_CAUS_STATE) {
1696 ATM_DEBUG2("unisig_vc_act21: error %d on message 0x%x\n",
1698 msg->msg_ie_caus->ie_caus_diagnostic[0]);
1700 (void)unisig_clear_vcc(usp, uvp, cause);
1709 * VC state machine action 22
1710 * Received STATUS ENQ
1712 * Send STATUS with cause 30 "response to STATUS ENQUIRY" and
1716 * usp pointer to protocol instance block
1717 * uvp pointer to the VCCB for the affected connection (may
1719 * msg pointer to a UNISIG message structure
1723 * errno error encountered
1727 unisig_vc_act22(usp, uvp, msg)
1729 struct unisig_vccb *uvp;
1730 struct unisig_msg *msg;
1733 struct unisig_msg *status;
1734 struct ie_generic *callst_ie, *cause_ie;
1736 ATM_DEBUG3("unisig_vc_perror: usp=%p, uvp=%p, msg=%p\n",
1740 * Get memory for a STATUS message
1742 status = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1745 callst_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
1746 if (callst_ie == NULL) {
1750 cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
1751 if (cause_ie == NULL) {
1753 atm_free(callst_ie);
1758 * Fill out the response
1761 status->msg_call_ref = uvp->uv_call_ref;
1763 if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
1764 status->msg_call_ref = msg->msg_call_ref &
1765 UNI_MSG_CALL_REF_MASK;
1767 status->msg_call_ref = msg->msg_call_ref |
1768 UNI_MSG_CALL_REF_RMT;
1770 status->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL;
1772 status->msg_type = UNI_MSG_STAT;
1773 status->msg_type_flag = 0;
1774 status->msg_type_action = 0;
1775 status->msg_ie_clst = callst_ie;
1776 status->msg_ie_caus = cause_ie;
1779 * Fill out the call state IE
1781 callst_ie->ie_ident = UNI_IE_CLST;
1782 callst_ie->ie_coding = 0;
1783 callst_ie->ie_flag = 0;
1784 callst_ie->ie_action = 0;
1786 switch(uvp->uv_sstate) {
1788 callst_ie->ie_clst_state = UNI_NULL;
1791 callst_ie->ie_clst_state = uvp->uv_sstate;
1794 callst_ie->ie_clst_state = UNI_NULL;
1798 * Fill out the cause IE
1800 cause_ie->ie_ident = UNI_IE_CAUS;
1801 cause_ie->ie_coding = 0;
1802 cause_ie->ie_flag = 0;
1803 cause_ie->ie_action = 0;
1804 cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
1805 cause_ie->ie_caus_cause = UNI_IE_CAUS_SENQ;
1808 * Send the STATUS message
1810 rc = unisig_send_msg(usp, status);
1811 unisig_free_msg(status);
1817 * VC state machine action 23
1818 * Received ADD PARTY
1820 * We don't support multipoint connections, so send an ADD PARTY REJECT
1823 * usp pointer to protocol instance block
1824 * uvp pointer to the VCCB for the affected connection
1825 * msg pointer to a UNISIG message structure
1829 * errno error encountered
1833 unisig_vc_act23(usp, uvp, msg)
1835 struct unisig_vccb *uvp;
1836 struct unisig_msg *msg;
1839 struct unisig_msg *apr_msg;
1842 * Get memory for the ADD PARTY REJECT message
1844 apr_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1845 if (apr_msg == NULL)
1849 * Fill out the message
1851 if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
1852 apr_msg->msg_call_ref = msg->msg_call_ref &
1853 UNI_MSG_CALL_REF_MASK;
1855 apr_msg->msg_call_ref = msg->msg_call_ref |
1856 UNI_MSG_CALL_REF_RMT;
1857 apr_msg->msg_type = UNI_MSG_ADPR;
1858 apr_msg->msg_type_flag = 0;
1859 apr_msg->msg_type_action = 0;
1862 * Use the endpoint reference IE from the received message
1864 apr_msg->msg_ie_eprf = msg->msg_ie_eprf;
1867 * Send the ADD PARTY REJECT message
1869 rc = unisig_send_msg(usp, apr_msg);
1870 apr_msg->msg_ie_eprf = NULL;
1871 unisig_free_msg(apr_msg);
1878 * VC state machine action 24
1884 * usp pointer to protocol instance block
1885 * uvp pointer to the VCCB for the affected connection
1886 * msg pointer to a UNISIG message structure
1890 * errno error encountered
1894 unisig_vc_act24(usp, uvp, msg)
1896 struct unisig_vccb *uvp;
1897 struct unisig_msg *msg;
1904 * VC state machine action 25
1910 * usp pointer to protocol instance block
1911 * uvp pointer to the VCCB for the affected connection
1912 * msg pointer to a UNISIG message structure
1916 * errno error encountered
1920 unisig_vc_act25(usp, uvp, msg)
1922 struct unisig_vccb *uvp;
1923 struct unisig_msg *msg;
1930 * VC state machine action 26
1933 * The abort handler was called to abort a PVC. Clear the VCCB and
1937 * usp pointer to protocol instance block
1938 * uvp pointer to the VCCB for the affected connection
1939 * msg pointer to a UNISIG message structure
1943 * errno error encountered
1947 unisig_vc_act26(usp, uvp, msg)
1949 struct unisig_vccb *uvp;
1950 struct unisig_msg *msg;
1955 * Clear any running timer
1957 UNISIG_VC_CANCEL((struct vccb *) uvp);
1962 rc = unisig_close_vcc(usp, uvp);
1969 if (uvp->uv_connvc->cvc_attr.cause.tag != T_ATM_PRESENT)
1970 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
1971 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
1973 atm_cm_cleared(uvp->uv_connvc);
1980 * VC state machine action 27
1981 * Signalling AAL failure
1983 * Change PVC state to UNI_PVC_ACT_DOWN.
1986 * usp pointer to protocol instance block
1987 * uvp pointer to the VCCB for the affected connection
1988 * msg pointer to a UNISIG message structure
1992 * errno error encountered
1996 unisig_vc_act27(usp, uvp, msg)
1998 struct unisig_vccb *uvp;
1999 struct unisig_msg *msg;
2004 uvp->uv_sstate = UNI_PVC_ACT_DOWN;
2009 uvp->uv_tstamp = time_second;
2016 * VC state machine action 28
2017 * Signalling AAL established
2019 * Set PVC state to UNI_PVC_ACTIVE.
2022 * usp pointer to protocol instance block
2023 * uvp pointer to the VCCB for the affected connection
2024 * msg pointer to a UNISIG message structure
2028 * errno error encountered
2032 unisig_vc_act28(usp, uvp, msg)
2034 struct unisig_vccb *uvp;
2035 struct unisig_msg *msg;
2040 uvp->uv_sstate = UNI_PVC_ACTIVE;
2045 uvp->uv_tstamp = time_second;
2052 * VC state machine action 29
2055 * Send a RELEASE COMPLETE message with cause 81, "invalid call
2059 * usp pointer to protocol instance block
2060 * uvp pointer to the VCCB for the affected connection (may
2062 * msg pointer to a UNISIG message structure
2066 * errno error encountered
2070 unisig_vc_act29(usp, uvp, msg)
2072 struct unisig_vccb *uvp;
2073 struct unisig_msg *msg;
2078 * Send a RELEASE COMPLETE message
2080 rc = unisig_send_release_complete(usp, uvp, msg,
2088 * VC state machine action 30
2089 * Release routine called while SSCF session down, or SSCF session
2090 * reset or lost while in UNI_CALL_PRESENT
2092 * Go to UNI_FREE state
2095 * usp pointer to protocol instance block
2096 * uvp pointer to the VCCB for the affected connection
2097 * msg pointer to a UNISIG message structure
2101 * errno error encountered
2105 unisig_vc_act30(usp, uvp, msg)
2107 struct unisig_vccb *uvp;
2108 struct unisig_msg *msg;
2111 * Clear any running timer
2113 UNISIG_VC_CANCEL((struct vccb *) uvp);
2116 * Clear the call state
2118 uvp->uv_sstate = UNI_FREE;
2119 uvp->uv_ustate = VCCU_CLOSED;
2124 uvp->uv_tstamp = time_second;
2131 * VC state machine action 31
2132 * Accept handler called in UNI_FREE state.
2134 * The call was in UNI_CALL_PRESENT state when it was closed because
2135 * of an SSCF failure. Return an error indication. The accept
2136 * handler will free the VCCB and return the proper code to the
2140 * usp pointer to protocol instance block
2141 * uvp pointer to the VCCB for the affected connection
2142 * msg pointer to a UNISIG message structure
2146 * errno error encountered
2150 unisig_vc_act31(usp, uvp, msg)
2152 struct unisig_vccb *uvp;
2153 struct unisig_msg *msg;
2160 * Initiate clearing a call by sending a RELEASE message.
2163 * usp pointer to protocol instance block
2164 * uvp pointer to the VCCB for the affected connection
2165 * msg pointer to UNI signalling message that the RELEASE
2166 * responds to (may be NULL)
2167 * cause the reason for clearing the call; a value of
2168 * T_ATM_ABSENT indicates that the cause code is
2169 * in the VCC's ATM attributes block
2173 * errno error encountered
2177 unisig_vc_clear_call(usp, uvp, msg, cause)
2179 struct unisig_vccb *uvp;
2180 struct unisig_msg *msg;
2186 * Clear the retry count
2191 * Make sure the ATM attributes block has a valid cause code,
2194 if (cause == T_ATM_ABSENT &&
2195 uvp->uv_connvc->cvc_attr.cause.tag !=
2197 uvp->uv_connvc->cvc_attr.cause.tag = T_ATM_PRESENT;
2198 uvp->uv_connvc->cvc_attr.cause.v.coding_standard =
2200 uvp->uv_connvc->cvc_attr.cause.v.location =
2202 uvp->uv_connvc->cvc_attr.cause.v.cause_value =
2203 usp->us_proto == ATM_SIG_UNI30 ?
2204 T_ATM_CAUSE_UNSPECIFIED_NORMAL :
2205 T_ATM_CAUSE_NORMAL_CALL_CLEARING;
2209 * Send a RELEASE message
2211 rc = unisig_send_release(usp, uvp, msg, cause);
2218 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
2221 * Set the VCCB state
2223 uvp->uv_sstate = UNI_RELEASE_REQUEST;
2224 if (uvp->uv_ustate != VCCU_ABORT)
2225 uvp->uv_ustate = VCCU_CLOSED;
2230 uvp->uv_tstamp = time_second;