1 /*
2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *	i4b_l3fsm.c - layer 3 FSM
28  *	-------------------------
29  *
30  *	$Id: i4b_l3fsm.c,v 1.1 2003/04/06 04:37:48 tg Exp $
31  *
32  * $FreeBSD$
33  *
34  *      last edit-date: [Fri Jan  5 11:33:47 2001]
35  *
36  *---------------------------------------------------------------------------*/
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: i4b_l3fsm.c,v 1.9 2002/09/27 15:37:56 provos Exp $");
40 
41 #ifdef __FreeBSD__
42 #include "i4bq931.h"
43 #else
44 #define	NI4BQ931	1
45 #endif
46 #if NI4BQ931 > 0
47 
48 #include <sys/param.h>
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
51 #include <sys/mbuf.h>
52 #include <sys/socket.h>
53 #include <net/if.h>
54 
55 #include <sys/timeout.h>
56 
57 #ifdef __FreeBSD__
58 #include <machine/i4b_debug.h>
59 #include <machine/i4b_ioctl.h>
60 #include <machine/i4b_cause.h>
61 #else
62 #include <netisdn/i4b_debug.h>
63 #include <netisdn/i4b_ioctl.h>
64 #include <netisdn/i4b_cause.h>
65 #endif
66 
67 #include <netisdn/i4b_isdnq931.h>
68 #include <netisdn/i4b_l2.h>
69 #include <netisdn/i4b_l1l2.h>
70 #include <netisdn/i4b_l3l4.h>
71 #include <netisdn/i4b_mbuf.h>
72 #include <netisdn/i4b_global.h>
73 #include <netisdn/i4b_l3.h>
74 #include <netisdn/i4b_l3fsm.h>
75 #include <netisdn/i4b_q931.h>
76 #include <netisdn/i4b_l4.h>
77 
78 
79 static void F_00A(call_desc_t *cd), F_00H(call_desc_t *cd), F_00I(call_desc_t *cd);
80 static void F_00J(call_desc_t *cd);
81 
82 static void F_01B(call_desc_t *cd), F_01K(call_desc_t *cd), F_01L(call_desc_t *cd);
83 static void F_01M(call_desc_t *cd), F_01N(call_desc_t *cd), F_01U(call_desc_t *cd);
84 static void F_01O(call_desc_t *cd);
85 
86 static void F_03C(call_desc_t *cd), F_03N(call_desc_t *cd), F_03O(call_desc_t *cd);
87 static void F_03P(call_desc_t *cd), F_03Y(call_desc_t *cd);
88 
89 static void F_04O(call_desc_t *cd);
90 
91 static void F_06D(call_desc_t *cd), F_06E(call_desc_t *cd), F_06F(call_desc_t *cd);
92 static void F_06G(call_desc_t *cd), F_06J(call_desc_t *cd), F_06Q(call_desc_t *cd);
93 
94 static void F_07E(call_desc_t *cd), F_07F(call_desc_t *cd), F_07G(call_desc_t *cd);
95 
96 static void F_08R(call_desc_t *cd), F_08Z(call_desc_t *cd);
97 
98 static void F_09D(call_desc_t *cd), F_09E(call_desc_t *cd), F_09F(call_desc_t *cd);
99 static void F_09G(call_desc_t *cd);
100 
101 static void F_11J(call_desc_t *cd), F_11Q(call_desc_t *cd), F_11V(call_desc_t *cd);
102 
103 static void F_12C(call_desc_t *cd), F_12J(call_desc_t *cd);
104 
105 static void F_19I(call_desc_t *cd), F_19J(call_desc_t *cd), F_19K(call_desc_t *cd);
106 static void F_19W(call_desc_t *cd);
107 
108 static void F_NCNA(call_desc_t *cd), F_STENQ(call_desc_t *cd), F_STAT(call_desc_t *cd);
109 static void F_INFO(call_desc_t *cd), F_RELCP(call_desc_t *cd), F_REL(call_desc_t *cd);
110 static void F_DISC(call_desc_t *cd), F_DCRQ(call_desc_t *cd), F_UEM(call_desc_t *cd);
111 static void F_SIGN(call_desc_t *cd), F_DLEI(call_desc_t *cd), F_ILL(call_desc_t *cd);
112 static void F_309TO(call_desc_t *cd), F_DECF(call_desc_t *cd), F_FCTY(call_desc_t *cd);
113 static void F_DECF1(call_desc_t *cd), F_DECF2(call_desc_t *cd), F_DECF3(call_desc_t *cd);
114 static void F_DLRI(call_desc_t *cd), F_DLRIA(call_desc_t *cd), F_DECF4(call_desc_t *cd);
115 
116 #if DO_I4B_DEBUG
117 static char *l3state_text[N_STATES] = {
118 	 "ST_U0 - Null",
119 	 "ST_U1 - Out Init",
120 	 "ST_U3 - Out Proc",
121 	 "ST_U4 - Out Delv",
122 	 "ST_U6 - In Pres",
123 	 "ST_U7 - In Rxd",
124 	 "ST_U8 - In ConReq",
125 	 "ST_U9 - In Proc",
126 	"ST_U10 - Active",
127 	"ST_U11 - Disc Req",
128 	"ST_U12 - Disc Ind",
129 	"ST_U19 - Rel Req",
130 
131 	"ST_IWA - In Wait EST-Accept",
132 	"ST_IWR - In Wait EST-Reject",
133 	"ST_OW - Out Wait EST",
134 	"ST_IWL - In Wait EST-Alert",
135 
136 	"ST_SUSE - Subroutine sets state",
137 
138 	"Illegal State"
139 };
140 
141 static char *l3event_text[N_EVENTS] = {
142 	"EV_SETUPRQ - L4 SETUP REQ",	/* setup request from L4		*/
143 	"EV_DISCRQ - L4 DISC REQ",	/* disconnect request from L4		*/
144 	"EV_RELRQ - L4 REL REQ",	/* release request from L4		*/
145 	"EV_ALERTRQ - L4 ALERT REQ",	/* alerting request from L4		*/
146 	"EV_SETACRS - L4 accept RSP",	/* setup response accept from l4	*/
147 	"EV_SETRJRS - L4 reject RSP",	/* setup response reject from l4	*/
148 	"EV_SETDCRS - L4 ignore RSP",	/* setup response dontcare from l4	*/
149 
150 	"EV_SETUP - rxd SETUP",		/* incoming SETUP message from L2	*/
151 	"EV_STATUS - rxd STATUS",	/* incoming STATUS message from L2	*/
152 	"EV_RELEASE - rxd REL",		/* incoming RELEASE message from L2	*/
153 	"EV_RELCOMP - rxd REL COMPL",	/* incoming RELEASE COMPLETE from L2	*/
154 	"EV_SETUPAK - rxd SETUP ACK",	/* incoming SETUP ACK message from L2	*/
155 	"EV_CALLPRC - rxd CALL PROC",	/* incoming CALL PROCEEDING from L2	*/
156 	"EV_ALERT - rxd ALERT",		/* incoming ALERT message from L2	*/
157 	"EV_CONNECT - rxd CONNECT",	/* incoming CONNECT message from L2	*/
158 	"EV_PROGIND - rxd PROG IND",	/* incoming Progress IND from L2	*/
159 	"EV_DISCONN - rxd DISC",	/* incoming DISCONNECT message from L2	*/
160 	"EV_CONACK - rxd CONN ACK",	/* incoming CONNECT ACK message from L2	*/
161 	"EV_STATENQ - rxd STAT ENQ",	/* incoming STATUS ENQ message from L2	*/
162 	"EV_INFO - rxd INFO",		/* incoming INFO message from L2	*/
163 	"EV_FACILITY - rxd FACILITY",	/* incoming FACILITY message 		*/
164 
165 	"EV_T303EXP - T303 timeout",	/* Timer T303 expired			*/
166 	"EV_T305EXP - T305 timeout",	/* Timer T305 expired			*/
167 	"EV_T308EXP - T308 timeout",	/* Timer T308 expired			*/
168 	"EV_T309EXP - T309 timeout",	/* Timer T309 expired			*/
169 	"EV_T310EXP - T310 timeout",	/* Timer T310 expired			*/
170 	"EV_T313EXP - T313 timeout",	/* Timer T313 expired			*/
171 
172 	"EV_DLESTIN - L2 DL_Est_Ind",	/* dl establish indication from l2	*/
173 	"EV_DLRELIN - L2 DL_Rel_Ind",	/* dl release indication from l2	*/
174 	"EV_DLESTCF - L2 DL_Est_Cnf",	/* dl establish confirm from l2		*/
175 	"EV_DLRELCF - L2 DL_Rel_Cnf",	/* dl release confirm from l2		*/
176 
177 	"EV_ILL - Illegal event!!" 	/* Illegal */
178 };
179 #endif
180 
181 /*---------------------------------------------------------------------------*
182  *	layer 3 state transition table
183  *---------------------------------------------------------------------------*/
184 struct l3state_tab {
185 	void (*func) (call_desc_t *);	/* function to execute */
186 	int newstate;				/* next state */
187 } l3state_tab[N_EVENTS][N_STATES] = {
188 
189 /* STATE:	ST_U0			ST_U1			ST_U3			ST_U4			ST_U6			ST_U7			ST_U8			ST_U9			ST_U10			ST_U11			ST_U12			ST_U19			ST_IWA			ST_IWR			ST_OW			ST_IWL			ST_SUBSET		ST_ILL	      */
190 /* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
191 /*EV_SETUPRQ*/	{{F_00A,  ST_SUSE},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL, ST_ILL},        {F_ILL, ST_ILL}},
192 /*EV_DISCRQ */	{{F_ILL,  ST_ILL},	{F_01B,	 ST_U11},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_ILL,  ST_ILL},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_ILL,	 ST_ILL},	{F_NCNA, ST_U12},	{F_ILL,	 ST_ILL},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_DCRQ, ST_U11},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
193 /*EV_RELRQ  */	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_03C,  ST_U19},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_12C,	 ST_U19},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
194 /*EV_ALERTRQ*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_06D,  ST_SUSE},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_09D,	 ST_U7},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
195 /*EV_SETACRS*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_06E,  ST_SUSE},	{F_07E,	 ST_U8},	{F_ILL,	 ST_ILL},	{F_09E,	 ST_U8},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
196 /*EV_SETRJRS*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_06F,  ST_SUSE},	{F_07F,	 ST_U0},	{F_ILL,	 ST_ILL},	{F_09F,	 ST_U0},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
197 /*EV_SETDCRS*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_06G,  ST_U0},	{F_07G,	 ST_U0},	{F_ILL,	 ST_ILL},	{F_09G,	 ST_U0},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
198 /* STATE:	ST_U0			ST_U1			ST_U3			ST_U4			ST_U6			ST_U7			ST_U8			ST_U9			ST_U10			ST_U11			ST_U12			ST_U19			ST_IWA			ST_IWR			ST_OW			ST_IWL			ST_SUBSET		ST_ILL	      */
199 /* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
200 /*EV_SETUP  */	{{F_00H,  ST_U6},	{F_SIGN, ST_U1},	{F_SIGN, ST_U3},	{F_SIGN, ST_U4},	{F_SIGN, ST_U6},	{F_SIGN, ST_U7},	{F_SIGN, ST_U8},	{F_SIGN, ST_U9},	{F_SIGN, ST_U10},	{F_SIGN, ST_U11},	{F_SIGN, ST_U12},	{F_SIGN, ST_U19},	{F_SIGN, ST_IWA},	{F_SIGN, ST_IWR},	{F_SIGN, ST_OW},	{F_SIGN, ST_IWL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
201 /*EV_STATUS */	{{F_00I,  ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_19I,	 ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_STAT, ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
202 /*EV_RELEASE*/	{{F_00J,  ST_U0},	{F_UEM,	 ST_SUSE},	{F_REL,  ST_U0},	{F_REL,  ST_U0},	{F_06J,	 ST_U0},	{F_REL,	 ST_U0},	{F_REL,	 ST_U0},	{F_REL,	 ST_U0},	{F_REL,	 ST_U0},	{F_11J,	 ST_U0},	{F_12J,	 ST_U0},	{F_19J,	 ST_U0},	{F_REL,	 ST_U0},	{F_REL,	 ST_U0},	{F_REL,	 ST_U0},	{F_REL,  ST_U0},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
203 /*EV_RELCOMP*/	{{F_NCNA, ST_U0},	{F_01K,	 ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_19K,	 ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_RELCP,ST_U0},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
204 /*EV_SETUPAK*/	{{F_UEM,  ST_SUSE},	{F_01L,	 ST_U3},	{F_UEM,  ST_SUSE},	{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
205 /*EV_CALLPRC*/	{{F_UEM,  ST_SUSE},	{F_01M,	 ST_U3},	{F_NCNA, ST_U3},	{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
206 /*EV_ALERT  */	{{F_UEM,  ST_SUSE},	{F_01N,	 ST_U4},	{F_03N,  ST_U4},	{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
207 /*EV_CONNECT*/	{{F_UEM,  ST_SUSE},	{F_01O,	 ST_U10},	{F_03O,  ST_U10},	{F_04O,  ST_U10},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
208 /*EV_PROGIND*/	{{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_03P,  ST_U3},	{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
209 /*EV_DISCONN*/	{{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_06Q,	 ST_U12},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_11Q,	 ST_U19},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_DISC, ST_U12},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
210 /*EV_CONACK */	{{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_UEM,  ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_08R,	 ST_U10},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,	 ST_SUSE},	{F_UEM,  ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
211 /*EV_STATENQ*/	{{F_STENQ,ST_U0},	{F_STENQ,ST_U1},	{F_STENQ,ST_U3},	{F_STENQ,ST_U4},	{F_STENQ,ST_U6},	{F_STENQ,ST_U7},	{F_STENQ,ST_U8},	{F_STENQ,ST_U9},	{F_STENQ,ST_U10},	{F_STENQ,ST_U11},	{F_STENQ,ST_U12},	{F_STENQ,ST_U19},	{F_STENQ,ST_IWA},	{F_STENQ,ST_IWR},	{F_STENQ,ST_OW},	{F_STENQ,ST_OW},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
212 /*EV_INFO   */	{{F_UEM,  ST_SUSE},	{F_UEM,  ST_SUSE},	{F_INFO, ST_U3},	{F_INFO, ST_U4},	{F_UEM,	 ST_SUSE},	{F_INFO, ST_U7},	{F_INFO, ST_U8},	{F_INFO, ST_U9},	{F_INFO, ST_U10},	{F_INFO, ST_U11},	{F_INFO, ST_U12},	{F_UEM,  ST_SUSE},	{F_INFO, ST_IWA},	{F_INFO, ST_IWR},	{F_INFO, ST_OW},	{F_INFO, ST_OW},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
213 /*EV_FACILITY*/	{{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_FCTY, ST_SUSE},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
214 /* STATE:	ST_U0			ST_U1			ST_U3			ST_U4			ST_U6			ST_U7			ST_U8			ST_U9			ST_U10			ST_U11			ST_U12			ST_U19			ST_IWA			ST_IWR			ST_OW			ST_IWL			ST_SUBSET		ST_ILL	      */
215 /* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
216 /*EV_T303EXP*/	{{F_ILL,  ST_ILL},	{F_01U,	 ST_SUSE},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
217 /*EV_T305EXP*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_11V,	 ST_U19},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
218 /*EV_T308EXP*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_19W,	 ST_SUSE},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
219 /*EV_T309EXP*/	{{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_309TO,ST_U0},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
220 /*EV_T310EXP*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_03Y,  ST_U11},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
221 /*EV_T313EXP*/	{{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_08Z,	 ST_U11},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
222 /* STATE:	ST_U0			ST_U1			ST_U3			ST_U4			ST_U6			ST_U7			ST_U8			ST_U9			ST_U10			ST_U11			ST_U12			ST_U19			ST_IWA			ST_IWR			ST_OW			ST_IWL			ST_SUBSET		ST_ILL	      */
223 /* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
224 /*EV_DLESTIN*/	{{F_ILL,  ST_ILL},	{F_DLEI, ST_U1},	{F_DLEI, ST_U3},	{F_DLEI, ST_U4},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_DLEI, ST_U1},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
225 /*EV_DLRELIN*/	{{F_NCNA, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRIA,ST_U10},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_DLRI, ST_U0},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
226 /*EV_DLESTCF*/	{{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF, ST_SUSE},	{F_DECF2,ST_U8},	{F_DECF3,ST_U0},	{F_DECF1,ST_U1},	{F_DECF4,ST_U7},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
227 /*EV_DLRELCF*/	{{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}},
228 /*EV_ILL    */	{{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,  ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	 ST_ILL},	{F_ILL,	ST_ILL},        {F_ILL, ST_ILL}}
229 };
230 
231 /*---------------------------------------------------------------------------*
232  *	event handler
233  *---------------------------------------------------------------------------*/
next_l3state(call_desc_t * cd,int event)234 void next_l3state(call_desc_t *cd, int event)
235 {
236 	int currstate, newstate;
237 
238 	if(event > N_EVENTS)
239 		panic("i4b_l3fsm.c: event > N_EVENTS");
240 
241 	currstate = cd->Q931state;
242 
243 	if(currstate > N_STATES)
244 		panic("i4b_l3fsm.c: currstate > N_STATES");
245 
246 	newstate = l3state_tab[event][currstate].newstate;
247 
248 	if(newstate > N_STATES)
249 		panic("i4b_l3fsm.c: newstate > N_STATES");
250 
251 	NDBGL3(L3_F_MSG, "L3 FSM event [%s]: [%s => %s]",
252 				l3event_text[event],
253                                 l3state_text[currstate],
254                                 l3state_text[newstate]);
255 
256 	/* execute function */
257 
258         (*l3state_tab[event][currstate].func)(cd);
259 
260 	if(newstate == ST_ILL)
261 	{
262 		newstate = currstate;
263 		NDBGL3(L3_F_ERR, "FSM illegal state, state = %s, event = %s!",
264 				l3state_text[newstate],
265 				l3event_text[event]);
266 	}
267 
268 	if(newstate != ST_SUSE)
269 		cd->Q931state = newstate;
270 }
271 
272 #if DO_I4B_DEBUG
273 /*---------------------------------------------------------------------------*
274  *	return pointer to current state description
275  *---------------------------------------------------------------------------*/
print_l3state(call_desc_t * cd)276 char *print_l3state(call_desc_t *cd)
277 {
278 	return((char *) l3state_text[cd->Q931state]);
279 }
280 #endif
281 
282 /*---------------------------------------------------------------------------*
283  *	L3 FSM state U0 event L4 setup req
284  *---------------------------------------------------------------------------*/
F_00A(call_desc_t * cd)285 static void F_00A(call_desc_t *cd)
286 {
287 	NDBGL3(L3_F_MSG, "FSM function F_00A executing");
288 
289 	if(i4b_get_dl_stat(cd) == DL_DOWN)
290 	{
291 		struct l2_softc * l2sc = (l2_softc_t*)cd->l3drv->l1_token;
292 		i4b_dl_establish_req(l2sc, l2sc->drv);
293 		cd->Q931state = ST_OW;
294 	}
295 	else
296 	{
297 		i4b_l3_tx_setup(cd);
298 		cd->Q931state = ST_U1;
299 	}
300 
301 	cd->T303_first_to = 1;
302 	T303_start(cd);
303 }
304 
305 /*---------------------------------------------------------------------------*
306  *	L3 FSM state U0 event SETUP from L2
307  *---------------------------------------------------------------------------*/
F_00H(call_desc_t * cd)308 static void F_00H(call_desc_t *cd)
309 {
310 	NDBGL3(L3_F_MSG, "FSM function F_00H executing");
311 	i4b_l4_connect_ind(cd);	/* tell l4 we have an incoming setup */
312 }
313 
314 /*---------------------------------------------------------------------------*
315  *	L3 FSM state U0 event STATUS from L2
316  *---------------------------------------------------------------------------*/
F_00I(call_desc_t * cd)317 static void F_00I(call_desc_t *cd)
318 {
319 	NDBGL3(L3_F_MSG, "FSM function F_00I executing");
320 
321 	if(cd->call_state != 0)
322 	{
323 		cd->cause_out = 101;
324 		i4b_l3_tx_release_complete(cd, 1);	/* 1 = send cause */
325 	}
326 	cd->Q931state = ST_U0;
327 }
328 
329 /*---------------------------------------------------------------------------*
330  *	L3 FSM state U0 event RELEASE from L2
331  *---------------------------------------------------------------------------*/
F_00J(call_desc_t * cd)332 static void F_00J(call_desc_t *cd)
333 {
334 	NDBGL3(L3_F_MSG, "FSM function F_00J executing");
335 	i4b_l3_tx_release_complete(cd, 0);	/* 0 = don't send cause */
336 }
337 
338 /*---------------------------------------------------------------------------*
339  *	L3 FSM state U1 event disconnect req from L4
340  *---------------------------------------------------------------------------*/
F_01B(call_desc_t * cd)341 static void F_01B(call_desc_t *cd)
342 {
343 	NDBGL3(L3_F_MSG, "FSM function F_01B executing");
344 	/* cause from L4 */
345 	i4b_l3_tx_disconnect(cd);
346 	T303_stop(cd);
347 	T305_start(cd);
348 }
349 
350 /*---------------------------------------------------------------------------*
351  *	L3 FSM state U1 event RELEASE COMPLETE from L2
352  *---------------------------------------------------------------------------*/
F_01K(call_desc_t * cd)353 static void F_01K(call_desc_t *cd)
354 {
355 	NDBGL3(L3_F_MSG, "FSM function F_01K executing");
356 	T303_stop(cd);
357 	i4b_l4_disconnect_ind(cd);	/* tell l4 we were rejected */
358 	freecd_by_cd(cd);
359 }
360 
361 /*---------------------------------------------------------------------------*
362  *	L3 FSM state U1 event SETUP ACK from L2
363  *---------------------------------------------------------------------------*/
F_01L(call_desc_t * cd)364 static void F_01L(call_desc_t *cd)
365 {
366 	NDBGL3(L3_F_MSG, "FSM function F_01L executing");
367 	T303_stop(cd);
368 
369 	/*
370 	 * since this implementation does NOT support overlap sending,
371 	 * we react here as if we received a CALL PROCEEDING because
372 	 * several PBX's react with a SETUP ACK even if the called
373 	 * number is complete AND we sent a SENDING COMPLETE in the
374 	 * preceding SETUP message. (-hm)
375 	 */
376 
377 	T310_start(cd);
378 	i4b_l4_proceeding_ind(cd);
379 }
380 
381 /*---------------------------------------------------------------------------*
382  *	L3 FSM state U1 event CALL PROCEEDING from L2
383  *---------------------------------------------------------------------------*/
F_01M(call_desc_t * cd)384 static void F_01M(call_desc_t *cd)
385 {
386 	NDBGL3(L3_F_MSG, "FSM function F_01M executing");
387 	T303_stop(cd);
388 	T310_start(cd);
389 	i4b_l4_proceeding_ind(cd);
390 }
391 
392 /*---------------------------------------------------------------------------*
393  *	L3 FSM state U1 event ALERT from L2  (XXX !)
394  *---------------------------------------------------------------------------*/
F_01N(call_desc_t * cd)395 static void F_01N(call_desc_t *cd)
396 {
397 	NDBGL3(L3_F_MSG, "FSM function F_01N executing");
398 	T303_stop(cd);
399 	i4b_l4_alert_ind(cd);
400 }
401 
402 /*---------------------------------------------------------------------------*
403  *	L3 FSM state U1 event CONNECT from L2 (XXX !)
404  *---------------------------------------------------------------------------*/
F_01O(call_desc_t * cd)405 static void F_01O(call_desc_t *cd)
406 {
407 	NDBGL3(L3_F_MSG, "FSM function F_01O executing");
408 	T303_stop(cd);
409 	i4b_l3_tx_connect_ack(cd);
410 	i4b_l4_connect_active_ind(cd);
411 }
412 
413 /*---------------------------------------------------------------------------*
414  *	L3 FSM state U1 event T303 timeout
415  *---------------------------------------------------------------------------*/
F_01U(call_desc_t * cd)416 static void F_01U(call_desc_t *cd)
417 {
418 	NDBGL3(L3_F_MSG, "FSM function F_01U executing");
419 	if(cd->T303_first_to == 1)
420 	{
421 		cd->T303_first_to = 0;
422 		i4b_l3_tx_setup(cd);
423 		T303_start(cd);
424 		cd->Q931state = ST_U1;
425 	}
426 	else
427 	{
428 		i4b_l4_disconnect_ind(cd);
429 		freecd_by_cd(cd);
430 		cd->Q931state = ST_U0;
431 	}
432 }
433 
434 /*---------------------------------------------------------------------------*
435  *	L3 FSM state U3 event release req from L4
436  *---------------------------------------------------------------------------*/
F_03C(call_desc_t * cd)437 static void F_03C(call_desc_t *cd)
438 {
439 	NDBGL3(L3_F_MSG, "FSM function F_03C executing");
440 	T310_stop(cd);
441 	cd->cause_out = 6;
442 	i4b_l3_tx_release(cd, 1);	/* 0 = don't send cause */
443 	cd->T308_first_to = 1;
444 	T308_start(cd);
445 }
446 
447 /*---------------------------------------------------------------------------*
448  *	L3 FSM state U3 event ALERT from L2
449  *---------------------------------------------------------------------------*/
F_03N(call_desc_t * cd)450 static void F_03N(call_desc_t *cd)
451 {
452 	NDBGL3(L3_F_MSG, "FSM function F_03N executing");
453 	T310_stop(cd);
454 	i4b_l4_alert_ind(cd);
455 }
456 
457 /*---------------------------------------------------------------------------*
458  *	L3 FSM state U3 event CONNECT from L2
459  *---------------------------------------------------------------------------*/
F_03O(call_desc_t * cd)460 static void F_03O(call_desc_t *cd)
461 {
462 	NDBGL3(L3_F_MSG, "FSM function F_03O executing");
463 	T310_stop(cd);
464 	i4b_l3_tx_connect_ack(cd);	/* CONNECT ACK to network */
465 	i4b_l4_connect_active_ind(cd);
466 }
467 
468 /*---------------------------------------------------------------------------*
469  *	L3 FSM state U3 event PROGESS IND from L2
470  *---------------------------------------------------------------------------*/
F_03P(call_desc_t * cd)471 static void F_03P(call_desc_t *cd)
472 {
473 	NDBGL3(L3_F_MSG, "FSM function F_03P executing");
474 	T310_stop(cd);
475 #ifdef NOTDEF
476 	i4b_l4_progress_ind(cd);
477 #endif
478 }
479 
480 /*---------------------------------------------------------------------------*
481  *	L3 FSM state U3 event T310 timeout
482  *---------------------------------------------------------------------------*/
F_03Y(call_desc_t * cd)483 static void F_03Y(call_desc_t *cd)
484 {
485 	NDBGL3(L3_F_MSG, "FSM function F_03Y executing");
486 	cd->cause_out = 102;	/* recovery on timer expiry */
487 	i4b_l3_tx_disconnect(cd);
488 	T305_start(cd);
489 	i4b_l4_disconnect_ind(cd);
490 }
491 
492 /*---------------------------------------------------------------------------*
493  *	L3 FSM state U4 event CONNECT from L2
494  *---------------------------------------------------------------------------*/
F_04O(call_desc_t * cd)495 static void F_04O(call_desc_t *cd)
496 {
497 	NDBGL3(L3_F_MSG, "FSM function F_04O executing");
498 	i4b_l3_tx_connect_ack(cd);	/* CONNECT ACK to network */
499 	i4b_l4_connect_active_ind(cd);
500 }
501 
502 /*---------------------------------------------------------------------------*
503  *	L3 FSM state U6 event alert req from L4
504  *---------------------------------------------------------------------------*/
F_06D(call_desc_t * cd)505 static void F_06D(call_desc_t *cd)
506 {
507 	NDBGL3(L3_F_MSG, "FSM function F_06D executing");
508 
509 	if(i4b_get_dl_stat(cd) == DL_DOWN)
510 	{
511 		struct l2_softc * l2sc = (l2_softc_t*)cd->l3drv->l1_token;
512 		i4b_dl_establish_req(l2sc, l2sc->drv);
513 		cd->Q931state = ST_IWL;
514 	}
515 	else
516 	{
517 		i4b_l3_tx_alert(cd);
518 		cd->Q931state = ST_U7;
519 	}
520 }
521 
522 /*---------------------------------------------------------------------------*
523  *	L3 FSM state U6 event incoming setup accept from L4
524  *---------------------------------------------------------------------------*/
F_06E(call_desc_t * cd)525 static void F_06E(call_desc_t *cd)
526 {
527 	NDBGL3(L3_F_MSG, "FSM function F_06E executing");
528 
529 	if(i4b_get_dl_stat(cd) == DL_DOWN)
530 	{
531 		struct l2_softc * l2sc = (l2_softc_t*)cd->l3drv->l1_token;
532 		i4b_dl_establish_req(l2sc, l2sc->drv);
533 		cd->Q931state = ST_IWA;
534 	}
535 	else
536 	{
537 		i4b_l3_tx_connect(cd);
538 		cd->Q931state = ST_U8;
539 	}
540 	T313_start(cd);
541 }
542 
543 /*---------------------------------------------------------------------------*
544  *	L3 FSM state U6 event incoming setup reject from L4
545  *---------------------------------------------------------------------------*/
F_06F(call_desc_t * cd)546 static void F_06F(call_desc_t *cd)
547 {
548 	NDBGL3(L3_F_MSG, "FSM function F_06F executing");
549 
550 	if(i4b_get_dl_stat(cd) == DL_DOWN)
551 	{
552 		struct l2_softc * l2sc = (l2_softc_t*)cd->l3drv->l1_token;
553 		i4b_dl_establish_req(l2sc, l2sc->drv);
554 		cd->Q931state = ST_IWR;
555 	}
556 	else
557 	{
558 		int s = splnet();
559 		i4b_l3_tx_release_complete(cd, 1);
560 		cd->Q931state = ST_U0;
561 		freecd_by_cd(cd);
562 		splx(s);
563 	}
564 }
565 
566 /*---------------------------------------------------------------------------*
567  *	L3 FSM state U6 event incoming setup ignore from L4
568  *---------------------------------------------------------------------------*/
F_06G(call_desc_t * cd)569 static void F_06G(call_desc_t *cd)
570 {
571 	NDBGL3(L3_F_MSG, "FSM function F_06G executing");
572 	freecd_by_cd(cd);
573 }
574 
575 /*---------------------------------------------------------------------------*
576  *	L3 FSM state U6 event RELEASE from L2
577  *---------------------------------------------------------------------------*/
F_06J(call_desc_t * cd)578 static void F_06J(call_desc_t *cd)
579 {
580 	NDBGL3(L3_F_MSG, "FSM function F_06J executing");
581 	i4b_l3_tx_release_complete(cd, 0);
582 	i4b_l4_disconnect_ind(cd);
583 	freecd_by_cd(cd);
584 }
585 
586 /*---------------------------------------------------------------------------*
587  *	L3 FSM state U6 event DISCONNECT from L2
588  *---------------------------------------------------------------------------*/
F_06Q(call_desc_t * cd)589 static void F_06Q(call_desc_t *cd)
590 {
591 	NDBGL3(L3_F_MSG, "FSM function F_06Q executing");
592 	i4b_l4_disconnect_ind(cd);
593 }
594 
595 /*---------------------------------------------------------------------------*
596  *	L3 FSM state U7 event setup response accept from L4
597  *---------------------------------------------------------------------------*/
F_07E(call_desc_t * cd)598 static void F_07E(call_desc_t *cd)
599 {
600 	NDBGL3(L3_F_MSG, "FSM function F_07E executing");
601 	i4b_l3_tx_connect(cd);
602 	T313_start(cd);
603 }
604 
605 /*---------------------------------------------------------------------------*
606  *	L3 FSM state U7 event setup response reject from L4
607  *---------------------------------------------------------------------------*/
F_07F(call_desc_t * cd)608 static void F_07F(call_desc_t *cd)
609 {
610 	NDBGL3(L3_F_MSG, "FSM function F_07F executing");
611 	i4b_l3_tx_release_complete(cd, 1);
612 	freecd_by_cd(cd);
613 }
614 
615 /*---------------------------------------------------------------------------*
616  *	L3 FSM state U7 event setup response ignore from L4
617  *---------------------------------------------------------------------------*/
F_07G(call_desc_t * cd)618 static void F_07G(call_desc_t *cd)
619 {
620 	NDBGL3(L3_F_MSG, "FSM function F_07G executing");
621 	freecd_by_cd(cd);
622 }
623 
624 /*---------------------------------------------------------------------------*
625  *	L3 FSM state U8 event CONNECT ACK from L2
626  *---------------------------------------------------------------------------*/
F_08R(call_desc_t * cd)627 static void F_08R(call_desc_t *cd)
628 {
629 	NDBGL3(L3_F_MSG, "FSM function F_08R executing");
630 	T313_stop(cd);
631 	i4b_l4_connect_active_ind(cd);
632 }
633 
634 /*---------------------------------------------------------------------------*
635  *	L3 FSM state U8 event T313 timeout
636  *---------------------------------------------------------------------------*/
F_08Z(call_desc_t * cd)637 static void F_08Z(call_desc_t *cd)
638 {
639 	NDBGL3(L3_F_MSG, "FSM function F_08Z executing");
640 	cd->cause_out = 102;	/* recovery on timer expiry */
641 	i4b_l3_tx_disconnect(cd);
642 	T305_start(cd);
643 	i4b_l4_disconnect_ind(cd);
644 }
645 
646 /*---------------------------------------------------------------------------*
647  *	L3 FSM state U9 event alert req from L4
648  *---------------------------------------------------------------------------*/
F_09D(call_desc_t * cd)649 static void F_09D(call_desc_t *cd)
650 {
651 	NDBGL3(L3_F_MSG, "FSM function F_09D executing");
652 	i4b_l3_tx_alert(cd);
653 }
654 
655 /*---------------------------------------------------------------------------*
656  *	L3 FSM state U9 event setup response accept from L4
657  *---------------------------------------------------------------------------*/
F_09E(call_desc_t * cd)658 static void F_09E(call_desc_t *cd)
659 {
660 	NDBGL3(L3_F_MSG, "FSM function F_09E executing");
661 	i4b_l3_tx_connect(cd);
662 	T313_start(cd);
663 }
664 
665 /*---------------------------------------------------------------------------*
666  *	L3 FSM state U9 event setup response reject from L4
667  *---------------------------------------------------------------------------*/
F_09F(call_desc_t * cd)668 static void F_09F(call_desc_t *cd)
669 {
670 	NDBGL3(L3_F_MSG, "FSM function F_09F executing");
671 	i4b_l3_tx_release_complete(cd, 1);
672 	freecd_by_cd(cd);
673 }
674 /*---------------------------------------------------------------------------*
675  *	L3 FSM state U9 event setup response ignore from L4
676  *---------------------------------------------------------------------------*/
F_09G(call_desc_t * cd)677 static void F_09G(call_desc_t *cd)
678 {
679 	NDBGL3(L3_F_MSG, "FSM function F_09G executing");
680 	freecd_by_cd(cd);
681 }
682 
683 /*---------------------------------------------------------------------------*
684  *	L3 FSM state U11 event RELEASE from L2
685  *---------------------------------------------------------------------------*/
F_11J(call_desc_t * cd)686 static void F_11J(call_desc_t *cd)
687 {
688 	NDBGL3(L3_F_MSG, "FSM function F_11J executing");
689 	T305_stop(cd);
690 	i4b_l3_tx_release_complete(cd, 0);
691 	i4b_l4_disconnect_ind(cd);
692 	freecd_by_cd(cd);
693 }
694 
695 /*---------------------------------------------------------------------------*
696  *	L3 FSM state U11 event DISCONNECT from L2
697  *---------------------------------------------------------------------------*/
F_11Q(call_desc_t * cd)698 static void F_11Q(call_desc_t *cd)
699 {
700 	NDBGL3(L3_F_MSG, "FSM function F_11Q executing");
701 	T305_stop(cd);
702 	i4b_l3_tx_release(cd, 0);
703 	cd->T308_first_to = 1;
704 	T308_start(cd);
705 }
706 
707 /*---------------------------------------------------------------------------*
708  *	L3 FSM state U11 event T305 timeout
709  *---------------------------------------------------------------------------*/
F_11V(call_desc_t * cd)710 static void F_11V(call_desc_t *cd)
711 {
712 	NDBGL3(L3_F_MSG, "FSM function F_11V executing");
713 	cd->cause_out = 102;
714 	i4b_l3_tx_release(cd, 1);
715 	cd->T308_first_to = 1;
716 	T308_start(cd);
717 }
718 
719 /*---------------------------------------------------------------------------*
720  *	L3 FSM state U12 event release req from L4
721  *---------------------------------------------------------------------------*/
F_12C(call_desc_t * cd)722 static void F_12C(call_desc_t *cd)
723 {
724 	NDBGL3(L3_F_MSG, "FSM function F_12C executing");
725 	i4b_l3_tx_release(cd, 1);
726 	cd->T308_first_to = 1;
727 	T308_start(cd);
728 }
729 
730 /*---------------------------------------------------------------------------*
731  *	L3 FSM state U12 event RELEASE from L2
732  *---------------------------------------------------------------------------*/
F_12J(call_desc_t * cd)733 static void F_12J(call_desc_t *cd)
734 {
735 	NDBGL3(L3_F_MSG, "FSM function F_12J executing");
736 	i4b_l3_tx_release_complete(cd, 0);
737 	i4b_l4_disconnect_ind(cd);
738 	freecd_by_cd(cd);
739 }
740 
741 /*---------------------------------------------------------------------------*
742  *	L3 FSM state U19 event STATUS from L2
743  *---------------------------------------------------------------------------*/
F_19I(call_desc_t * cd)744 static void F_19I(call_desc_t *cd)
745 {
746 	NDBGL3(L3_F_MSG, "FSM function F_19I executing");
747 
748 	if(cd->call_state == 0)
749 	{
750 		i4b_l4_status_ind(cd);
751 		freecd_by_cd(cd);
752 		cd->Q931state = ST_U0;
753 	}
754 	else
755 	{
756 		cd->Q931state = ST_U19;
757 	}
758 }
759 
760 /*---------------------------------------------------------------------------*
761  *	L3 FSM state U19 event RELEASE from L2
762  *---------------------------------------------------------------------------*/
F_19J(call_desc_t * cd)763 static void F_19J(call_desc_t *cd)
764 {
765 	NDBGL3(L3_F_MSG, "FSM function F_19J executing");
766 	T308_stop(cd);
767 	i4b_l4_disconnect_ind(cd);
768 	freecd_by_cd(cd);
769 }
770 
771 /*---------------------------------------------------------------------------*
772  *	L3 FSM state U19 event RELEASE COMPLETE from L2
773  *---------------------------------------------------------------------------*/
F_19K(call_desc_t * cd)774 static void F_19K(call_desc_t *cd)
775 {
776 	NDBGL3(L3_F_MSG, "FSM function F_19K executing");
777 	T308_stop(cd);
778 	i4b_l4_disconnect_ind(cd);
779 	freecd_by_cd(cd);
780 }
781 
782 /*---------------------------------------------------------------------------*
783  *	L3 FSM state U19 event T308 timeout
784  *---------------------------------------------------------------------------*/
F_19W(call_desc_t * cd)785 static void F_19W(call_desc_t *cd)
786 {
787 	NDBGL3(L3_F_MSG, "FSM function F_19W executing");
788 	if(cd->T308_first_to == 0)
789 	{
790 		cd->T308_first_to = 1;
791 		i4b_l3_tx_release(cd, 0);
792 		T308_start(cd);
793 		cd->Q931state = ST_U19;
794 	}
795 	else
796 	{
797 		cd->T308_first_to = 0;
798 		i4b_l4_disconnect_ind(cd);
799 		freecd_by_cd(cd);
800 		cd->Q931state = ST_U0;
801 	}
802 }
803 
804 /*---------------------------------------------------------------------------*
805  *	L3 FSM routine no change no action
806  *---------------------------------------------------------------------------*/
F_NCNA(call_desc_t * cd)807 static void F_NCNA(call_desc_t *cd)
808 {
809 }
810 
811 /*---------------------------------------------------------------------------*
812  *	L3 FSM any state event STATUS ENQ from L2
813  *---------------------------------------------------------------------------*/
F_STENQ(call_desc_t * cd)814 static void F_STENQ(call_desc_t *cd)
815 {
816 	NDBGL3(L3_F_MSG, "FSM function F_STENQ executing");
817 	i4b_l3_tx_status(cd, CAUSE_Q850_STENQRSP); /* 30, resonse to stat enq */
818 }
819 
820 /*---------------------------------------------------------------------------*
821  *	L3 FSM any state except 0 & 19 event STATUS from L2
822  *---------------------------------------------------------------------------*/
F_STAT(call_desc_t * cd)823 static void F_STAT(call_desc_t *cd)
824 {
825 	NDBGL3(L3_F_MSG, "FSM function F_STAT executing");
826 	if(cd->call_state == 0)
827 	{
828 		i4b_l4_status_ind(cd);
829 		cd->Q931state = ST_U0;
830 		freecd_by_cd(cd);
831 	}
832 	else
833 	{
834 		/* XXX !!!!!!!!!!!!!!!!!! */
835 
836 		i4b_l4_status_ind(cd);
837 		cd->cause_out = 101;	/* message not compatible with call state */
838 		i4b_l3_tx_disconnect(cd);
839 		T305_start(cd);
840 		cd->Q931state = ST_U11;
841 	}
842 }
843 
844 /*---------------------------------------------------------------------------*
845  *	L3 FSM some states event INFORMATION from L2
846  *---------------------------------------------------------------------------*/
F_INFO(call_desc_t * cd)847 static void F_INFO(call_desc_t *cd)
848 {
849 	NDBGL3(L3_F_MSG, "FSM function F_INFO executing");
850 	i4b_l4_info_ind(cd);
851 	/* remain in current state */
852 }
853 
854 /*---------------------------------------------------------------------------*
855  *	L3 FSM some states event RELEASE COMPLETE from L2
856  *---------------------------------------------------------------------------*/
F_RELCP(call_desc_t * cd)857 static void F_RELCP(call_desc_t *cd)
858 {
859 	NDBGL3(L3_F_MSG, "FSM function F_RELCP executing");
860 	i4b_l3_stop_all_timers(cd);
861 	i4b_l4_disconnect_ind(cd);
862 	freecd_by_cd(cd);
863 }
864 
865 /*---------------------------------------------------------------------------*
866  *	L3 FSM some states event RELEASE from L2
867  *---------------------------------------------------------------------------*/
F_REL(call_desc_t * cd)868 static void F_REL(call_desc_t *cd)
869 {
870 	NDBGL3(L3_F_MSG, "FSM function F_REL executing");
871 	i4b_l3_stop_all_timers(cd);
872 	i4b_l3_tx_release_complete(cd, 0);
873 	i4b_l4_disconnect_ind(cd);
874 	freecd_by_cd(cd);
875 }
876 
877 /*---------------------------------------------------------------------------*
878  *	L3 FSM some states event DISCONNECT from L2
879  *---------------------------------------------------------------------------*/
F_DISC(call_desc_t * cd)880 static void F_DISC(call_desc_t *cd)
881 {
882 	NDBGL3(L3_F_MSG, "FSM function F_DISC executing");
883 	i4b_l3_stop_all_timers(cd);
884 
885 	/*
886 	 * no disconnect ind to L4, no jump to state U12
887 	 * instead we issue a RELEASE and jump to U19
888 	 */
889 
890 	i4b_l3_tx_release(cd, 0);
891 	cd->T308_first_to = 1;
892 	T308_start(cd);
893 	cd->Q931state = ST_U19;
894 }
895 
896 /*---------------------------------------------------------------------------*
897  *	L3 FSM some states event disconnect request from L4
898  *---------------------------------------------------------------------------*/
F_DCRQ(call_desc_t * cd)899 static void F_DCRQ(call_desc_t *cd)
900 {
901 	NDBGL3(L3_F_MSG, "FSM function F_DCRQ executing");
902 
903 	/* stop T310 in case this is the result of an incoming call for a */
904 	/* calledback connection */
905 
906 	if(cd->T310 == TIMER_ACTIVE)
907 		T310_stop(cd);
908 
909 	/* cause from L4 */
910 	i4b_l3_tx_disconnect(cd);
911 	T305_start(cd);
912 	cd->Q931state = ST_U11;
913 }
914 
915 /*---------------------------------------------------------------------------*
916  *	L3 FSM any state except 0 event unexpected message from L2
917  *---------------------------------------------------------------------------*/
F_UEM(call_desc_t * cd)918 static void F_UEM(call_desc_t *cd)
919 {
920 	NDBGL3(L3_F_ERR, "FSM function F_UEM executing, state = %s", print_l3state(cd));
921 	i4b_l3_tx_status(cd, CAUSE_Q850_MSGNCWCS); /* 101, message not compatible with call state */
922 }
923 
924 /*---------------------------------------------------------------------------*
925  *	L3 FSM any state except 0 event SETUP from L2
926  *---------------------------------------------------------------------------*/
F_SIGN(call_desc_t * cd)927 static void F_SIGN(call_desc_t *cd)
928 {
929 	NDBGL3(L3_F_ERR, "FSM function F_SIGN executing");
930 
931 /* XXX */ /* freecd_by_cd(cd); ?????????? XXX */
932 }
933 
934 /*---------------------------------------------------------------------------*
935  *	L3 FSM relevant states event DL ESTABLISH IND from L2
936  *---------------------------------------------------------------------------*/
F_DLEI(call_desc_t * cd)937 static void F_DLEI(call_desc_t *cd)
938 {
939 	NDBGL3(L3_F_MSG, "FSM function F_DLEI executing");
940 
941 /* XXX */
942 
943 	/* remain in current state */
944 }
945 
946 /*---------------------------------------------------------------------------*
947  *	L3 FSM any state event illegal event occurred
948  *---------------------------------------------------------------------------*/
F_ILL(call_desc_t * cd)949 static void F_ILL(call_desc_t *cd)
950 {
951 	NDBGL3(L3_F_MSG, "FSM function F_ILL executing");
952 }
953 
954 /*---------------------------------------------------------------------------*
955  *	L3 FSM any state event T309 timeout
956  *---------------------------------------------------------------------------*/
F_309TO(call_desc_t * cd)957 static void F_309TO(call_desc_t *cd)
958 {
959 	NDBGL3(L3_F_ERR, "FSM function F_309TO executing");
960 
961 /* XXX */
962 
963 #ifdef NOTDEF
964 	i4b_l4_dl_fail_ind(cd);
965 #endif
966 
967 	freecd_by_cd(cd);
968 }
969 
970 /*---------------------------------------------------------------------------*
971  *	L3 FSM any state event FACILITY message received
972  *---------------------------------------------------------------------------*/
F_FCTY(call_desc_t * cd)973 static void F_FCTY(call_desc_t *cd)
974 {
975 	NDBGL3(L3_F_MSG, "FSM function F_FCTY executing");
976 	/* ST_SUSE, no change in state ! */
977 }
978 
979 /*---------------------------------------------------------------------------*
980  *	L3 FSM state ST_OW event DL ESTABLISH CONF from L2
981  *---------------------------------------------------------------------------*/
F_DECF1(call_desc_t * cd)982 static void F_DECF1(call_desc_t *cd)
983 {
984 	NDBGL3(L3_F_MSG, "FSM function F_DECF1 executing");
985 	i4b_l3_tx_setup(cd);
986 }
987 
988 /*---------------------------------------------------------------------------*
989  *	L3 FSM state ST_IWA event DL ESTABLISH CONF from L2
990  *---------------------------------------------------------------------------*/
F_DECF2(call_desc_t * cd)991 static void F_DECF2(call_desc_t *cd)
992 {
993 	NDBGL3(L3_F_MSG, "FSM function F_DECF2 executing");
994 	i4b_l3_tx_connect(cd);
995 }
996 
997 /*---------------------------------------------------------------------------*
998  *	L3 FSM state ST_IWR event DL ESTABLISH CONF from L2
999  *---------------------------------------------------------------------------*/
F_DECF3(call_desc_t * cd)1000 static void F_DECF3(call_desc_t *cd)
1001 {
1002 	NDBGL3(L3_F_MSG, "FSM function F_DECF3 executing");
1003 	i4b_l3_tx_release_complete(cd, 1);
1004 	freecd_by_cd(cd);
1005 }
1006 
1007 /*---------------------------------------------------------------------------*
1008  *	L3 FSM state ST_IWL event DL ESTABLISH CONF from L2
1009  *---------------------------------------------------------------------------*/
F_DECF4(call_desc_t * cd)1010 static void F_DECF4(call_desc_t *cd)
1011 {
1012 	NDBGL3(L3_F_MSG, "FSM function F_DECF4 executing");
1013 	i4b_l3_tx_alert(cd);
1014 }
1015 
1016 
1017 /*---------------------------------------------------------------------------*
1018  *	L3 FSM any state event DL ESTABLISH CONF from L2
1019  *---------------------------------------------------------------------------*/
F_DECF(call_desc_t * cd)1020 static void F_DECF(call_desc_t *cd)
1021 {
1022 	NDBGL3(L3_F_MSG, "FSM function F_DECF executing");
1023 	T309_stop(cd);
1024 	i4b_l3_tx_status(cd, CAUSE_Q850_NORMUNSP); /* 31, normal unspecified */
1025 }
1026 
1027 /*---------------------------------------------------------------------------*
1028  *	L3 FSM any state except U10 event DL RELEASE IND from L2
1029  *---------------------------------------------------------------------------*/
F_DLRI(call_desc_t * cd)1030 static void F_DLRI(call_desc_t *cd)
1031 {
1032 	NDBGL3(L3_F_MSG, "FSM function F_DLRI executing");
1033 	i4b_l3_stop_all_timers(cd);
1034 	i4b_l4_disconnect_ind(cd);
1035 	freecd_by_cd(cd);
1036 }
1037 
1038 /*---------------------------------------------------------------------------*
1039  *	L3 FSM state U10 event DL RELEASE IND from L2
1040  *---------------------------------------------------------------------------*/
F_DLRIA(call_desc_t * cd)1041 static void F_DLRIA(call_desc_t *cd)
1042 {
1043 	struct l2_softc * l2sc = (l2_softc_t*)cd->l3drv->l1_token;
1044 	NDBGL3(L3_F_MSG, "FSM function F_DLRIA executing");
1045 
1046 	if(cd->T309 == TIMER_IDLE)
1047 		T309_start(cd);
1048 
1049 	i4b_dl_establish_req(l2sc, l2sc->drv);
1050 }
1051 
1052 #endif /* NI4BQ931 > 0 */
1053