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