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