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.2 2003/06/17 04:28:49 dillon 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>
46 static int unisig_vc_invalid __P((struct unisig *, struct unisig_vccb *,
47 struct unisig_msg *));
48 static int unisig_vc_act01 __P((struct unisig *, struct unisig_vccb *,
49 struct unisig_msg *));
50 static int unisig_vc_act02 __P((struct unisig *, struct unisig_vccb *,
51 struct unisig_msg *));
52 static int unisig_vc_act03 __P((struct unisig *, struct unisig_vccb *,
53 struct unisig_msg *));
54 static int unisig_vc_act04 __P((struct unisig *, struct unisig_vccb *,
55 struct unisig_msg *));
56 static int unisig_vc_act05 __P((struct unisig *, struct unisig_vccb *,
57 struct unisig_msg *));
58 static int unisig_vc_act06 __P((struct unisig *, struct unisig_vccb *,
59 struct unisig_msg *));
60 static int unisig_vc_act07 __P((struct unisig *, struct unisig_vccb *,
61 struct unisig_msg *));
62 static int unisig_vc_act08 __P((struct unisig *, struct unisig_vccb *,
63 struct unisig_msg *));
64 static int unisig_vc_act09 __P((struct unisig *, struct unisig_vccb *,
65 struct unisig_msg *));
66 static int unisig_vc_act10 __P((struct unisig *, struct unisig_vccb *,
67 struct unisig_msg *));
68 static int unisig_vc_act11 __P((struct unisig *, struct unisig_vccb *,
69 struct unisig_msg *));
70 static int unisig_vc_act12 __P((struct unisig *, struct unisig_vccb *,
71 struct unisig_msg *));
72 static int unisig_vc_act13 __P((struct unisig *, struct unisig_vccb *,
73 struct unisig_msg *));
74 static int unisig_vc_act14 __P((struct unisig *, struct unisig_vccb *,
75 struct unisig_msg *));
76 static int unisig_vc_act15 __P((struct unisig *, struct unisig_vccb *,
77 struct unisig_msg *));
78 static int unisig_vc_act16 __P((struct unisig *, struct unisig_vccb *,
79 struct unisig_msg *));
80 static int unisig_vc_act17 __P((struct unisig *, struct unisig_vccb *,
81 struct unisig_msg *));
82 static int unisig_vc_act18 __P((struct unisig *, struct unisig_vccb *,
83 struct unisig_msg *));
84 static int unisig_vc_act19 __P((struct unisig *, struct unisig_vccb *,
85 struct unisig_msg *));
86 static int unisig_vc_act20 __P((struct unisig *, struct unisig_vccb *,
87 struct unisig_msg *));
88 static int unisig_vc_act21 __P((struct unisig *, struct unisig_vccb *,
89 struct unisig_msg *));
90 static int unisig_vc_act22 __P((struct unisig *, struct unisig_vccb *,
91 struct unisig_msg *));
92 static int unisig_vc_act23 __P((struct unisig *, struct unisig_vccb *,
93 struct unisig_msg *));
94 static int unisig_vc_act24 __P((struct unisig *, struct unisig_vccb *,
95 struct unisig_msg *));
96 static int unisig_vc_act25 __P((struct unisig *, struct unisig_vccb *,
97 struct unisig_msg *));
98 static int unisig_vc_act26 __P((struct unisig *, struct unisig_vccb *,
99 struct unisig_msg *));
100 static int unisig_vc_act27 __P((struct unisig *, struct unisig_vccb *,
101 struct unisig_msg *));
102 static int unisig_vc_act28 __P((struct unisig *, struct unisig_vccb *,
103 struct unisig_msg *));
104 static int unisig_vc_act29 __P((struct unisig *, struct unisig_vccb *,
105 struct unisig_msg *));
106 static int unisig_vc_act30 __P((struct unisig *, struct unisig_vccb *,
107 struct unisig_msg *));
108 static int unisig_vc_act31 __P((struct unisig *, struct unisig_vccb *,
109 struct unisig_msg *));
110 static int unisig_vc_clear_call __P((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 __P((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(usp, uvp, event, msg)
208 struct unisig_vccb *uvp;
210 struct unisig_msg *msg;
212 int action, rc, state;
215 * Select an action from the state table
218 state = uvp->uv_sstate;
221 action = unisig_vc_states[event][state];
222 if (action >= MAX_ACTION || action < 0)
223 panic("unisig_vc_state: invalid action\n");
226 * Perform the requested action
228 ATM_DEBUG4("unisig_vc_state: uvp=%p, state=%d, event=%d, action=%d\n",
229 uvp, state, event, action);
230 rc = unisig_vc_act_vec[action](usp, uvp, msg);
237 * VC state machine action 0
238 * Unexpected action - log an error message
241 * usp pointer to protocol instance block
242 * uvp pointer to the VCCB for the affected connection (may
244 * msg pointer to a UNISIG message structure
248 * errno error encountered
252 unisig_vc_invalid(usp, uvp, msg)
254 struct unisig_vccb *uvp;
255 struct unisig_msg *msg;
257 log(LOG_ERR, "unisig_vc_state: unexpected action\n");
263 * VC state machine action 1
264 * Setup handler called
266 * Send SETUP, start timer T303, go to UNI_CALL_INITIATED state
269 * usp pointer to protocol instance block
270 * uvp pointer to the VCCB for the affected connection
271 * msg pointer to a UNISIG message structure
275 * errno error encountered
279 unisig_vc_act01(usp, uvp, msg)
281 struct unisig_vccb *uvp;
282 struct unisig_msg *msg;
287 * Send the setup message
289 rc = unisig_send_setup(usp, uvp);
297 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T303);
302 uvp->uv_sstate = UNI_CALL_INITIATED;
307 uvp->uv_tstamp = time_second;
314 * VC state machine action 2
315 * Timeout while waiting for CALL PROCEEDING or CONNECT
317 * If this is the second expiration, clear the call. Otherwise,
318 * retransmit the SETUP message and restart T303.
321 * usp pointer to protocol instance block
322 * uvp pointer to the VCCB for the affected connection
323 * msg pointer to a UNISIG message structure
327 * errno error encountered
331 unisig_vc_act02(usp, uvp, msg)
333 struct unisig_vccb *uvp;
334 struct unisig_msg *msg;
342 rc = unisig_clear_vcc(usp, uvp,
343 T_ATM_CAUSE_NO_ROUTE_TO_DESTINATION);
346 (void) unisig_send_setup(usp, uvp);
347 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T303);
355 * VC state machine action 3
357 * Clear the call internally
360 * usp pointer to protocol instance block
361 * uvp pointer to the VCCB for the affected connection
362 * msg pointer to a UNISIG message structure
366 * errno error encountered
370 unisig_vc_act03(usp, uvp, msg)
372 struct unisig_vccb *uvp;
373 struct unisig_msg *msg;
380 if ((msg != NULL) && (msg->msg_ie_caus != NULL)) {
381 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
383 cause = T_ATM_ABSENT;
385 cause = T_ATM_CAUSE_DESTINATION_OUT_OF_ORDER;
390 rc = unisig_clear_vcc(usp, uvp, cause);
397 * VC state machine action 4
398 * Received CALL PROCEEDING
400 * Start timer T310, go to UNI_CALL_OUT_PROC
403 * usp pointer to protocol instance block
404 * uvp pointer to the VCCB for the affected connection
405 * msg pointer to a UNISIG message structure
409 * errno error encountered
413 unisig_vc_act04(usp, uvp, msg)
415 struct unisig_vccb *uvp;
416 struct unisig_msg *msg;
418 int cause, rc, vpi, vci;
419 struct atm_pif *pip = usp->us_pif;
420 struct ie_generic *iep;
423 * Clear any running timer
425 UNISIG_VC_CANCEL((struct vccb *) uvp);
428 * Make sure a Connection ID is part of the message
430 if (msg->msg_ie_cnid) {
431 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
432 vci = msg->msg_ie_cnid->ie_cnid_vci;
434 iep = (struct ie_generic *)atm_allocate(&unisig_iepool);
437 iep->ie_ident = UNI_IE_CNID;
438 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
439 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
440 cause = UNI_IE_CAUS_MISSING;
441 ATM_DEBUG0("unisig_vc_act04: no CNID in Call Proc\n");
446 * Make sure we can handle the specified VPI and VCI
448 if (vpi > pip->pif_maxvpi || vci > pip->pif_maxvci ||
449 vci < UNI_IE_CNID_MIN_VCI) {
450 cause = UNI_IE_CAUS_BAD_VCC;
451 ATM_DEBUG0("unisig_vc_act04: VPI/VCI invalid\n");
456 * Make sure the specified VPI and VCI are not in use
458 if (unisig_find_vpvc(usp, vpi, vci, VCC_OUT)) {
459 cause = UNI_IE_CAUS_NA_VCC;
460 ATM_DEBUG0("unisig_vc_act04: VPI/VCI in use\n");
467 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T310);
470 * Save the specified VPI and VCI
478 uvp->uv_sstate = UNI_CALL_OUT_PROC;
483 uvp->uv_tstamp = time_second;
489 * Initiate call clearing
491 rc = unisig_vc_clear_call(usp, uvp, msg, cause);
498 * VC state machine action 5
499 * Timeout in UNI_CALL_OUT_PROC
501 * Clear call towards network
504 * usp pointer to protocol instance block
505 * uvp pointer to the VCCB for the affected connection
506 * msg pointer to a UNISIG message structure
510 * errno error encountered
514 unisig_vc_act05(usp, uvp, msg)
516 struct unisig_vccb *uvp;
517 struct unisig_msg *msg;
520 struct unisig_msg *rls_msg;
521 struct ie_generic *cause_ie;
524 * Send a RELEASE message
526 rls_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
529 cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
530 if (cause_ie == NULL) {
536 * Fill out the RELEASE message
538 rls_msg->msg_call_ref = uvp->uv_call_ref;
539 rls_msg->msg_type = UNI_MSG_RLSE;
540 rls_msg->msg_type_flag = 0;
541 rls_msg->msg_type_action = 0;
542 rls_msg->msg_ie_caus = cause_ie;
545 * Fill out the cause IE
547 cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
548 cause_ie->ie_caus_cause = UNI_IE_CAUS_TIMER;
549 KM_COPY("310", cause_ie->ie_caus_diagnostic, 3);
552 * Send the RELEASE message.
554 rc = unisig_send_msg(usp, rls_msg);
555 unisig_free_msg(rls_msg);
560 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
565 uvp->uv_sstate = UNI_RELEASE_REQUEST;
566 uvp->uv_ustate = VCCU_CLOSED;
571 uvp->uv_tstamp = time_second;
578 * VC state machine action 6
581 * Send CONNECT ACK, go to UNI_ACTIVE state
584 * usp pointer to protocol instance block
585 * uvp pointer to the VCCB for the affected connection
586 * msg pointer to a UNISIG message structure
590 * errno error encountered
594 unisig_vc_act06(usp, uvp, msg)
596 struct unisig_vccb *uvp;
597 struct unisig_msg *msg;
599 int cause, rc, vci, vpi;
600 struct atm_pif *pip = usp->us_pif;
601 struct unisig_msg *cack_msg;
602 struct ie_generic *iep;
606 * Clear any running timer
608 UNISIG_VC_CANCEL((struct vccb *) uvp);
610 ap = &uvp->uv_connvc->cvc_attr;
613 * See if a VPI/VCI is specified
615 if (msg->msg_ie_cnid) {
617 * Yes--VPI/VCI must be the first specification or must
618 * match what was specified before
620 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
621 vci = msg->msg_ie_cnid->ie_cnid_vci;
622 if ((uvp->uv_vpi || uvp->uv_vci) &&
623 (vpi != uvp->uv_vpi ||
624 vci != uvp->uv_vci)) {
625 cause = UNI_IE_CAUS_BAD_VCC;
626 ATM_DEBUG0("unisig_vc_act06: VPI/VCI invalid\n");
631 * Specified VPI/VCI must be within range
633 if (vpi > pip->pif_maxvpi || vci > pip->pif_maxvci ||
634 vci < UNI_IE_CNID_MIN_VCI) {
635 cause = UNI_IE_CAUS_BAD_VCC;
636 ATM_DEBUG0("unisig_vc_act06: VPI/VCI invalid\n");
643 * No--VCI must have been specified earlier
646 iep = (struct ie_generic *)atm_allocate(
650 iep->ie_ident = UNI_IE_CNID;
651 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
652 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
653 cause = UNI_IE_CAUS_MISSING;
654 ATM_DEBUG0("unisig_vc_act06: CNID missing\n");
660 * Handle AAL parameters negotiation
662 if (msg->msg_ie_aalp) {
663 struct ie_generic *aalp = msg->msg_ie_aalp;
666 * AAL parameters must have been sent in SETUP
668 if ((ap->aal.tag != T_ATM_PRESENT) ||
669 (ap->aal.type != aalp->ie_aalp_aal_type)) {
670 cause = UNI_IE_CAUS_IECONTENT;
674 switch (aalp->ie_aalp_aal_type) {
676 case UNI_IE_AALP_AT_AAL3:
678 * Maximum SDU size negotiation
680 if (aalp->ie_aalp_4_fwd_max_sdu == T_ATM_ABSENT)
682 if ((ap->aal.v.aal4.forward_max_SDU_size <
683 aalp->ie_aalp_4_fwd_max_sdu) ||
684 (ap->aal.v.aal4.backward_max_SDU_size <
685 aalp->ie_aalp_4_bkwd_max_sdu)) {
686 cause = UNI_IE_CAUS_IECONTENT;
689 ap->aal.v.aal4.forward_max_SDU_size =
690 aalp->ie_aalp_4_fwd_max_sdu;
691 ap->aal.v.aal4.backward_max_SDU_size =
692 aalp->ie_aalp_4_bkwd_max_sdu;
696 case UNI_IE_AALP_AT_AAL5:
698 * Maximum SDU size negotiation
700 if (aalp->ie_aalp_5_fwd_max_sdu == T_ATM_ABSENT)
702 if ((ap->aal.v.aal5.forward_max_SDU_size <
703 aalp->ie_aalp_5_fwd_max_sdu) ||
704 (ap->aal.v.aal5.backward_max_SDU_size <
705 aalp->ie_aalp_5_bkwd_max_sdu)) {
706 cause = UNI_IE_CAUS_IECONTENT;
709 ap->aal.v.aal5.forward_max_SDU_size =
710 aalp->ie_aalp_5_fwd_max_sdu;
711 ap->aal.v.aal5.backward_max_SDU_size =
712 aalp->ie_aalp_5_bkwd_max_sdu;
719 * Get memory for a CONNECT ACK message
721 cack_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
722 if (cack_msg == NULL)
726 * Fill out the CONNECT ACK message
728 cack_msg->msg_call_ref = uvp->uv_call_ref;
729 cack_msg->msg_type = UNI_MSG_CACK;
730 cack_msg->msg_type_flag = 0;
731 cack_msg->msg_type_action = 0;
734 * Send the CONNECT ACK message
736 rc = unisig_send_msg(usp, cack_msg);
737 unisig_free_msg(cack_msg);
742 uvp->uv_sstate = UNI_ACTIVE;
743 uvp->uv_ustate = VCCU_OPEN;
748 uvp->uv_tstamp = time_second;
751 * Notify the user that the connection is now active
753 atm_cm_connected(uvp->uv_connvc);
759 * Initiate call clearing
761 rc = unisig_vc_clear_call(usp, uvp, msg, cause);
768 * VC state machine action 7
769 * Abort routine called or signalling SAAL session reset while in
770 * one of the call setup states
772 * Clear the call, send RELEASE COMPLETE, notify the user.
775 * usp pointer to protocol instance block
776 * uvp pointer to the VCCB for the affected connection
777 * msg pointer to a UNISIG message structure
781 * errno error encountered
785 unisig_vc_act07(usp, uvp, msg)
787 struct unisig_vccb *uvp;
788 struct unisig_msg *msg;
793 * Clear any running timer
795 UNISIG_VC_CANCEL((struct vccb *) uvp);
798 * Send a RELEASE COMPLETE message rejecting the connection
800 rc = unisig_send_release_complete(usp, uvp, msg,
804 * Clear the call VCCB
806 uvp->uv_sstate = UNI_FREE;
807 uvp->uv_ustate = VCCU_CLOSED;
812 uvp->uv_tstamp = time_second;
817 if ((msg != NULL) && (msg->msg_ie_caus != NULL))
818 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
821 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
822 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
823 atm_cm_cleared(uvp->uv_connvc);
830 * VC state machine action 8
833 * Check call paramaters, notify user that a call has been received,
834 * set UNI_CALL_PRESENT state
837 * usp pointer to protocol instance block
838 * uvp pointer to the VCCB for the affected connection
839 * msg pointer to a UNISIG message structure
843 * errno error encountered
847 unisig_vc_act08(usp, uvp, msg)
849 struct unisig_vccb *uvp;
850 struct unisig_msg *msg;
852 int cause = 0, rc, vpi, vci;
853 struct atm_pif *pip = usp->us_pif;
858 ATM_DEBUG3("unisig_vc_act08: usp=%p, uvp=%p, msg=%p\n",
862 * Make sure that the called address is the right format
864 if (msg->msg_ie_cdad->ie_cdad_plan != UNI_IE_CDAD_PLAN_NSAP) {
865 cause = UNI_IE_CAUS_IECONTENT;
866 ATM_DEBUG0("unisig_vc_act08: bad address format\n");
871 * Make sure that the called address is ours
873 nap = (Atm_addr_nsap *) msg->msg_ie_cdad->ie_cdad_addr.address;
874 if (bcmp(usp->us_addr.address, nap, /* XXX */
875 sizeof(Atm_addr_nsap)-1)) {
876 cause = UNI_IE_CAUS_IECONTENT;
877 ATM_DEBUG0("unisig_vc_act08: address not mine\n");
882 * Find the right NIF for the given selector byte
885 while (nip && nip->nif_sel != nap->aan_sel) {
886 nip = nip->nif_pnext;
889 cause = UNI_IE_CAUS_IECONTENT;
890 ATM_DEBUG0("unisig_vc_act08: bad selector byte\n");
895 * See if we recognize the specified AAL
897 if (msg->msg_ie_aalp->ie_aalp_aal_type != UNI_IE_AALP_AT_AAL3 &&
898 msg->msg_ie_aalp->ie_aalp_aal_type !=
899 UNI_IE_AALP_AT_AAL5) {
900 cause = UNI_IE_CAUS_UAAL;
901 ATM_DEBUG0("unisig_vc_act08: bad AAL\n");
906 * Should verify that we can handle requested
911 * Make sure the specified VPI/VCI is valid
913 vpi = msg->msg_ie_cnid->ie_cnid_vpci;
914 vci = msg->msg_ie_cnid->ie_cnid_vci;
915 if (vpi > pip->pif_maxvpi ||
916 vci > pip->pif_maxvci ||
917 vci < UNI_IE_CNID_MIN_VCI) {
918 cause = UNI_IE_CAUS_BAD_VCC;
919 ATM_DEBUG0("unisig_vc_act08: VPI/VCI invalid\n");
924 * Make sure the specified VPI/VCI isn't in use already
926 if (unisig_find_vpvc(usp, vpi, vci, VCC_IN)) {
927 cause = UNI_IE_CAUS_NA_VCC;
928 ATM_DEBUG0("unisig_vc_act08: VPI/VCI in use\n");
933 * Make sure it's a point-to-point connection
935 if (msg->msg_ie_bbcp->ie_bbcp_conn_config !=
937 cause = UNI_IE_CAUS_NI_BC;
938 ATM_DEBUG0("unisig_vc_act08: conn not pt-pt\n");
943 * Fill in the VCCB fields that we can at this point
945 uvp->uv_type = VCC_SVC | VCC_IN | VCC_OUT;
946 uvp->uv_proto = pip->pif_sigmgr->sm_proto;
947 uvp->uv_sstate = UNI_CALL_PRESENT;
948 uvp->uv_ustate = VCCU_POPEN;
951 uvp->uv_vpi = msg->msg_ie_cnid->ie_cnid_vpci;
952 uvp->uv_vci = msg->msg_ie_cnid->ie_cnid_vci;
953 uvp->uv_tstamp = time_second;
956 * Copy the connection attributes from the SETUP message
957 * to an attribute block
959 KM_ZERO(&attr, sizeof(attr));
961 attr.aal.tag = T_ATM_ABSENT;
962 attr.traffic.tag = T_ATM_ABSENT;
963 attr.bearer.tag = T_ATM_ABSENT;
964 attr.bhli.tag = T_ATM_ABSENT;
965 attr.blli.tag_l2 = T_ATM_ABSENT;
966 attr.blli.tag_l3 = T_ATM_ABSENT;
967 attr.llc.tag = T_ATM_ABSENT;
968 attr.called.tag = T_ATM_ABSENT;
969 attr.calling.tag = T_ATM_ABSENT;
970 attr.qos.tag = T_ATM_ABSENT;
971 attr.transit.tag = T_ATM_ABSENT;
972 attr.cause.tag = T_ATM_ABSENT;
973 unisig_save_attrs(usp, msg, &attr);
976 * Notify the connection manager of the new VCC
978 ATM_DEBUG0("unisig_vc_act08: notifying user of connection\n");
979 rc = atm_cm_incoming((struct vccb *)uvp, &attr);
984 * Wait for the connection recipient to issue an accept
990 ATM_DEBUG1("unisig_vc_act08: reject with cause=%d\n", cause);
993 * Clear the VCCB state
995 uvp->uv_sstate = UNI_NULL;
1000 uvp->uv_tstamp = time_second;
1003 * Some problem was detected with the request. Send a Q.2931
1004 * message rejecting the connection.
1006 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1013 * VC state machine action 9
1014 * Accept routine called by user
1016 * Send CONNECT, start timer T313, go to UNI_CONNECT_REQUEST state
1019 * usp pointer to protocol instance block
1020 * uvp pointer to the VCCB for the affected connection
1021 * msg pointer to a UNISIG message structure
1025 * errno error encountered
1029 unisig_vc_act09(usp, uvp, msg)
1031 struct unisig_vccb *uvp;
1032 struct unisig_msg *msg;
1035 struct unisig_msg *conn_msg;
1037 conn_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1038 if (conn_msg == NULL)
1042 * Fill out the response
1044 conn_msg->msg_call_ref = uvp->uv_call_ref;
1045 conn_msg->msg_type = UNI_MSG_CONN;
1046 conn_msg->msg_type_flag = 0;
1047 conn_msg->msg_type_action = 0;
1050 * Send the CONNECT message. If the send fails, the other
1051 * side will eventually time out and close the connection.
1053 rc = unisig_send_msg(usp, conn_msg);
1054 unisig_free_msg(conn_msg);
1062 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T313);
1067 uvp->uv_sstate = UNI_CONNECT_REQUEST;
1072 uvp->uv_tstamp = time_second;
1079 * VC state machine action 10
1080 * Received CONNECT ACK
1082 * Go to UNI_ACTIVE state
1085 * usp pointer to protocol instance block
1086 * uvp pointer to the VCCB for the affected connection
1087 * msg pointer to a UNISIG message structure
1091 * errno error encountered
1095 unisig_vc_act10(usp, uvp, msg)
1097 struct unisig_vccb *uvp;
1098 struct unisig_msg *msg;
1101 * Clear any running timer
1103 UNISIG_VC_CANCEL((struct vccb *) uvp);
1108 uvp->uv_sstate = UNI_ACTIVE;
1109 uvp->uv_ustate = VCCU_OPEN;
1114 uvp->uv_tstamp = time_second;
1117 * Notify the user that the call is up
1119 atm_cm_connected(uvp->uv_connvc);
1126 * VC state machine action 11
1127 * Reject handler called
1129 * Send RELEASE COMPLETE, clear the call
1132 * usp pointer to protocol instance block
1133 * uvp pointer to the VCCB for the affected connection
1134 * msg pointer to a UNISIG message structure
1138 * errno error encountered
1142 unisig_vc_act11(usp, uvp, msg)
1144 struct unisig_vccb *uvp;
1145 struct unisig_msg *msg;
1150 * Send generic cause code if one is not already set
1152 if (uvp->uv_connvc->cvc_attr.cause.tag == T_ATM_PRESENT)
1153 cause = T_ATM_ABSENT;
1155 cause = T_ATM_CAUSE_CALL_REJECTED;
1158 * Send a RELEASE COMPLETE message
1160 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1163 * Clear the call VCCB
1165 uvp->uv_sstate = UNI_FREE;
1166 uvp->uv_ustate = VCCU_CLOSED;
1171 uvp->uv_tstamp = time_second;
1178 * VC state machine action 12
1179 * Release or abort routine called
1181 * Send RELEASE, start timer T308, go to UNI_RELEASE_REQUEST state
1184 * usp pointer to protocol instance block
1185 * uvp pointer to the VCCB for the affected connection
1186 * msg pointer to a UNISIG message structure
1190 * errno error encountered
1194 unisig_vc_act12(usp, uvp, msg)
1196 struct unisig_vccb *uvp;
1197 struct unisig_msg *msg;
1202 * Clear any running timer
1204 UNISIG_VC_CANCEL((struct vccb *) uvp);
1207 * Send the RELEASE message
1209 rc = unisig_vc_clear_call(usp, uvp, (struct unisig_msg *)NULL,
1217 * VC state machine action 13
1218 * RELEASE COMPLETE received
1223 * usp pointer to protocol instance block
1224 * uvp pointer to the VCCB for the affected connection
1225 * msg pointer to a UNISIG message structure
1229 * errno error encountered
1233 unisig_vc_act13(usp, uvp, msg)
1235 struct unisig_vccb *uvp;
1236 struct unisig_msg *msg;
1239 * Clear any running timer
1241 UNISIG_VC_CANCEL((struct vccb *) uvp);
1246 uvp->uv_sstate = UNI_FREE;
1247 if (uvp->uv_ustate != VCCU_ABORT)
1248 uvp->uv_ustate = VCCU_CLOSED;
1253 uvp->uv_tstamp = time_second;
1256 * Notify the user that the call is now closed
1258 if (msg->msg_ie_caus != NULL)
1259 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
1261 atm_cm_cleared(uvp->uv_connvc);
1268 * VC state machine action 14
1269 * Timer expired while waiting for RELEASE COMPLETE
1271 * If this is the second expiration, just clear the call. Otherwise,
1272 * retransmit the RELEASE message and restart timer T308.
1275 * usp pointer to protocol instance block
1276 * uvp pointer to the VCCB for the affected connection
1277 * msg pointer to a UNISIG message structure
1281 * errno error encountered
1285 unisig_vc_act14(usp, uvp, msg)
1287 struct unisig_vccb *uvp;
1288 struct unisig_msg *msg;
1293 * Check the retry count
1295 if (uvp->uv_retry) {
1297 * Clear the connection
1299 rc = unisig_clear_vcc(usp, uvp,
1300 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
1303 * Increment the retry count
1308 * Resend the RELEASE message
1310 rc = unisig_send_release(usp, uvp,
1311 (struct unisig_msg *)0, T_ATM_ABSENT);
1316 * Restart timer T308
1318 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
1326 * VC state machine action 15
1327 * RELEASE received in UNI_ACTIVE state
1329 * Send RELEASE COMPLETE, go to UNI_FREE, notify the user
1332 * usp pointer to protocol instance block
1333 * uvp pointer to the VCCB for the affected connection
1334 * msg pointer to a UNISIG message structure
1338 * errno error encountered
1342 unisig_vc_act15(usp, uvp, msg)
1344 struct unisig_vccb *uvp;
1345 struct unisig_msg *msg;
1348 struct ie_generic *iep;
1351 * Clear any running timer
1353 UNISIG_VC_CANCEL((struct vccb *) uvp);
1356 * If there was no Cause IE, flag an error
1358 if (!msg->msg_ie_caus) {
1359 cause = UNI_IE_CAUS_MISSING;
1360 for (iep=msg->msg_ie_err; iep; iep=iep->ie_next) {
1361 if (iep->ie_ident == UNI_IE_CAUS &&
1362 iep->ie_err_cause ==
1363 UNI_IE_CAUS_IECONTENT) {
1364 cause = UNI_IE_CAUS_IECONTENT;
1367 if (cause == UNI_IE_CAUS_MISSING) {
1368 iep = (struct ie_generic *)atm_allocate(
1372 iep->ie_ident = UNI_IE_CNID;
1373 iep->ie_err_cause = UNI_IE_CAUS_MISSING;
1374 MSG_IE_ADD(msg, iep, UNI_MSG_IE_ERR);
1377 cause = UNI_IE_CAUS_NORM_UNSP;
1381 * Send a RELEASE COMPLETE message
1383 rc = unisig_send_release_complete(usp, uvp, msg, cause);
1388 uvp->uv_sstate = UNI_FREE;
1389 uvp->uv_ustate = VCCU_CLOSED;
1394 uvp->uv_tstamp = time_second;
1397 * Notify the user that the call is cleared
1399 if (msg->msg_ie_caus != NULL)
1400 unisig_cause_attr_from_ie(&uvp->uv_connvc->cvc_attr,
1403 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
1404 T_ATM_CAUSE_UNSPECIFIED_NORMAL);
1405 atm_cm_cleared(uvp->uv_connvc);
1412 * VC state machine action 16
1413 * RELEASE received in UNI_RELEASE_REQUEST state
1418 * usp pointer to protocol instance block
1419 * uvp pointer to the VCCB for the affected connection
1420 * msg pointer to a UNISIG message structure
1424 * errno error encountered
1428 unisig_vc_act16(usp, uvp, msg)
1430 struct unisig_vccb *uvp;
1431 struct unisig_msg *msg;
1436 * Clear any running timer
1438 UNISIG_VC_CANCEL((struct vccb *) uvp);
1443 rc = unisig_clear_vcc(usp, uvp, T_ATM_ABSENT);
1450 * VC state machine action 17
1453 * Send a STATUS message with cause 101, "message not compatible with
1457 * usp pointer to protocol instance block
1458 * uvp pointer to the VCCB for the affected connection
1459 * msg pointer to a UNISIG message structure
1463 * errno error encountered
1467 unisig_vc_act17(usp, uvp, msg)
1469 struct unisig_vccb *uvp;
1470 struct unisig_msg *msg;
1474 ATM_DEBUG3("unisig_vc_perror: usp=%p, uvp=%p, msg=%p\n",
1478 * Clear any running timer
1480 UNISIG_VC_CANCEL((struct vccb *) uvp);
1483 * Send a STATUS message
1485 rc = unisig_send_status(usp, uvp, msg, UNI_IE_CAUS_STATE);
1487 return(rc ? rc : EINVAL);
1492 * VC state machine action 18
1493 * Signalling AAL connection has been lost
1495 * Start timer T309. If the timer expires before the SAAL connection
1496 * comes back, the VCC will be cleared.
1499 * usp pointer to protocol instance block
1500 * uvp pointer to the VCCB for the affected connection
1501 * msg pointer to a UNISIG message structure
1505 * errno error encountered
1509 unisig_vc_act18(usp, uvp, msg)
1511 struct unisig_vccb *uvp;
1512 struct unisig_msg *msg;
1515 * Clear any running timer
1517 UNISIG_VC_CANCEL((struct vccb *) uvp);
1522 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T309);
1527 uvp->uv_sstate = UNI_SSCF_RECOV;
1534 * VC state machine action 19
1538 * usp pointer to protocol instance block
1539 * uvp pointer to the VCCB for the affected connection
1540 * msg pointer to a UNISIG message structure
1544 * errno error encountered
1548 unisig_vc_act19(usp, uvp, msg)
1550 struct unisig_vccb *uvp;
1551 struct unisig_msg *msg;
1558 * VC state machine action 20
1559 * SSCF establish indication in UNI_SSCF_RECOV state -- signalling
1560 * AAL has come up after an outage
1562 * Send STATUS ENQ to make sure we're in compatible state with other end
1565 * usp pointer to protocol instance block
1566 * uvp pointer to the VCCB for the affected connection
1567 * msg pointer to a UNISIG message structure
1571 * errno error encountered
1575 unisig_vc_act20(usp, uvp, msg)
1577 struct unisig_vccb *uvp;
1578 struct unisig_msg *msg;
1581 struct unisig_msg *stat_msg;
1584 * Clear any running timer
1586 UNISIG_VC_CANCEL((struct vccb *) uvp);
1589 * Get memory for a STATUS ENQUIRY message
1591 stat_msg = (struct unisig_msg *)atm_allocate(&unisig_msgpool);
1592 if (stat_msg == NULL)
1596 * Fill out the message
1598 stat_msg->msg_call_ref = uvp->uv_call_ref;
1599 stat_msg->msg_type = UNI_MSG_SENQ;
1600 stat_msg->msg_type_flag = 0;
1601 stat_msg->msg_type_action = 0;
1604 * Send the STATUS ENQUIRY message
1606 rc = unisig_send_msg(usp, stat_msg);
1607 unisig_free_msg(stat_msg);
1610 * Return to active state
1612 uvp->uv_sstate = UNI_ACTIVE;
1619 * VC state machine action 21
1623 * usp pointer to protocol instance block
1624 * uvp pointer to the VCCB for the affected connection (may
1626 * msg pointer to a UNISIG message structure
1630 * errno error encountered
1634 unisig_vc_act21(usp, uvp, msg)
1636 struct unisig_vccb *uvp;
1637 struct unisig_msg *msg;
1642 * Ignore a STATUS message with the global call reference
1644 if (GLOBAL_CREF(msg->msg_call_ref)) {
1649 * If the network thinks we're in NULL state, clear the VCC
1651 if (msg->msg_ie_clst->ie_clst_state == UNI_NULL) {
1653 (void)unisig_clear_vcc(usp, uvp,
1654 T_ATM_CAUSE_DESTINATION_OUT_OF_ORDER);
1660 * If we are in NULL state, send a RELEASE COMPLETE
1662 if (!uvp || (uvp->uv_sstate == UNI_FREE) ||
1663 (uvp->uv_sstate == UNI_NULL)) {
1664 rc = unisig_send_release_complete(usp,
1665 uvp, msg, UNI_IE_CAUS_STATE);
1670 * If the reported state doesn't match our state, close the VCC
1671 * unless we're in UNI_RELEASE_REQUEST or UNI_RELEASE_IND
1673 if (msg->msg_ie_clst->ie_clst_state != uvp->uv_sstate) {
1674 if (uvp->uv_sstate == UNI_RELEASE_REQUEST ||
1675 uvp->uv_sstate == UNI_RELEASE_IND) {
1678 rc = unisig_clear_vcc(usp, uvp,
1679 T_ATM_CAUSE_MESSAGE_INCOMPATIBLE_WITH_CALL_STATE);
1683 * States match, check for an error on one of our messages
1685 cause = msg->msg_ie_caus->ie_caus_cause;
1686 if (cause == UNI_IE_CAUS_MISSING ||
1687 cause == UNI_IE_CAUS_MTEXIST ||
1688 cause == UNI_IE_CAUS_IEEXIST ||
1689 cause == UNI_IE_CAUS_IECONTENT ||
1690 cause == UNI_IE_CAUS_STATE) {
1691 ATM_DEBUG2("unisig_vc_act21: error %d on message 0x%x\n",
1693 msg->msg_ie_caus->ie_caus_diagnostic[0]);
1695 (void)unisig_clear_vcc(usp, uvp, cause);
1704 * VC state machine action 22
1705 * Received STATUS ENQ
1707 * Send STATUS with cause 30 "response to STATUS ENQUIRY" and
1711 * usp pointer to protocol instance block
1712 * uvp pointer to the VCCB for the affected connection (may
1714 * msg pointer to a UNISIG message structure
1718 * errno error encountered
1722 unisig_vc_act22(usp, uvp, msg)
1724 struct unisig_vccb *uvp;
1725 struct unisig_msg *msg;
1728 struct unisig_msg *status;
1729 struct ie_generic *callst_ie, *cause_ie;
1731 ATM_DEBUG3("unisig_vc_perror: usp=%p, uvp=%p, msg=%p\n",
1735 * Get memory for a STATUS message
1737 status = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1740 callst_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
1741 if (callst_ie == NULL) {
1745 cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
1746 if (cause_ie == NULL) {
1748 atm_free(callst_ie);
1753 * Fill out the response
1756 status->msg_call_ref = uvp->uv_call_ref;
1758 if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
1759 status->msg_call_ref = msg->msg_call_ref &
1760 UNI_MSG_CALL_REF_MASK;
1762 status->msg_call_ref = msg->msg_call_ref |
1763 UNI_MSG_CALL_REF_RMT;
1765 status->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL;
1767 status->msg_type = UNI_MSG_STAT;
1768 status->msg_type_flag = 0;
1769 status->msg_type_action = 0;
1770 status->msg_ie_clst = callst_ie;
1771 status->msg_ie_caus = cause_ie;
1774 * Fill out the call state IE
1776 callst_ie->ie_ident = UNI_IE_CLST;
1777 callst_ie->ie_coding = 0;
1778 callst_ie->ie_flag = 0;
1779 callst_ie->ie_action = 0;
1781 switch(uvp->uv_sstate) {
1783 callst_ie->ie_clst_state = UNI_NULL;
1786 callst_ie->ie_clst_state = uvp->uv_sstate;
1789 callst_ie->ie_clst_state = UNI_NULL;
1793 * Fill out the cause IE
1795 cause_ie->ie_ident = UNI_IE_CAUS;
1796 cause_ie->ie_coding = 0;
1797 cause_ie->ie_flag = 0;
1798 cause_ie->ie_action = 0;
1799 cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
1800 cause_ie->ie_caus_cause = UNI_IE_CAUS_SENQ;
1803 * Send the STATUS message
1805 rc = unisig_send_msg(usp, status);
1806 unisig_free_msg(status);
1812 * VC state machine action 23
1813 * Received ADD PARTY
1815 * We don't support multipoint connections, so send an ADD PARTY REJECT
1818 * usp pointer to protocol instance block
1819 * uvp pointer to the VCCB for the affected connection
1820 * msg pointer to a UNISIG message structure
1824 * errno error encountered
1828 unisig_vc_act23(usp, uvp, msg)
1830 struct unisig_vccb *uvp;
1831 struct unisig_msg *msg;
1834 struct unisig_msg *apr_msg;
1837 * Get memory for the ADD PARTY REJECT message
1839 apr_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
1840 if (apr_msg == NULL)
1844 * Fill out the message
1846 if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
1847 apr_msg->msg_call_ref = msg->msg_call_ref &
1848 UNI_MSG_CALL_REF_MASK;
1850 apr_msg->msg_call_ref = msg->msg_call_ref |
1851 UNI_MSG_CALL_REF_RMT;
1852 apr_msg->msg_type = UNI_MSG_ADPR;
1853 apr_msg->msg_type_flag = 0;
1854 apr_msg->msg_type_action = 0;
1857 * Use the endpoint reference IE from the received message
1859 apr_msg->msg_ie_eprf = msg->msg_ie_eprf;
1862 * Send the ADD PARTY REJECT message
1864 rc = unisig_send_msg(usp, apr_msg);
1865 apr_msg->msg_ie_eprf = NULL;
1866 unisig_free_msg(apr_msg);
1873 * VC state machine action 24
1879 * usp pointer to protocol instance block
1880 * uvp pointer to the VCCB for the affected connection
1881 * msg pointer to a UNISIG message structure
1885 * errno error encountered
1889 unisig_vc_act24(usp, uvp, msg)
1891 struct unisig_vccb *uvp;
1892 struct unisig_msg *msg;
1899 * VC state machine action 25
1905 * usp pointer to protocol instance block
1906 * uvp pointer to the VCCB for the affected connection
1907 * msg pointer to a UNISIG message structure
1911 * errno error encountered
1915 unisig_vc_act25(usp, uvp, msg)
1917 struct unisig_vccb *uvp;
1918 struct unisig_msg *msg;
1925 * VC state machine action 26
1928 * The abort handler was called to abort a PVC. Clear the VCCB and
1932 * usp pointer to protocol instance block
1933 * uvp pointer to the VCCB for the affected connection
1934 * msg pointer to a UNISIG message structure
1938 * errno error encountered
1942 unisig_vc_act26(usp, uvp, msg)
1944 struct unisig_vccb *uvp;
1945 struct unisig_msg *msg;
1950 * Clear any running timer
1952 UNISIG_VC_CANCEL((struct vccb *) uvp);
1957 rc = unisig_close_vcc(usp, uvp);
1964 if (uvp->uv_connvc->cvc_attr.cause.tag != T_ATM_PRESENT)
1965 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
1966 T_ATM_CAUSE_NORMAL_CALL_CLEARING);
1968 atm_cm_cleared(uvp->uv_connvc);
1975 * VC state machine action 27
1976 * Signalling AAL failure
1978 * Change PVC state to UNI_PVC_ACT_DOWN.
1981 * usp pointer to protocol instance block
1982 * uvp pointer to the VCCB for the affected connection
1983 * msg pointer to a UNISIG message structure
1987 * errno error encountered
1991 unisig_vc_act27(usp, uvp, msg)
1993 struct unisig_vccb *uvp;
1994 struct unisig_msg *msg;
1999 uvp->uv_sstate = UNI_PVC_ACT_DOWN;
2004 uvp->uv_tstamp = time_second;
2011 * VC state machine action 28
2012 * Signalling AAL established
2014 * Set PVC state to UNI_PVC_ACTIVE.
2017 * usp pointer to protocol instance block
2018 * uvp pointer to the VCCB for the affected connection
2019 * msg pointer to a UNISIG message structure
2023 * errno error encountered
2027 unisig_vc_act28(usp, uvp, msg)
2029 struct unisig_vccb *uvp;
2030 struct unisig_msg *msg;
2035 uvp->uv_sstate = UNI_PVC_ACTIVE;
2040 uvp->uv_tstamp = time_second;
2047 * VC state machine action 29
2050 * Send a RELEASE COMPLETE message with cause 81, "invalid call
2054 * usp pointer to protocol instance block
2055 * uvp pointer to the VCCB for the affected connection (may
2057 * msg pointer to a UNISIG message structure
2061 * errno error encountered
2065 unisig_vc_act29(usp, uvp, msg)
2067 struct unisig_vccb *uvp;
2068 struct unisig_msg *msg;
2073 * Send a RELEASE COMPLETE message
2075 rc = unisig_send_release_complete(usp, uvp, msg,
2083 * VC state machine action 30
2084 * Release routine called while SSCF session down, or SSCF session
2085 * reset or lost while in UNI_CALL_PRESENT
2087 * Go to UNI_FREE state
2090 * usp pointer to protocol instance block
2091 * uvp pointer to the VCCB for the affected connection
2092 * msg pointer to a UNISIG message structure
2096 * errno error encountered
2100 unisig_vc_act30(usp, uvp, msg)
2102 struct unisig_vccb *uvp;
2103 struct unisig_msg *msg;
2106 * Clear any running timer
2108 UNISIG_VC_CANCEL((struct vccb *) uvp);
2111 * Clear the call state
2113 uvp->uv_sstate = UNI_FREE;
2114 uvp->uv_ustate = VCCU_CLOSED;
2119 uvp->uv_tstamp = time_second;
2126 * VC state machine action 31
2127 * Accept handler called in UNI_FREE state.
2129 * The call was in UNI_CALL_PRESENT state when it was closed because
2130 * of an SSCF failure. Return an error indication. The accept
2131 * handler will free the VCCB and return the proper code to the
2135 * usp pointer to protocol instance block
2136 * uvp pointer to the VCCB for the affected connection
2137 * msg pointer to a UNISIG message structure
2141 * errno error encountered
2145 unisig_vc_act31(usp, uvp, msg)
2147 struct unisig_vccb *uvp;
2148 struct unisig_msg *msg;
2155 * Initiate clearing a call by sending a RELEASE message.
2158 * usp pointer to protocol instance block
2159 * uvp pointer to the VCCB for the affected connection
2160 * msg pointer to UNI signalling message that the RELEASE
2161 * responds to (may be NULL)
2162 * cause the reason for clearing the call; a value of
2163 * T_ATM_ABSENT indicates that the cause code is
2164 * in the VCC's ATM attributes block
2168 * errno error encountered
2172 unisig_vc_clear_call(usp, uvp, msg, cause)
2174 struct unisig_vccb *uvp;
2175 struct unisig_msg *msg;
2181 * Clear the retry count
2186 * Make sure the ATM attributes block has a valid cause code,
2189 if (cause == T_ATM_ABSENT &&
2190 uvp->uv_connvc->cvc_attr.cause.tag !=
2192 uvp->uv_connvc->cvc_attr.cause.tag = T_ATM_PRESENT;
2193 uvp->uv_connvc->cvc_attr.cause.v.coding_standard =
2195 uvp->uv_connvc->cvc_attr.cause.v.location =
2197 uvp->uv_connvc->cvc_attr.cause.v.cause_value =
2198 usp->us_proto == ATM_SIG_UNI30 ?
2199 T_ATM_CAUSE_UNSPECIFIED_NORMAL :
2200 T_ATM_CAUSE_NORMAL_CALL_CLEARING;
2204 * Send a RELEASE message
2206 rc = unisig_send_release(usp, uvp, msg, cause);
2213 UNISIG_VC_TIMER((struct vccb *) uvp, UNI_T308);
2216 * Set the VCCB state
2218 uvp->uv_sstate = UNI_RELEASE_REQUEST;
2219 if (uvp->uv_ustate != VCCU_ABORT)
2220 uvp->uv_ustate = VCCU_CLOSED;
2225 uvp->uv_tstamp = time_second;