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