libisdn
Q931StateTE.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   FileName:             q931StateTE.c
00004 
00005   Contents:             Q.931 State Engine for TE (User Mode).
00006 
00007                         The controlling state engine for Q.931 is the state engine
00008                         on the NT side. The state engine on the TE side is a slave
00009                         of this. The TE side maintain it's own states as described in
00010                         ITU-T Q931, but will in raise conditions be overridden by
00011                         the NT side.
00012 
00013                         This reference implementation uses a process per message,
00014                         meaning that each message must check call states. This
00015                         is easier for dialect maintenance as each message proc
00016                         can be replaced individually. A new TE variant only
00017                         need to copy the Q931CreateTE and replace those procs or
00018                         need to override.
00019 
00020   License/Copyright:
00021 
00022   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
00023   email:janvb@caselaboratories.com
00024 
00025   Redistribution and use in source and binary forms, with or without
00026   modification, are permitted provided that the following conditions are
00027   met:
00028 
00029         * Redistributions of source code must retain the above copyright notice,
00030           this list of conditions and the following disclaimer.
00031         * Redistributions in binary form must reproduce the above copyright notice,
00032           this list of conditions and the following disclaimer in the documentation
00033           and/or other materials provided with the distribution.
00034         * Neither the name of the Case Labs, Ltd nor the names of its contributors
00035           may be used to endorse or promote products derived from this software
00036           without specific prior written permission.
00037 
00038   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00039   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00040   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00041   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00042   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00043   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00044   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00045   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00046   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00047   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00048   POSSIBILITY OF SUCH DAMAGE.
00049 *****************************************************************************/
00050 #include <stdlib.h>
00051 
00052 #include "Q931.h"
00053 #include "Q931priv.h"
00054 #include "Q932.h"
00055 
00056 extern L3INT Q931L4HeaderSpace;
00057 extern struct Q931MessageIE Q931MessageIEs[];
00058 
00068 void Q931CreateTE(struct Q931Dialect *d)
00069 {
00070         Q931DialectSetName(d, "Q.931 TE");
00071 
00072         /*
00073          * Flags
00074          */
00075         Q931DialectSetFlag(d, 0);
00076 
00077         /*
00078          * Codesets
00079          */
00080         Q931DialectAddCodeset(d, Q931_CODESET_0);
00081 
00082         /*
00083          * Q.931 Message encoder/decoder/handler table
00084          */
00085         Q931DialectSetMesProc(d, Q931mes_ALERTING,             Q931ProcAlertingTE,          Q931Umes_Generic, Q931Pmes_Generic);
00086         Q931DialectSetMesProc(d, Q931mes_CALL_PROCEEDING,      Q931ProcCallProceedingTE,    Q931Umes_Generic, Q931Pmes_Generic);
00087         Q931DialectSetMesProc(d, Q931mes_CONNECT,              Q931ProcConnectTE,           Q931Umes_Generic, Q931Pmes_Generic);
00088         Q931DialectSetMesProc(d, Q931mes_CONNECT_ACKNOWLEDGE,  Q931ProcConnectAckTE,        Q931Umes_Generic, Q931Pmes_Generic);
00089         Q931DialectSetMesProc(d, Q931mes_PROGRESS,             Q931ProcProgressTE,          Q931Umes_Generic, Q931Pmes_Generic);
00090         Q931DialectSetMesProc(d, Q931mes_SETUP,                Q931ProcSetupTE,             Q931Umes_Generic, Q931Pmes_Generic);
00091         Q931DialectSetMesProc(d, Q931mes_SETUP_ACKNOWLEDGE,    Q931ProcSetupAckTE,          Q931Umes_Generic, Q931Pmes_Generic);
00092         Q931DialectSetMesProc(d, Q931mes_RESUME,               Q931ProcResumeTE,            Q931Umes_Generic, Q931Pmes_Generic);
00093         Q931DialectSetMesProc(d, Q931mes_RESUME_ACKNOWLEDGE,   Q931ProcResumeAckTE,         Q931Umes_Generic, Q931Pmes_Generic);
00094         Q931DialectSetMesProc(d, Q931mes_RESUME_REJECT,        Q931ProcResumeRejectTE,      Q931Umes_Generic, Q931Pmes_Generic);
00095         Q931DialectSetMesProc(d, Q931mes_SUSPEND,              Q931ProcSuspendTE,           Q931Umes_Generic, Q931Pmes_Generic);
00096         Q931DialectSetMesProc(d, Q931mes_SUSPEND_ACKNOWLEDGE,  Q931ProcSuspendAckTE,        Q931Umes_Generic, Q931Pmes_Generic);
00097         Q931DialectSetMesProc(d, Q931mes_SUSPEND_REJECT,       Q931ProcSuspendRejectTE,     Q931Umes_Generic, Q931Pmes_Generic);
00098         Q931DialectSetMesProc(d, Q931mes_USER_INFORMATION,     Q931ProcUserInformationTE,   Q931Umes_Generic, Q931Pmes_Generic);
00099         Q931DialectSetMesProc(d, Q931mes_DISCONNECT,           Q931ProcDisconnectTE,        Q931Umes_Generic, Q931Pmes_Generic);
00100         Q931DialectSetMesProc(d, Q931mes_RELEASE,              Q931ProcReleaseTE,           Q931Umes_Generic, Q931Pmes_Generic);
00101         Q931DialectSetMesProc(d, Q931mes_RELEASE_COMPLETE,     Q931ProcReleaseCompleteTE,   Q931Umes_Generic, Q931Pmes_Generic);
00102         Q931DialectSetMesProc(d, Q931mes_RESTART,              Q931ProcRestartTE,           Q931Umes_Generic, Q931Pmes_Generic);
00103         Q931DialectSetMesProc(d, Q931mes_RESTART_ACKNOWLEDGE,  Q931ProcRestartAckTE,        Q931Umes_Generic, Q931Pmes_Generic);
00104         Q931DialectSetMesProc(d, Q931mes_CONGESTION_CONTROL,   Q931ProcCongestionControlTE, Q931Umes_Generic, Q931Pmes_Generic);
00105         Q931DialectSetMesProc(d, Q931mes_INFORMATION,          Q931ProcInformationTE,       Q931Umes_Generic, Q931Pmes_Generic);
00106         Q931DialectSetMesProc(d, Q931mes_NOTIFY,               Q931ProcNotifyTE,            Q931Umes_Generic, Q931Pmes_Generic);
00107         Q931DialectSetMesProc(d, Q931mes_STATUS,               Q931ProcStatusTE,            Q931Umes_Generic, Q931Pmes_Generic);
00108         Q931DialectSetMesProc(d, Q931mes_STATUS_ENQUIRY,       Q931ProcStatusEnquiryTE,     Q931Umes_Generic, Q931Pmes_Generic);
00109         Q931DialectSetMesProc(d, Q931mes_SEGMENT,              Q931ProcSegmentTE,           Q931Umes_Generic, Q931Pmes_Generic);
00110 
00111         /*
00112          * Q.932
00113          */
00114         Q931DialectSetMesProc(d, Q932mes_FACILITY,             Q932ProcFacilityTE,       Q932Umes_Facility,       Q932Pmes_Facility);
00115         Q931DialectSetMesProc(d, Q932mes_HOLD,                 Q932ProcHoldTE,           Q932Umes_Hold,           Q932Pmes_Hold);
00116         Q931DialectSetMesProc(d, Q932mes_HOLD_ACKNOWLEDGE,     Q932ProcHoldAckTE,        Q932Umes_HoldAck,        Q932Pmes_HoldAck);
00117         Q931DialectSetMesProc(d, Q932mes_HOLD_REJECT,          Q932ProcHoldRejectTE,     Q932Umes_HoldReject,     Q932Pmes_HoldReject);
00118         Q931DialectSetMesProc(d, Q932mes_REGISTER,             Q932ProcRegisterTE,       Q932Umes_Register,       Q932Pmes_Register);
00119         Q931DialectSetMesProc(d, Q932mes_RETRIEVE,             Q932ProcRetrieveTE,       Q932Umes_Retrieve,       Q932Pmes_Retrieve);
00120         Q931DialectSetMesProc(d, Q932mes_RETRIEVE_ACKNOWLEDGE, Q932ProcRetrieveAckTE,    Q932Umes_RetrieveAck,    Q932Pmes_RetrieveAck);
00121         Q931DialectSetMesProc(d, Q932mes_RETRIEVE_REJECT,      Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject);
00122 
00123         /*
00124          * Unknown / Invalid (Unexpected) Message handler
00125          */
00126         Q931DialectSetUnknownMesProc(d, Q931ProcUnknownMessage);
00127         Q931DialectSetInvalidMesProc(d, Q931ProcUnexpectedMessage);
00128 
00129         /*
00130          * Q.931 IE encoder/decoder table
00131          */
00132         Q931DialectSetIEProc(d, Q931ie_SEGMENTED_MESSAGE,                Q931Pie_Segment,     Q931Uie_Segment,      Q931Die_Segment);
00133         Q931DialectSetIEProc(d, Q931ie_BEARER_CAPABILITY,                Q931Pie_BearerCap,   Q931Uie_BearerCap,    Q931Die_BearerCap);
00134         Q931DialectSetIEProc(d, Q931ie_CAUSE,                            Q931Pie_Cause,       Q931Uie_Cause,        Q931Die_Cause);
00135         Q931DialectSetIEProc(d, Q931ie_CALL_IDENTITY,                    Q931Pie_CallID,      Q931Uie_CallID,       Q931Die_CallID);
00136         Q931DialectSetIEProc(d, Q931ie_CALL_STATE,                       Q931Pie_CallState,   Q931Uie_CallState,    Q931Die_CallState);
00137         Q931DialectSetIEProc(d, Q931ie_CHANNEL_IDENTIFICATION,           Q931Pie_ChanID,      Q931Uie_ChanID,       Q931Die_ChanID);
00138         Q931DialectSetIEProc(d, Q931ie_PROGRESS_INDICATOR,               Q931Pie_ProgInd,     Q931Uie_ProgInd,      Q931Die_ProgInd);
00139         Q931DialectSetIEProc(d, Q931ie_NETWORK_SPECIFIC_FACILITIES,      Q931Pie_NetFac,      Q931Uie_NetFac,       Q931Die_Generic);
00140         Q931DialectSetIEProc(d, Q931ie_NOTIFICATION_INDICATOR,           Q931Pie_NotifInd,    Q931Uie_NotifInd,     Q931Die_Generic);
00141         Q931DialectSetIEProc(d, Q931ie_DISPLAY,                          Q931Pie_Display,     Q931Uie_Display,      Q931Die_Display);
00142         Q931DialectSetIEProc(d, Q931ie_DATETIME,                         Q931Pie_DateTime,    Q931Uie_DateTime,     Q931Die_DateTime);
00143         Q931DialectSetIEProc(d, Q931ie_KEYPAD_FACILITY,                  Q931Pie_KeypadFac,   Q931Uie_KeypadFac,    Q931Die_Generic);
00144         Q931DialectSetIEProc(d, Q931ie_SIGNAL,                           Q931Pie_Signal,      Q931Uie_Signal,       Q931Die_Signal);
00145         Q931DialectSetIEProc(d, Q931ie_TRANSIT_DELAY_SELECTION_AND_IND,  Q931Pie_TransNetSel, Q931Uie_TransNetSel,  Q931Die_Generic);
00146         Q931DialectSetIEProc(d, Q931ie_CALLING_PARTY_NUMBER,             Q931Pie_CallingNum,  Q931Uie_CallingNum,   Q931Die_CallingNum);
00147         Q931DialectSetIEProc(d, Q931ie_CALLING_PARTY_SUBADDRESS,         Q931Pie_CallingSub,  Q931Uie_CallingSub,   Q931Die_CallingSub);
00148         Q931DialectSetIEProc(d, Q931ie_CALLED_PARTY_NUMBER,              Q931Pie_CalledNum,   Q931Uie_CalledNum,    Q931Die_CalledNum);
00149         Q931DialectSetIEProc(d, Q931ie_CALLED_PARTY_SUBADDRESS,          Q931Pie_CalledSub,   Q931Uie_CalledSub,    Q931Die_CalledSub);
00150         Q931DialectSetIEProc(d, Q931ie_TRANSIT_NETWORK_SELECTION,        Q931Pie_TransNetSel, Q931Uie_TransNetSel,  Q931Die_Generic);
00151         Q931DialectSetIEProc(d, Q931ie_RESTART_INDICATOR,                Q931Pie_RestartInd,  Q931Uie_RestartInd,   Q931Die_RestartInd);
00152         Q931DialectSetIEProc(d, Q931ie_LOW_LAYER_COMPATIBILITY,          Q931Pie_LLComp,      Q931Uie_LLComp,       Q931Die_LLComp);
00153         Q931DialectSetIEProc(d, Q931ie_HIGH_LAYER_COMPATIBILITY,         Q931Pie_HLComp,      Q931Uie_HLComp,       Q931Die_HLComp);
00154         Q931DialectSetIEProc(d, Q931ie_USER_USER,                        Q931Pie_UserUser,    Q931Uie_UserUser,     Q931Die_UserUser);
00155         Q931DialectSetIEProc(d, Q931ie_SENDING_COMPLETE,                 Q931Pie_SendComplete,Q931Uie_SendComplete, Q931Die_SendComplete);
00156         Q931DialectSetIEProc(d, Q931ie_CONNECTED_NUMBER,                 Q931Pie_Generic,     Q931Uie_Generic,      Q931Die_Generic);
00157         Q931DialectSetIEProc(d, Q931ie_CONNECTED_SUBADDRESS,             Q931Pie_Generic,     Q931Uie_Generic,      Q931Die_Generic);
00158 
00159         /*
00160          * Q.932
00161          */
00162         Q931DialectSetIEProc(d, Q932ie_FACILITY,                       Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00163         Q931DialectSetIEProc(d, Q932ie_EXTENDED_FACILITY,              Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00164         Q931DialectSetIEProc(d, Q932ie_FEATURE_ACTIVATION,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00165         Q931DialectSetIEProc(d, Q932ie_FEATURE_INDICATION,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00166         Q931DialectSetIEProc(d, Q932ie_SERVICE_PROFILE_IDENTIFICATION, Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00167         Q931DialectSetIEProc(d, Q932ie_ENDPOINT_IDENTIFIER,            Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00168 
00169         /*
00170          * Q.952
00171          */
00172         Q931DialectSetIEProc(d, Q931ie_REDIRECTING_NUMBER,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00173         Q931DialectSetIEProc(d, Q931ie_REDIRECTION_NUMBER,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00174 
00175         /*
00176          * State -> Allowed message table
00177          */
00178         /* Any State */
00179         Q931DialectAddStateEntry(d, Q931_UANY, Q931mes_STATUS,         MSGF_FROM_BOTH);
00180         Q931DialectAddStateEntry(d, Q931_UANY, Q931mes_STATUS_ENQUIRY, MSGF_FROM_L2);
00181         Q931DialectAddStateEntry(d, Q931_UANY, Q931mes_RESTART,             MSGF_FROM_BOTH);
00182         Q931DialectAddStateEntry(d, Q931_UANY, Q931mes_RESTART_ACKNOWLEDGE, MSGF_FROM_BOTH);
00183 
00184         /* State 0 Idle */
00185         Q931DialectAddStateEntry(d, Q931_U0, Q931mes_SETUP,            MSGF_FROM_BOTH);
00186         Q931DialectAddStateEntry(d, Q931_U0, Q931mes_RELEASE,          MSGF_FROM_L2);
00187         Q931DialectAddStateEntry(d, Q931_U0, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00188         Q931DialectAddStateEntry(d, Q931_U0, Q931mes_RESUME,           MSGF_FROM_L4);
00189 
00190         /* State 1 Call Initiating */
00191         Q931DialectAddStateEntry(d, Q931_U1, Q931mes_DISCONNECT,        MSGF_FROM_L4);
00192         Q931DialectAddStateEntry(d, Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, MSGF_FROM_L2);
00193         Q931DialectAddStateEntry(d, Q931_U1, Q931mes_RELEASE_COMPLETE,  MSGF_FROM_L2);
00194         Q931DialectAddStateEntry(d, Q931_U1, Q931mes_CALL_PROCEEDING,   MSGF_FROM_L2);
00195         Q931DialectAddStateEntry(d, Q931_U1, Q931mes_ALERTING,          MSGF_FROM_L2);  /* ITU-T Q.931 Annex D */
00196         Q931DialectAddStateEntry(d, Q931_U1, Q931mes_CONNECT,           MSGF_FROM_L2);  /* ITU-T Q.931 Annex D */
00197 
00198         /* State 2 Overlap Sending */
00199         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_DISCONNECT,       MSGF_FROM_BOTH);
00200         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00201         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_CALL_PROCEEDING,  MSGF_FROM_L2);
00202         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_ALERTING,         MSGF_FROM_L2);
00203         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_PROGRESS,         MSGF_FROM_L2);
00204         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_CONNECT,          MSGF_FROM_L2);
00205         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00206         Q931DialectAddStateEntry(d, Q931_U2, Q931mes_RELEASE,          MSGF_FROM_BOTH);
00207 
00208         /* State 3 Outgoing Call Proceeding */
00209         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_DISCONNECT,       MSGF_FROM_BOTH);
00210         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_PROGRESS,         MSGF_FROM_L2);
00211         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_ALERTING,         MSGF_FROM_L2);
00212         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_CONNECT,          MSGF_FROM_L2);
00213         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00214         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_RELEASE,          MSGF_FROM_BOTH);
00215         Q931DialectAddStateEntry(d, Q931_U3, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00216 
00217         /* State 4 Call Delivered */
00218         Q931DialectAddStateEntry(d, Q931_U4, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00219         Q931DialectAddStateEntry(d, Q931_U4, Q931mes_RELEASE,          MSGF_FROM_L2);
00220         Q931DialectAddStateEntry(d, Q931_U4, Q931mes_DISCONNECT,       MSGF_FROM_BOTH);
00221         Q931DialectAddStateEntry(d, Q931_U4, Q931mes_CONNECT,          MSGF_FROM_L2);
00222         Q931DialectAddStateEntry(d, Q931_U4, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00223 
00224         /* State 6 Call Precent */
00225         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_INFORMATION,      MSGF_FROM_L4);
00226         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_ALERTING,         MSGF_FROM_L4);
00227         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_CALL_PROCEEDING,  MSGF_FROM_L4);
00228         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_CONNECT,          MSGF_FROM_L4);
00229         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_RELEASE_COMPLETE, MSGF_FROM_BOTH);
00230         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_RELEASE,          MSGF_FROM_L2);
00231         Q931DialectAddStateEntry(d, Q931_U6, Q931mes_DISCONNECT,       MSGF_FROM_L2);
00232 
00233         /* State 7 Call Received */
00234         Q931DialectAddStateEntry(d, Q931_U7, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00235         Q931DialectAddStateEntry(d, Q931_U7, Q931mes_RELEASE,          MSGF_FROM_L2);
00236         Q931DialectAddStateEntry(d, Q931_U7, Q931mes_DISCONNECT,       MSGF_FROM_BOTH);
00237         Q931DialectAddStateEntry(d, Q931_U7, Q931mes_CONNECT,          MSGF_FROM_L4);
00238         Q931DialectAddStateEntry(d, Q931_U7, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00239 
00240         /* State 8 Connect request */
00241         Q931DialectAddStateEntry(d, Q931_U8, Q931mes_RELEASE_COMPLETE,    MSGF_FROM_L2);
00242         Q931DialectAddStateEntry(d, Q931_U8, Q931mes_RELEASE,             MSGF_FROM_L2);
00243         Q931DialectAddStateEntry(d, Q931_U8, Q931mes_DISCONNECT,          MSGF_FROM_BOTH);
00244         Q931DialectAddStateEntry(d, Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, MSGF_FROM_L2);
00245         Q931DialectAddStateEntry(d, Q931_U8, Q931mes_INFORMATION,         MSGF_FROM_BOTH);
00246 
00247         /* State 9 Incoming Call Proceeding */
00248         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_RELEASE_COMPLETE,  MSGF_FROM_L2);
00249         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_RELEASE,           MSGF_FROM_L2);
00250         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_DISCONNECT,        MSGF_FROM_BOTH);
00251         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_CONNECT,           MSGF_FROM_L4);
00252         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_ALERTING,          MSGF_FROM_L4);
00253         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_PROGRESS,          MSGF_FROM_L4);
00254         Q931DialectAddStateEntry(d, Q931_U9, Q931mes_INFORMATION,       MSGF_FROM_BOTH);
00255 
00256         /* State 10 Active */
00257         Q931DialectAddStateEntry(d, Q931_U10, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00258         Q931DialectAddStateEntry(d, Q931_U10, Q931mes_RELEASE,          MSGF_FROM_L2);
00259         Q931DialectAddStateEntry(d, Q931_U10, Q931mes_DISCONNECT,       MSGF_FROM_BOTH);
00260         Q931DialectAddStateEntry(d, Q931_U10, Q931mes_SUSPEND,          MSGF_FROM_L4);
00261         Q931DialectAddStateEntry(d, Q931_U10, Q931mes_NOTIFY,           MSGF_FROM_BOTH);
00262         Q931DialectAddStateEntry(d, Q931_U10, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00263         Q931DialectAddStateEntry(d, Q931_U10, Q932mes_FACILITY,         MSGF_FROM_BOTH);
00264 
00265         /* State 11 Disconnect Request */
00266         Q931DialectAddStateEntry(d, Q931_U11, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00267         Q931DialectAddStateEntry(d, Q931_U11, Q931mes_RELEASE,          MSGF_FROM_L2);
00268         Q931DialectAddStateEntry(d, Q931_U11, Q931mes_DISCONNECT,       MSGF_FROM_L2);
00269         Q931DialectAddStateEntry(d, Q931_U11, Q931mes_NOTIFY,           MSGF_FROM_L2);
00270         Q931DialectAddStateEntry(d, Q931_U11, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00271 
00272         /* State 12 Disconnect Ind */
00273         Q931DialectAddStateEntry(d, Q931_U12, Q931mes_RELEASE_COMPLETE, MSGF_FROM_BOTH);
00274         Q931DialectAddStateEntry(d, Q931_U12, Q931mes_RELEASE,          MSGF_FROM_BOTH);
00275         Q931DialectAddStateEntry(d, Q931_U12, Q931mes_INFORMATION,      MSGF_FROM_BOTH);
00276 
00277         /* State 15 Suspend Request */
00278         Q931DialectAddStateEntry(d, Q931_U15, Q931mes_RELEASE_COMPLETE,    MSGF_FROM_L2);
00279         Q931DialectAddStateEntry(d, Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, MSGF_FROM_L2);
00280         Q931DialectAddStateEntry(d, Q931_U15, Q931mes_SUSPEND_REJECT,      MSGF_FROM_L2);
00281         Q931DialectAddStateEntry(d, Q931_U15, Q931mes_DISCONNECT,          MSGF_FROM_L2);
00282         Q931DialectAddStateEntry(d, Q931_U15, Q931mes_RELEASE,             MSGF_FROM_L2);
00283         Q931DialectAddStateEntry(d, Q931_U15, Q931mes_INFORMATION,         MSGF_FROM_BOTH);
00284 
00285         /* State 17 Resume Request */
00286         Q931DialectAddStateEntry(d, Q931_U17, Q931mes_RELEASE_COMPLETE,   MSGF_FROM_L2);
00287         Q931DialectAddStateEntry(d, Q931_U17, Q931mes_RESUME_ACKNOWLEDGE, MSGF_FROM_L2);
00288         Q931DialectAddStateEntry(d, Q931_U17, Q931mes_RESUME_REJECT,      MSGF_FROM_L2);
00289 
00290         /* State 19 Release Request */
00291         Q931DialectAddStateEntry(d, Q931_U19, Q931mes_RELEASE_COMPLETE, MSGF_FROM_L2);
00292         Q931DialectAddStateEntry(d, Q931_U19, Q931mes_RELEASE,          MSGF_FROM_L2);
00293 
00294         /* State 25 Overlap Receiving */
00295         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_DISCONNECT,        MSGF_FROM_BOTH);
00296         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_SETUP_ACKNOWLEDGE, MSGF_FROM_L4);
00297         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_RELEASE_COMPLETE,  MSGF_FROM_BOTH);
00298         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_RELEASE,           MSGF_FROM_L2);
00299         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_CALL_PROCEEDING,   MSGF_FROM_L4);
00300         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_ALERTING,          MSGF_FROM_L4);
00301         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_CONNECT,           MSGF_FROM_L4);
00302         Q931DialectAddStateEntry(d, Q931_U25, Q931mes_INFORMATION,       MSGF_FROM_L2);
00303 
00304         /*
00305          * Timer default values & callbacks
00306          */
00307         Q931DialectSetTimerProcAll(d, Q931TimeoutDummy);
00308 
00309         /* Per-timer timeout callbacks, per-mode for now, until i know if they can be shared (and which) */
00310 /*
00311         Q931DialectSetTimerProc(d, Q931_TIMER_T301, Q931ProcTimeoutT301TE);
00312         Q931DialectSetTimerProc(d, Q931_TIMER_T302, Q931ProcTimeoutT302TE);
00313 */
00314         Q931DialectSetTimerProc(d, Q931_TIMER_T303, Q931ProcTimeoutT303TE);
00315         Q931DialectSetTimerProc(d, Q931_TIMER_T304, Q931ProcTimeoutT304TE);
00316         Q931DialectSetTimerProc(d, Q931_TIMER_T305, Q931ProcTimeoutT305TE);
00317         Q931DialectSetTimerProc(d, Q931_TIMER_T308, Q931ProcTimeoutT308TE);
00318 /*      Q931DialectSetTimerProc(d, Q931_TIMER_T309, Q931ProcTimeoutT309TE); */
00319         Q931DialectSetTimerProc(d, Q931_TIMER_T310, Q931ProcTimeoutT310TE);
00320 /*      Q931DialectSetTimerProc(d, Q931_TIMER_T311, Q931ProcTimeoutT311TE); */
00321         Q931DialectSetTimerProc(d, Q931_TIMER_T313, Q931ProcTimeoutT313TE);
00322 /*
00323         Q931DialectSetTimerProc(d, Q931_TIMER_T314, Q931ProcTimeoutT314TE);
00324         Q931DialectSetTimerProc(d, Q931_TIMER_T316, Q931ProcTimeoutT316TE);
00325         Q931DialectSetTimerProc(d, Q931_TIMER_T317, Q931ProcTimeoutT317TE);
00326 */
00327         Q931DialectSetTimerProc(d, Q931_TIMER_T318, Q931ProcTimeoutT318TE);
00328 /*
00329         Q931DialectSetTimerProc(d, Q931_TIMER_T319, Q931ProcTimeoutT319TE);
00330         Q931DialectSetTimerProc(d, Q931_TIMER_T321, Q931ProcTimeoutT321TE);
00331         Q931DialectSetTimerProc(d, Q931_TIMER_T322, Q931ProcTimeoutT322TE);
00332 */
00333 
00334         Q931DialectSetTimeout(d, Q931_TIMER_T301, 180000);      /* T301: 180s */
00335         Q931DialectSetTimeout(d, Q931_TIMER_T302,  15000);      /* T302:  15s */
00336         Q931DialectSetTimeout(d, Q931_TIMER_T303,   4000);      /* T303:   4s */
00337         Q931DialectSetTimeout(d, Q931_TIMER_T304,  30000);      /* T304:  30s */
00338         Q931DialectSetTimeout(d, Q931_TIMER_T305,  30000);      /* T305:  30s */
00339         Q931DialectSetTimeout(d, Q931_TIMER_T308,   4000);      /* T308:   4s */
00340         Q931DialectSetTimeout(d, Q931_TIMER_T309,  60000);      /* T309:  60s */
00341         Q931DialectSetTimeout(d, Q931_TIMER_T310,  60000);      /* T310:  60s */
00342         Q931DialectSetTimeout(d, Q931_TIMER_T313,   4000);      /* T313:   4s */
00343         Q931DialectSetTimeout(d, Q931_TIMER_T314,   4000);      /* T314:   4s */
00344         Q931DialectSetTimeout(d, Q931_TIMER_T316, 120000);      /* T316: 120s */
00345         Q931DialectSetTimeout(d, Q931_TIMER_T317,  90000);      /* T317:  90s */
00346         Q931DialectSetTimeout(d, Q931_TIMER_T318,   4000);      /* T318:   4s */
00347         Q931DialectSetTimeout(d, Q931_TIMER_T319,   4000);      /* T319:   4s */
00348         Q931DialectSetTimeout(d, Q931_TIMER_T321,  30000);      /* T321:  30s */
00349         Q931DialectSetTimeout(d, Q931_TIMER_T322,   4000);      /* T322:   4s */
00350 
00351         /*
00352          * Q.931 message <-> ie table
00353          */
00354         Q931DialectSetMesIEMap(d, Q931MessageIEs);
00355 }
00356 
00357 
00372 L3INT Q931ProcAlertingTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00373 {
00374         L3INT ret = Q931E_NO_ERROR;
00375 #if 0
00376         /* Find the call using CRV (TODO: move one level up,
00377          * change function signature(s) to use Q931_Call * instead of
00378          * Q931_TrunkInfo_t *)
00379          */
00380         call = Q931GetCallByCRV(trunk, msg->CRV);
00381         if (!call)
00382                 return Q931E_INVALID_CRV;
00383 
00384         /* check if message is valid in this state (TODO: move one level up) */
00385         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00386                 return Q931E_UNEXPECTED_MESSAGE;
00387 #endif
00388         switch(from) {
00389         case Q931_MSG_FROM_L4:
00390                 switch(Q931CallGetState(call)) {
00391                 case Q931_U6:
00392                 case Q931_U9:
00393                         /* Send ALERTING */
00394                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00395 
00396                         /* => U7 Call received */
00397                         Q931CallSetState(call, Q931_U7);
00398                         break;
00399                 default:
00400                         break;
00401                 }
00402                 break;
00403         case Q931_MSG_FROM_L2:
00404                 switch(Q931CallGetState(call)) {
00405                 case Q931_U1:
00406                         /* Stop T303 */
00407                         Q931CallStopTimer(call, Q931_TIMER_T303);
00408 
00409                         /* TODO: Invoke new event CB: Alerting indication */
00410                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00411 
00412                         {
00413                                 /* Enqueue event */
00414                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00415 
00416                                 event->id   = Q931_EVENT_ALERTING_INDICATION;
00417                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00418                                 event->data.message.type = msg->MesType;
00419                                 event->data.message.data = msg;
00420 
00421                                 Q931CallQueueEvent(call, event);
00422                         }
00423 
00424                         /* => U4: Call delivered */
00425                         Q931CallSetState(call, Q931_U4);
00426                         break;
00427 
00428                 case Q931_U2:
00429                         /* Stop T304 */
00430                         Q931CallStopTimer(call, Q931_TIMER_T304);
00431 
00432                         /* TODO: Invoke new event CB: Alerting indication */
00433                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00434 
00435                         {
00436                                 /* Enqueue event */
00437                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00438 
00439                                 event->id   = Q931_EVENT_ALERTING_INDICATION;
00440                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00441                                 event->data.message.type = msg->MesType;
00442                                 event->data.message.data = msg;
00443 
00444                                 Q931CallQueueEvent(call, event);
00445                         }
00446 
00447                         /* => U4: Call delivered */
00448                         Q931CallSetState(call, Q931_U4);
00449                         break;
00450 
00451                 case Q931_U3:
00452                         /* Stop T310, Start T301 */
00453                         Q931CallStartTimer(call, Q931_TIMER_T301);
00454 
00455                         /* TODO: Invoke new event CB: Alerting indication */
00456                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00457 
00458                         {
00459                                 /* Enqueue event */
00460                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00461 
00462                                 event->id   = Q931_EVENT_ALERTING_INDICATION;
00463                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00464                                 event->data.message.type = msg->MesType;
00465                                 event->data.message.data = msg;
00466 
00467                                 Q931CallQueueEvent(call, event);
00468                         }
00469 
00470                         /* => U4: Call delivered */
00471                         Q931CallSetState(call, Q931_U4);
00472                         break;
00473 
00474                 default:
00475                         break;
00476                 }
00477                 break;
00478         default:
00479                 ret = Q931E_INTERNAL;
00480         }
00481         return ret;
00482 }
00483 
00484 
00494 L3INT Q931ProcCallProceedingTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00495 {
00496         L3INT ret = Q931E_NO_ERROR;
00497 #if 0
00498         /* Find the call using CRV (TODO: move one level up,
00499          * change function signature(s) to use Q931_Call * instead of
00500          * Q931_TrunkInfo_t *)
00501          */
00502         call = Q931GetCallByCRV(trunk, msg->CRV);
00503         if (!call)
00504                 return Q931E_INVALID_CRV;
00505 
00506         /* check if message is valid in this state (TODO: move one level up) */
00507         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00508                 return Q931E_UNEXPECTED_MESSAGE;
00509 #endif
00510         switch(from) {
00511         case Q931_MSG_FROM_L4:
00512                 switch(Q931CallGetState(call)) {
00513                 case Q931_U6:
00514                         /* Send CALL PROCEEDING */
00515                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00516 
00517                         /* => U9 Incoming call proceeding */
00518                         Q931CallSetState(call, Q931_U9);
00519                         break;
00520                 default:
00521                         break;
00522                 }
00523                 break;
00524         case Q931_MSG_FROM_L2:
00525                 switch(Q931CallGetState(call)) {
00526                 case Q931_U1:
00527                 case Q931_U2:
00528                         /* Stop T303/T304, Start T310 */
00529                         Q931CallStartTimer(call, Q931_TIMER_T310);
00530 
00531                         /* TODO: Invoke new event CB: Proceeding indication */
00532                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00533 
00534                         {
00535                                 /* Enqueue event */
00536                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00537 
00538                                 event->id   = Q931_EVENT_PROCEEDING_INDICATION;
00539                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00540                                 event->data.message.type = msg->MesType;
00541                                 event->data.message.data = msg;
00542 
00543                                 Q931CallQueueEvent(call, event);
00544                         }
00545 
00546                         /* => U3 Outgoing call proceeding */
00547                         Q931CallSetState(call, Q931_U3);
00548                         break;
00549                 default:
00550                         break;
00551                 }
00552                 break;
00553         default:
00554                 ret = Q931E_INTERNAL;
00555         }
00556         return ret;
00557 }
00558 
00559 
00569 L3INT Q931ProcConnectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00570 {
00571         L3INT ret = Q931E_NO_ERROR;
00572 #if 0
00573         /* Find the call using CRV */
00574         call = Q931GetCallByCRV(trunk, msg->CRV);
00575         if (!call)
00576                 return Q931E_INVALID_CRV;
00577 
00578         /* check if message is valid in this state */
00579         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00580                 return Q931E_UNEXPECTED_MESSAGE;
00581 #endif
00582         switch(from) {
00583         case Q931_MSG_FROM_L4:
00584                 switch(Q931CallGetState(call)) {
00585                 case Q931_U6:   /* Setup response */
00586                 case Q931_U7:
00587                 case Q931_U9:
00588                         /* Send CONNECT */
00589                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00590 
00591                         /* Start T313 */
00592                         Q931CallStartTimer(call, Q931_TIMER_T313);
00593 
00594                         /* => U8 Connect request */
00595                         Q931CallSetState(call, Q931_U8);
00596                         break;
00597                 default:
00598                         break;
00599                 }
00600                 break;
00601         case Q931_MSG_FROM_L2:
00602                 switch(Q931CallGetState(call)) {
00603                 case Q931_U1:
00604                         /* Stop T303 */
00605                         Q931CallStopTimer(call, Q931_TIMER_T303);
00606 
00607                 case Q931_U2:
00608                         /* Stop T304 */
00609                         Q931CallStopTimer(call, Q931_TIMER_T304);
00610 
00611                 case Q931_U3:
00612                         /* Stop T310 */
00613                         Q931CallStopTimer(call, Q931_TIMER_T310);
00614 
00615                 case Q931_U4:
00616                         /* Stop T301 (something missing in the spec huh?) */
00617                         Q931CallStopTimer(call, Q931_TIMER_T301);
00618 
00619                         /* TODO: Send Setup confirm */
00620                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00621 
00622                         {
00623                                 /* Enqueue event */
00624                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00625 
00626                                 event->id   = Q931_EVENT_SETUP_CONFIRM;
00627                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00628                                 event->data.message.type = msg->MesType;
00629                                 event->data.message.data = msg;
00630 
00631                                 Q931CallQueueEvent(call, event);
00632                         }
00633 
00634                         if (Q931TrunkIsSetFlag(trunk, Q931_TFLAG_AUTO_CONNECT_ACK)) {
00635                                 Q931AckConnect(call);
00636                         }
00637 
00638                         /* => U10 Active */
00639                         Q931CallSetState(call, Q931_U10);
00640                         break;
00641 
00642                 default:
00643                         break;
00644                 }
00645                 break;
00646         default:
00647                 ret = Q931E_INTERNAL;
00648         }
00649         return ret;
00650 }
00651 
00652 
00662 L3INT Q931ProcConnectAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00663 {
00664         L3INT ret = Q931E_NO_ERROR;
00665 #if 0
00666         /* Find the call using CRV */
00667         call = Q931GetCallByCRV(trunk, msg->CRV);
00668         if (!call)
00669                 return Q931E_INVALID_CRV;
00670 
00671         /* check if message is valid in this state */
00672         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00673                 return Q931E_UNEXPECTED_MESSAGE;
00674 #endif
00675         switch(from) {
00676 #if 0
00677         case Q931_MSG_FROM_L4:
00678                 /* TODO Add proc here */
00679                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
00680                 break;
00681 #endif
00682         case Q931_MSG_FROM_L2:
00683                 switch(Q931CallGetState(call)) {
00684                 case Q931_U8:
00685                         /* Stop T313 */
00686                         Q931CallStopTimer(call, Q931_TIMER_T313);
00687 
00688                         /* TODO: Setup complete indication */
00689                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00690 
00691                         {
00692                                 /* Enqueue event */
00693                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00694 
00695                                 event->id   = Q931_EVENT_SETUP_COMPLETE_INDICATION;
00696                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00697                                 event->data.message.type = msg->MesType;
00698                                 event->data.message.data = msg;
00699 
00700                                 Q931CallQueueEvent(call, event);
00701                         }
00702 
00703                         /* => U10 Active */
00704                         Q931CallSetState(call, Q931_U10);
00705                         break;
00706                 default:
00707                         break;
00708                 }
00709                 break;
00710         default:
00711                 ret = Q931E_INTERNAL;
00712         }
00713         return ret;
00714 }
00715 
00716 
00726 L3INT Q931ProcProgressTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00727 {
00728         L3INT ret = Q931E_NO_ERROR;
00729 #if 0
00730         /* Find the call using CRV */
00731         call = Q931GetCallByCRV(trunk, msg->CRV);
00732         if (!call)
00733                 return Q931E_INVALID_CRV;
00734 
00735         /* check if message is valid in this state */
00736         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00737                 return Q931E_UNEXPECTED_MESSAGE;
00738 #endif
00739         switch(from) {
00740         case Q931_MSG_FROM_L4:
00741                 switch(Q931CallGetState(call)) {
00742                 case Q931_U9:
00743                         /* Send PROGRESS */
00744                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00745 
00746                         /* == U9 Incoming call proceeding */
00747                         break;
00748                 default:
00749                         break;
00750                 }
00751                 break;
00752         case Q931_MSG_FROM_L2:
00753                 switch(Q931CallGetState(call)) {
00754                 case Q931_U2:
00755                         /* Stop T304 (?) */
00756                         Q931CallStopTimer(call, Q931_TIMER_T304);
00757 
00758                         /* Send proceeding indication */
00759                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00760 
00761                         {
00762                                 /* Enqueue event */
00763                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00764 
00765                                 event->id   = Q931_EVENT_PROCEEDING_INDICATION;
00766                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00767                                 event->data.message.type = msg->MesType;
00768                                 event->data.message.data = msg;
00769 
00770                                 Q931CallQueueEvent(call, event);
00771                         }
00772 
00773                         /* == U2 Overlap sending */
00774                         break;
00775 
00776                 case Q931_U3:
00777                         /* Stop T310 */
00778                         Q931CallStopTimer(call, Q931_TIMER_T310);
00779 
00780                         /* Send proceeding indication */
00781                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00782 
00783                         {
00784                                 /* Enqueue event */
00785                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00786 
00787                                 event->id   = Q931_EVENT_PROCEEDING_INDICATION;
00788                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00789                                 event->data.message.type = msg->MesType;
00790                                 event->data.message.data = msg;
00791 
00792                                 Q931CallQueueEvent(call, event);
00793                         }
00794 
00795                         /* == U3 Outgoing call proceeding */
00796                         break;
00797                 default:
00798                         break;
00799                 }
00800                 break;
00801         default:
00802                 ret = Q931E_INTERNAL;
00803         }
00804         return ret;
00805 }
00806 
00807 
00817 L3INT Q931ProcSetupTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00818 {
00819         L3INT ret = Q931E_NO_ERROR;
00820 #ifdef __UNUSED__
00821         /* NOTE: this is handled by upper layers */
00822 
00823         /* Find the call using CRV */
00824         if (msg->CRV) {
00825                 call = Q931GetCallByCRV(trunk, msg->CRV);
00826                 if (call && Q931CallGetState(call) != Q931_U0) {
00827                         /* Reject SETUP on existing calls */
00828                         Q931Disconnect(trunk, from, msg->CRV, 81);
00829                         return Q931E_UNEXPECTED_MESSAGE;
00830                 }
00831         }
00832 
00833         if (call) {
00834                 /* check if message is valid in this state */
00835                 if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00836                         return Q931E_UNEXPECTED_MESSAGE;
00837         }
00838 #endif
00839         switch(from) {
00840         case Q931_MSG_FROM_L4:          /* outgoing call */
00841                 if (!call) {
00842                         call = Q931CallNew(trunk);
00843                         if (!call) {
00844                                 return Q931E_INTERNAL;
00845                         }
00846                         msg->CRV = Q931CallGetCRV(call);
00847                 }
00848 
00849                 Q931Log(trunk, Q931_LOG_INFO, "Creating new outbound call with CRV: %d\n", msg->CRV);
00850 
00851                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
00852                 if (ret < Q931E_NO_ERROR) {
00853                         Q931Log(trunk, Q931_LOG_INFO, "ProcSETUP Q931Tx32 retval: %d\n", ret);
00854                         return ret;
00855                 }
00856 
00857                 Q931CallStartTimer(call, Q931_TIMER_T303);
00858 
00859                 Q931CallSetState(call, Q931_U1);
00860                 break;
00861 
00862         case Q931_MSG_FROM_L2:          /* incoming call */
00863                 if (!call) {
00864                         call = Q931CallNewIncoming(trunk, msg->CRV);
00865                         if (!call) {
00866                                 /* Not possible to allocate CRV entry, so must reject call */
00867                                 Q931Disconnect(trunk, from, msg->CRV, 42);
00868                                 return Q931E_INTERNAL;
00869                         }
00870                 }
00871 
00872                 /* Send setup indication to user */
00873                 {
00874                         /* Enqueue event */
00875                         struct Q931_CallEvent *event = Q931CallNewEvent(call);
00876 
00877                         event->id   = Q931_EVENT_SETUP_INDICATION;
00878                         event->type = Q931_EVENT_TYPE_MESSAGE;
00879                         event->data.message.type = msg->MesType;
00880                         event->data.message.data = msg;
00881 
00882                         Q931CallQueueEvent(call, event);
00883                 }
00884 
00885                 /* Set state U6 */
00886                 Q931CallSetState(call, Q931_U6);
00887 
00888                 /* old way */
00889                 ret = Q931Tx34(trunk, call, msg, msg->Size);
00890                 if (ret >= Q931E_NO_ERROR) {
00891                         if (Q931TrunkIsSetFlag(trunk, Q931_TFLAG_AUTO_SETUP_ACK)) {
00892                                 Q931AckSetup(trunk, msg);
00893                         }
00894                         return ret;
00895                 } else {
00896                         /* Must be full queue, meaning we can't process the call */
00897                         /* so we must disconnect */
00898                         Q931Disconnect(trunk, from, msg->CRV, 81);
00899                         return ret;
00900                 }
00901                 break;
00902 
00903         default:
00904                 ret = Q931E_INTERNAL;
00905         }
00906         return ret;
00907 }
00908 
00909 
00919 L3INT Q931ProcSetupAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00920 {
00921         L3INT ret = Q931E_NO_ERROR;
00922 #if 0
00923         /* Find the call using CRV */
00924         call = Q931GetCallByCRV(trunk, msg->CRV);
00925         if (!call)
00926                 return Q931E_INVALID_CRV;
00927 
00928         /* check if message is valid in this state */
00929         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
00930                 return Q931E_UNEXPECTED_MESSAGE;
00931 #endif
00932         switch(from) {
00933         case Q931_MSG_FROM_L4:
00934                 switch(Q931CallGetState(call)) {
00935                 case Q931_U6:   /* More info request */
00936                         /* Send SETUP ACK */
00937                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00938 
00939                         /* Start T302 */
00940                         Q931CallStartTimer(call, Q931_TIMER_T302);
00941 
00942                         /* => U25 Overlap receiving */
00943                         Q931CallSetState(call, Q931_U25);
00944                         break;
00945                 default:
00946                         break;
00947                 }
00948                 break;
00949         case Q931_MSG_FROM_L2:
00950                 switch(Q931CallGetState(call)) {
00951                 case Q931_U1:
00952                         /* Stop T303 */
00953                         Q931CallStopTimer(call, Q931_TIMER_T303);
00954 
00955                         /* TODO: More information indication */
00956                         {
00957                                 /* Enqueue event */
00958                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
00959 
00960                                 event->id   = Q931_EVENT_MORE_INFO_INDICATION;
00961                                 event->type = Q931_EVENT_TYPE_MESSAGE;
00962                                 event->data.message.type = msg->MesType;
00963                                 event->data.message.data = msg;
00964 
00965                                 Q931CallQueueEvent(call, event);
00966                         }
00967 
00968                         /* Stop T303, Start T304 */
00969                         Q931CallStartTimer(call, Q931_TIMER_T304);
00970 
00971                         /* => U2 Overlap sending */
00972                         Q931CallSetState(call, Q931_U2);
00973                         break;
00974                 default:
00975                         break;
00976                 }
00977                 break;
00978         default:
00979                 ret = Q931E_INTERNAL;
00980         }
00981         return ret;
00982 }
00983 
00984 
00994 L3INT Q931ProcResumeTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00995 {
00996         L3INT ret = Q931E_NO_ERROR;
00997 
00998         switch(from) {
00999         case Q931_MSG_FROM_L4:
01000                 /* Find the call using CRV */
01001                 call = Q931GetCallByCRV(trunk, msg->CRV);
01002                 if (!call) {
01003                         call = Q931CallNew(trunk);
01004                         if (!call) {
01005                                 return Q931E_INTERNAL;
01006                         }
01007 
01008                         /* Send RESUME to network */
01009                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01010                         if (ret != Q931E_NO_ERROR)
01011                                 return ret;
01012 
01013                         /* Start timer T318 */
01014                         Q931CallStartTimer(call, Q931_TIMER_T318);
01015 
01016                         /* set state U17 */
01017                         Q931CallSetState(call, Q931_U17);
01018                 } else {
01019                         return Q931E_ILLEGAL_MESSAGE;
01020                 }
01021                 break;
01022 
01023         default:
01024                 ret = Q931E_ILLEGAL_MESSAGE;
01025         }
01026         return ret;
01027 }
01028 
01029 
01039 L3INT Q931ProcResumeAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01040 {
01041         L3INT ret = Q931E_NO_ERROR;
01042 #if 0
01043         /* Find the call using CRV */
01044         call = Q931GetCallByCRV(trunk, msg->CRV);
01045         if (!call)
01046                 return Q931E_INVALID_CRV;
01047 
01048         /* check if message is valid in this state */
01049         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01050                 return Q931E_UNEXPECTED_MESSAGE;
01051 #endif
01052         switch(from) {
01053         case Q931_MSG_FROM_L4:
01054                 /* TODO Add proc here */
01055                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01056                 break;
01057         case Q931_MSG_FROM_L2:
01058                 /* Stop T318 */
01059                 Q931CallStopTimer(call, Q931_TIMER_T318);
01060 
01061                 /* => State U10 (Active) */
01062                 Q931CallSetState(call, Q931_U10);
01063 
01064                 /* TODO: Send Resume confirm */
01065                 {
01066                         /* Enqueue event */
01067                         struct Q931_CallEvent *event = Q931CallNewEvent(call);
01068 
01069                         event->id   = Q931_EVENT_RESUME_CONFIRM;
01070                         event->type = Q931_EVENT_TYPE_MESSAGE;
01071                         event->data.message.type = msg->MesType;
01072                         event->data.message.data = msg;
01073 
01074                         Q931CallQueueEvent(call, event);
01075                 }
01076 
01077                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01078                 break;
01079         default:
01080                 ret = Q931E_ILLEGAL_MESSAGE;
01081         }
01082         return ret;
01083 }
01084 
01085 
01095 L3INT Q931ProcResumeRejectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01096 {
01097         L3INT ret = Q931E_NO_ERROR;
01098 #if 0
01099         /* Find the call using CRV */
01100         call = Q931GetCallByCRV(trunk, msg->CRV);
01101         if (!call)
01102                 return Q931E_INVALID_CRV;
01103 
01104         /* check if message is valid in this state */
01105         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01106                 return Q931E_UNEXPECTED_MESSAGE;
01107 #endif
01108         switch(from) {
01109         case Q931_MSG_FROM_L4:
01110                 /* TODO Add proc here */
01111                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01112                 break;
01113         case Q931_MSG_FROM_L2:
01114                 /* Stop T318 */
01115                 Q931CallStopTimer(call, Q931_TIMER_T318);
01116 
01117                 /* TODO: send resume confirm error */
01118                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01119 
01120                 {
01121                         /* Enqueue event */
01122                         struct Q931_CallEvent *event = Q931CallNewEvent(call);
01123 
01124                         event->id    = Q931_EVENT_RESUME_CONFIRM;
01125                         event->type  = Q931_EVENT_TYPE_MESSAGE;
01126                         event->error = 1;
01127                         event->data.message.type = msg->MesType;
01128                         event->data.message.data = msg;
01129 
01130                         Q931CallQueueEvent(call, event);
01131                 }
01132 
01133                 /* TODO: release CRV */
01134                 Q931CallSetState(call, Q931_U0);
01135                 Q931CallRelease(call);
01136                 break;
01137         default:
01138                 ret = Q931E_ILLEGAL_MESSAGE;
01139         }
01140         return ret;
01141 }
01142 
01143 
01153 L3INT Q931ProcSuspendTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01154 {
01155         L3INT ret = Q931E_NO_ERROR;
01156 #if 0
01157         /* Find the call using CRV */
01158         call = Q931GetCallByCRV(trunk, msg->CRV);
01159         if (!call)
01160                 return Q931E_INVALID_CRV;
01161 
01162         /* check if message is valid in this state */
01163         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01164                 return Q931E_UNEXPECTED_MESSAGE;
01165 #endif
01166         switch(from) {
01167         case Q931_MSG_FROM_L4:
01168                 /* Start T319 */
01169                 Q931CallStartTimer(call, Q931_TIMER_T319);
01170 
01171                 /* Send message */
01172                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01173 
01174                 /* => State U15 (Suspend Request) */
01175                 Q931CallSetState(call, Q931_U15);
01176                 break;
01177 #if 0
01178         case Q931_MSG_FROM_L2:
01179                 /* TODO Add proc here */
01180                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01181                 break;
01182 #endif
01183         default:
01184                 ret = Q931E_ILLEGAL_MESSAGE;
01185         }
01186         return ret;
01187 }
01188 
01189 
01199 L3INT Q931ProcSuspendAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01200 {
01201         L3INT ret = Q931E_NO_ERROR;
01202 #if 0
01203         /* Find the call using CRV */
01204         call = Q931GetCallByCRV(trunk, msg->CRV);
01205         if (!call)
01206                 return Q931E_INVALID_CRV;
01207 
01208         /* check if message is valid in this state */
01209         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01210                 return Q931E_UNEXPECTED_MESSAGE;
01211 #endif
01212         switch(from) {
01213 #if 0
01214         case Q931_MSG_FROM_L4:
01215                 /* TODO Add proc here */
01216                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01217                 break;
01218 #endif
01219         case Q931_MSG_FROM_L2:
01220                 /* Stop T319 */
01221                 Q931CallStopTimer(call, Q931_TIMER_T319);
01222 
01223                 /* TODO: send Suspend confirm */
01224                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01225 
01226                 {
01227                         /* Enqueue event */
01228                         struct Q931_CallEvent *event = Q931CallNewEvent(call);
01229 
01230                         event->id   = Q931_EVENT_SUSPEND_CONFIRM;
01231                         event->type = Q931_EVENT_TYPE_MESSAGE;
01232                         event->data.message.type = msg->MesType;
01233                         event->data.message.data = msg;
01234 
01235                         Q931CallQueueEvent(call, event);
01236                 }
01237 
01238                 /* Release CRV */
01239                 Q931CallSetState(call, Q931_U0);
01240                 Q931CallRelease(call);
01241                 break;
01242         default:
01243                 ret = Q931E_ILLEGAL_MESSAGE;
01244         }
01245         return ret;
01246 }
01247 
01248 
01258 L3INT Q931ProcSuspendRejectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01259 {
01260         L3INT ret = Q931E_NO_ERROR;
01261 #if 0
01262         /* Find the call using CRV */
01263         call = Q931GetCallByCRV(trunk, msg->CRV);
01264         if (!call)
01265                 return Q931E_INVALID_CRV;
01266 
01267         /* check if message is valid in this state */
01268         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01269                 return Q931E_UNEXPECTED_MESSAGE;
01270 #endif
01271         switch(from) {
01272 #if 0
01273         case Q931_MSG_FROM_L4:
01274                 /* TODO Add proc here */
01275                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01276                 break;
01277 #endif
01278         case Q931_MSG_FROM_L2:
01279                 /* Stop T319 */
01280                 Q931CallStopTimer(call, Q931_TIMER_T319);
01281 
01282                 /* TODO: Send Suspend confirm error */
01283                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01284 
01285                 {
01286                         /* Enqueue event */
01287                         struct Q931_CallEvent *event = Q931CallNewEvent(call);
01288 
01289                         event->id    = Q931_EVENT_SUSPEND_CONFIRM;
01290                         event->type  = Q931_EVENT_TYPE_MESSAGE;
01291                         event->error = 1;
01292                         event->data.message.type = msg->MesType;
01293                         event->data.message.data = msg;
01294 
01295                         Q931CallQueueEvent(call, event);
01296                 }
01297 
01298                 /* => State U10 (Active) */
01299                 Q931CallSetState(call, Q931_U10);
01300                 break;
01301         default:
01302                 ret = Q931E_ILLEGAL_MESSAGE;
01303         }
01304         return ret;
01305 }
01306 
01307 
01317 L3INT Q931ProcUserInformationTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01318 {
01319         L3INT ret = Q931E_NO_ERROR;
01320 
01321         /* TODO: ????? */
01322 #if 0
01323         /* Find the call using CRV */
01324         call = Q931GetCallByCRV(trunk, msg->CRV);
01325         if (!call)
01326                 return Q931E_INVALID_CRV;
01327 
01328         /* check if message is valid in this state */
01329         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01330                 return Q931E_UNEXPECTED_MESSAGE;
01331 #endif
01332         switch(from) {
01333         case Q931_MSG_FROM_L4:
01334                 switch (Q931CallGetState(call)) {
01335                 case Q931_U0:
01336                 case Q931_U1:
01337                 case Q931_U6:
01338                 case Q931_U17:
01339                 case Q931_U19:
01340                         ret = Q931E_ILLEGAL_MESSAGE;
01341                         break;
01342 
01343                 case Q931_U2:
01344                         /* Send INFORMATION */
01345                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01346 
01347                         /* Start / Restart T304 */
01348                         Q931CallStartTimer(call, Q931_TIMER_T304);
01349 
01350                         /* == U2 (Overlap sending) */
01351                         break;
01352 
01353                 default:
01354                         /* Send INFORMATION */
01355                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01356                         break;
01357                 }
01358                 break;
01359         case Q931_MSG_FROM_L2:
01360                 switch (Q931CallGetState(call)) {
01361                 case Q931_U0:
01362                 case Q931_U1:
01363                 case Q931_U6:
01364                 case Q931_U17:
01365                 case Q931_U19:
01366                         ret = Q931E_ILLEGAL_MESSAGE;
01367                         break;
01368 
01369                 case Q931_U25:
01370                         /* TODO: send Info indication */
01371                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01372 
01373                         {
01374                                 /* Enqueue event */
01375                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01376 
01377                                 event->id   = Q931_EVENT_INFORMATION_INDICATION;
01378                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01379                                 event->data.message.type = msg->MesType;
01380                                 event->data.message.data = msg;
01381 
01382                                 Q931CallQueueEvent(call, event);
01383                         }
01384 
01385                         /* Start T302 */
01386                         Q931CallStartTimer(call, Q931_TIMER_T302);
01387 
01388                         /* == U25 (Overlap receiving) */
01389                         break;
01390 
01391                 default:
01392                         /* TODO: send Info indication */
01393                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01394 
01395                         {
01396                                 /* Enqueue event */
01397                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01398 
01399                                 event->id   = Q931_EVENT_INFORMATION_INDICATION;
01400                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01401                                 event->data.message.type = msg->MesType;
01402                                 event->data.message.data = msg;
01403 
01404                                 Q931CallQueueEvent(call, event);
01405                         }
01406                         break;
01407                 }
01408                 break;
01409         default:
01410                 ret = Q931E_ILLEGAL_MESSAGE;
01411         }
01412         return ret;
01413 }
01414 
01415 
01425 L3INT Q931ProcDisconnectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01426 {
01427         L3INT ret = Q931E_NO_ERROR;
01428 
01429         Q931Log(trunk, Q931_LOG_DEBUG, "Processing DISCONNECT message from %s for CRV: %d (%#hx)\n",
01430                                                  from == Q931_MSG_FROM_L4 ? "Local" : "Remote", msg->CRV, msg->CRV);
01431 #if 0
01432         /* Find the call using CRV */
01433         call = Q931GetCallByCRV(trunk, msg->CRV);
01434         if (!call)
01435                 return Q931E_INVALID_CRV;
01436 
01437         /* check if message is valid in this state */
01438         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01439                 return Q931E_UNEXPECTED_MESSAGE;
01440 #endif
01441         switch(from) {
01442         case Q931_MSG_FROM_L4:
01443                 switch(Q931CallGetState(call)) {
01444                 case Q931_U0:
01445                 case Q931_U6:
01446                 case Q931_U11:
01447                 case Q931_U12:
01448                 case Q931_U15:
01449                 case Q931_U17:
01450                 case Q931_U19:
01451                         /* TODO: should never occur? */
01452                         break;
01453 
01454                 case Q931_U1:
01455                         /* Disconnect */
01456                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01457 
01458                         /* Stop T303, Start T305 */
01459                         Q931CallStartTimer(call, Q931_TIMER_T305);
01460 
01461                         /* => U11 Disconnect request */
01462                         Q931CallSetState(call, Q931_U11);
01463                         break;
01464 
01465                 default:
01466                         /* Stop all timers */
01467                         Q931CallStopAllTimers(call);
01468 
01469                         /* Disconnect */
01470                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01471 
01472                         /* Start T305 */
01473                         Q931CallStartTimer(call, Q931_TIMER_T305);
01474 
01475                         /* => U11 Disconnect request */
01476                         Q931CallSetState(call, Q931_U11);
01477                 }
01478                 break;
01479         case Q931_MSG_FROM_L2:
01480                 switch(Q931CallGetState(call)) {
01481                 case Q931_U0:
01482                 case Q931_U1:
01483                 case Q931_U12:
01484                 case Q931_U17:
01485                 case Q931_U19:
01486                         /* TODO: should never occur? */
01487                         break;
01488 
01489                 case Q931_U6:
01490                         /* TODO: Send Disconnect indication */
01491                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01492 
01493                         {
01494                                 /* Enqueue event */
01495                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01496 
01497                                 event->id   = Q931_EVENT_DISCONNECT_INDICATION;
01498                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01499                                 event->data.message.type = msg->MesType;
01500                                 event->data.message.data = msg;
01501 
01502                                 Q931CallQueueEvent(call, event);
01503                         }
01504 
01505                         /* => U12 Disconnect indication */
01506                         Q931CallSetState(call, Q931_U12);
01507                         break;
01508 
01509                 case Q931_U11:
01510                         /* Stop T305 */
01511                         Q931CallStopTimer(call, Q931_TIMER_T305);
01512 
01513                         /* TODO: Send Release reply */
01514                         Q931Log(trunk, Q931_LOG_ERROR, "OOOPS!! We should really send a RELEASE request here!\n");
01515 
01516                         /* Start T308 */
01517                         Q931CallStartTimer(call, Q931_TIMER_T308);
01518 
01519                         /* => U19 Release request */
01520                         Q931CallSetState(call, Q931_U19);
01521                         break;
01522 
01523                 case Q931_U15:
01524                         /* Stop T319... */
01525                         Q931CallStopAllTimers(call);
01526 
01527                         /* TODO: Send Disconnect indication */
01528                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01529 
01530                         {
01531                                 /* Enqueue event */
01532                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01533 
01534                                 event->id   = Q931_EVENT_DISCONNECT_INDICATION;
01535                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01536                                 event->data.message.type = msg->MesType;
01537                                 event->data.message.data = msg;
01538 
01539                                 Q931CallQueueEvent(call, event);
01540                         }
01541 
01542                         /* => U12 Disconnect indication */
01543                         Q931CallSetState(call, Q931_U12);
01544                         break;
01545 
01546                 default:
01547                         /* TODO: Send Disconnect indication */
01548                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01549 
01550                         {
01551                                 /* Enqueue event */
01552                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01553 
01554                                 event->id   = Q931_EVENT_DISCONNECT_INDICATION;
01555                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01556                                 event->data.message.type = msg->MesType;
01557                                 event->data.message.data = msg;
01558 
01559                                 Q931CallQueueEvent(call, event);
01560                         }
01561 
01562                         /* Stop all timers */
01563                         Q931CallStopAllTimers(call);
01564 
01565                         /* => U12 Disconnect indication */
01566                         Q931CallSetState(call, Q931_U12);
01567                 }
01568                 break;
01569         default:
01570                 ret = Q931E_ILLEGAL_MESSAGE;
01571         }
01572         return ret;
01573 }
01574 
01575 
01585 L3INT Q931ProcReleaseTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01586 {
01587         L3INT ret = Q931E_NO_ERROR;
01588 #if 0
01589         /* Find the call using CRV */
01590         call = Q931GetCallByCRV(trunk, msg->CRV);
01591         if (!call)
01592                 return Q931E_INVALID_CRV;
01593 
01594         /* check if message is valid in this state */
01595         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01596                 return Q931E_UNEXPECTED_MESSAGE;
01597 #endif
01598         switch(from) {
01599         case Q931_MSG_FROM_L4:
01600                 switch(Q931CallGetState(call)) {
01601                 case Q931_U2:
01602                         /* Send RELEASE (cause 6) */
01603                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01604 
01605                         /* Stop T304, Start T308 */
01606                         Q931CallStartTimer(call, Q931_TIMER_T308);
01607 
01608                         /* => U19 Release Request */
01609                         Q931CallSetState(call, Q931_U19);
01610                         break;
01611 
01612                 case Q931_U3:
01613                         /* Stop T310 */
01614                         Q931CallStopTimer(call, Q931_TIMER_T310);
01615 
01616                         /* Send RELEASE (cause 6) */
01617                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01618 
01619                         /* Stop Start T308 */
01620                         Q931CallStartTimer(call, Q931_TIMER_T308);
01621 
01622                         /* => U19 Release Request */
01623                         Q931CallSetState(call, Q931_U19);
01624                         break;
01625 
01626                 case Q931_U12:
01627                         /* Send RELEASE */
01628                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01629 
01630                         /* Stop T304, Start T308 */
01631                         Q931CallStartTimer(call, Q931_TIMER_T308);
01632 
01633                         /* => U19 Release Request */
01634                         Q931CallSetState(call, Q931_U19);
01635                         break;
01636 
01637                 default:
01638                         break;
01639                 }
01640                 break;
01641         case Q931_MSG_FROM_L2:
01642                 switch(Q931CallGetState(call)) {
01643                 case Q931_U1:
01644                 case Q931_U17:
01645                         /* Should never happen? */
01646                         break;
01647 
01648                 case Q931_U0:
01649                         /* Release indication */
01650                         Q931Tx34(trunk, call, msg, msg->Size);
01651 
01652                         {
01653                                 /* Enqueue event */
01654                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01655 
01656                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
01657                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01658                                 event->data.message.type = msg->MesType;
01659                                 event->data.message.data = msg;
01660 
01661                                 Q931CallQueueEvent(call, event);
01662                         }
01663 
01664                         /* Send RELEASE COMPLETE reply */
01665                         ret = Q931ReleaseComplete(trunk, call, 0);
01666                         break;
01667 
01668                 case Q931_U6:
01669                 case Q931_U12:
01670                         /* Release indication */
01671                         Q931Tx34(trunk, call, msg, msg->Size);
01672 
01673                         {
01674                                 /* Enqueue event */
01675                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01676 
01677                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
01678                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01679                                 event->data.message.type = msg->MesType;
01680                                 event->data.message.data = msg;
01681 
01682                                 Q931CallQueueEvent(call, event);
01683                         }
01684 
01685                         /* Send RELEASE COMPLETE reply */
01686                         ret = Q931ReleaseComplete(trunk, call, 0);
01687                         break;
01688 
01689                 case Q931_U11:
01690                         /* Stop T305 */
01691                         Q931CallStopTimer(call, Q931_TIMER_T305);
01692 
01693                         /* Release indication */
01694                         Q931Tx34(trunk, call, msg, msg->Size);
01695 
01696                         {
01697                                 /* Enqueue event */
01698                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01699 
01700                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
01701                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01702                                 event->data.message.type = msg->MesType;
01703                                 event->data.message.data = msg;
01704 
01705                                 Q931CallQueueEvent(call, event);
01706                         }
01707 
01708                         /* Send RELEASE COMPLETE reply */
01709                         ret = Q931ReleaseComplete(trunk, call, 0);
01710                         break;
01711 
01712                 case Q931_U15:
01713                         /* Stop T319 */
01714                         Q931CallStopTimer(call, Q931_TIMER_T319);
01715 
01716                         /* Release indication */
01717                         Q931Tx34(trunk, call, msg, msg->Size);
01718 
01719                         {
01720                                 /* Enqueue event */
01721                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01722 
01723                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
01724                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01725                                 event->data.message.type = msg->MesType;
01726                                 event->data.message.data = msg;
01727 
01728                                 Q931CallQueueEvent(call, event);
01729                         }
01730 
01731                         /* Send RELEASE COMPLETE reply */
01732                         ret = Q931ReleaseComplete(trunk, call, 0);
01733                         break;
01734 
01735                 case Q931_U19:
01736                         /* Stop T308 */
01737                         Q931CallStopTimer(call, Q931_TIMER_T308);
01738 
01739                         /* TODO: Send release confirm */
01740                         Q931Tx34(trunk, call, msg, msg->Size);
01741 
01742                         {
01743                                 /* Enqueue event */
01744                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01745 
01746                                 event->id   = Q931_EVENT_RELEASE_CONFIRM;
01747                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01748                                 event->data.message.type = msg->MesType;
01749                                 event->data.message.data = msg;
01750 
01751                                 Q931CallQueueEvent(call, event);
01752                         }
01753                         break;
01754 
01755                 default:
01756                         /* Stop all timers */
01757                         Q931CallStopAllTimers(call);
01758 
01759                         /* TODO: Send release indication */
01760                         Q931Tx34(trunk, call, msg, msg->Size);
01761 
01762                         {
01763                                 /* Enqueue event */
01764                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01765 
01766                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
01767                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01768                                 event->data.message.type = msg->MesType;
01769                                 event->data.message.data = msg;
01770 
01771                                 Q931CallQueueEvent(call, event);
01772                         }
01773 
01774                         /* Send RELEASE COMPLETE reply */
01775                         ret = Q931ReleaseComplete(trunk, call, 0);
01776                 }
01777 
01778                 /* Release CRV */
01779                 Q931CallSetState(call, Q931_U0);
01780                 Q931CallRelease(call);
01781                 break;
01782         default:
01783                 ret = Q931E_ILLEGAL_MESSAGE;
01784         }
01785         return ret;
01786 }
01787 
01788 
01798 L3INT Q931ProcReleaseCompleteTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01799 {
01800         L3INT ret = Q931E_NO_ERROR;
01801 #if 0
01802         /* Find the call using CRV */
01803         call = Q931GetCallByCRV(trunk, msg->CRV);
01804         if (!call)
01805                 return Q931E_INVALID_CRV;
01806 
01807         /* check if message is valid in this state */
01808         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01809                 return Q931E_UNEXPECTED_MESSAGE;
01810 #endif
01811         switch(from) {
01812         case Q931_MSG_FROM_L4:
01813                 switch(Q931CallGetState(call)) {
01814                 case Q931_U6:   /* Reject request */
01815                         /* Send RELEASE COMPLETE */
01816                         ret = Q931ReleaseComplete(trunk, call, 0);
01817 
01818                         /* Release CRV (?) */
01819                         Q931CallSetState(call, Q931_U0);
01820                         Q931CallRelease(call);
01821                         break;
01822 
01823                 default:
01824                         break;
01825                 }
01826                 break;
01827         case Q931_MSG_FROM_L2:
01828                 switch(Q931CallGetState(call)) {
01829                 case Q931_U0:
01830                         /* Release call */
01831                         Q931CallRelease(call);
01832                         break;
01833 
01834                 case Q931_U1:
01835                         /* Stop T303 */
01836                         Q931CallStopTimer(call, Q931_TIMER_T303);
01837 
01838                         /* TODO: Send reject indication */
01839                         Q931Tx34(trunk, call, msg, msg->Size);
01840 
01841                         {
01842                                 /* Enqueue event */
01843                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01844 
01845                                 event->id   = Q931_EVENT_REJECT_INDICATION;
01846                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01847                                 event->data.message.type = msg->MesType;
01848                                 event->data.message.data = msg;
01849 
01850                                 Q931CallQueueEvent(call, event);
01851                         }
01852                         break;
01853 
01854                 case Q931_U19:
01855                         /* Stop T308 */
01856                         Q931CallStopTimer(call, Q931_TIMER_T308);
01857 
01858                         /* TODO: Send release confirm */
01859                         Q931Tx34(trunk, call, msg, msg->Size);
01860 
01861                         {
01862                                 /* Enqueue event */
01863                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01864 
01865                                 event->id   = Q931_EVENT_RELEASE_CONFIRM;
01866                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01867                                 event->data.message.type = msg->MesType;
01868                                 event->data.message.data = msg;
01869 
01870                                 Q931CallQueueEvent(call, event);
01871                         }
01872                         break;
01873 
01874                 default:
01875                         /* Stop all timers */
01876                         Q931CallStopAllTimers(call);
01877 
01878                         /* TODO: Release indication */
01879                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01880 
01881                         {
01882                                 /* Enqueue event */
01883                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
01884 
01885                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
01886                                 event->type = Q931_EVENT_TYPE_MESSAGE;
01887                                 event->data.message.type = msg->MesType;
01888                                 event->data.message.data = msg;
01889 
01890                                 Q931CallQueueEvent(call, event);
01891                         }
01892                 }
01893 
01894                 /* Release CRV */
01895                 Q931CallSetState(call, Q931_U0);
01896                 Q931CallRelease(call);
01897                 break;
01898         default:
01899                 ret = Q931E_ILLEGAL_MESSAGE;
01900         }
01901         return ret;
01902 }
01903 
01904 
01914 L3INT Q931ProcRestartTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01915 {
01916         L3INT ret = Q931E_NO_ERROR;
01917 
01918         if (msg->CRV)
01919                 return Q931E_INVALID_CRV;
01920 
01921 #if 0
01922         /* Find the call using CRV */
01923         call = Q931GetCallByCRV(trunk, msg->CRV);
01924         if (!call)
01925                 return Q931E_INVALID_CRV;
01926 
01927         /* check if message is valid in this state */
01928         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01929                 return Q931E_UNEXPECTED_MESSAGE;
01930 #endif
01931         /* TODO: T317, proper handling etc. */
01932 
01933         switch(from) {
01934         case Q931_MSG_FROM_L4:
01935                 /* TODO Add proc here */
01936                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01937                 break;
01938         case Q931_MSG_FROM_L2:
01939                 /* TODO Add proc here */
01940                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01941 
01942                 if (Q931TrunkIsSetFlag(trunk, Q931_TFLAG_AUTO_RESTART_ACK)) {
01943                         Q931AckRestart(trunk, msg);
01944                 }
01945 
01946                 /* TODO: Restart?? */
01947                 break;
01948         default:
01949                 ret = Q931E_ILLEGAL_MESSAGE;
01950         }
01951         return ret;
01952 }
01953 
01954 
01964 L3INT Q931ProcRestartAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01965 {
01966         L3INT ret = Q931E_NO_ERROR;
01967 
01968 #if 0
01969         /* Find the call using CRV */
01970         call = Q931GetCallByCRV(trunk, msg->CRV);
01971         if (!call)
01972                 return Q931E_INVALID_CRV;
01973 
01974         /* check if message is valid in this state */
01975         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01976                 return Q931E_UNEXPECTED_MESSAGE;
01977 #endif
01978 #if 0
01979         if (msg->CRV) {
01980                 /* Find the call using CRV */
01981                 ret = Q931FindCRV(trunk, msg->CRV, &callIndex);
01982                 if (ret != Q931E_NO_ERROR)
01983                         return ret;
01984                 /* TODO - Set correct timer here */
01985                 Q931StartTimer(trunk, callIndex, Q931_TIMER_T303);
01986         }
01987 #endif
01988 
01989         switch(from) {
01990         case Q931_MSG_FROM_L4:
01991                 /* TODO Add proc here */
01992                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01993                 break;
01994         case Q931_MSG_FROM_L2:
01995                 /* TODO Add proc here */
01996                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01997 
01998                 /* TODO: RestartACK?? */
01999                 break;
02000         default:
02001                 ret = Q931E_ILLEGAL_MESSAGE;
02002         }
02003         return ret;
02004 }
02005 
02006 
02016 L3INT Q931ProcCongestionControlTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02017 {
02018         L3INT ret = Q931E_NO_ERROR;
02019 #if 0
02020         /* Find the call using CRV */
02021         call = Q931GetCallByCRV(trunk, msg->CRV);
02022         if (!call)
02023                 return Q931E_INVALID_CRV;
02024 
02025         /* check if message is valid in this state */
02026         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02027                 return Q931E_UNEXPECTED_MESSAGE;
02028 #endif
02029         switch(from) {
02030         case Q931_MSG_FROM_L4:
02031                 /* TODO Add proc here */
02032                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02033                 break;
02034         case Q931_MSG_FROM_L2:
02035                 /* TODO Add proc here */
02036                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02037                 break;
02038         default:
02039                 ret = Q931E_ILLEGAL_MESSAGE;
02040         }
02041         return ret;
02042 }
02043 
02044 
02054 L3INT Q931ProcInformationTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02055 {
02056         L3INT ret = Q931E_NO_ERROR;
02057 #if 0
02058         /* Find the call using CRV */
02059         call = Q931GetCallByCRV(trunk, msg->CRV);
02060         if (!call)
02061                 return Q931E_INVALID_CRV;
02062 
02063         /* check if message is valid in this state */
02064         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02065                 return Q931E_UNEXPECTED_MESSAGE;
02066 #endif
02067         switch(from) {
02068         case Q931_MSG_FROM_L4:
02069                 /* TODO Add proc here */
02070                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02071                 break;
02072         case Q931_MSG_FROM_L2:
02073                 /* TODO Add proc here */
02074                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02075                 break;
02076         default:
02077                 ret = Q931E_ILLEGAL_MESSAGE;
02078         }
02079         return ret;
02080 }
02081 
02082 
02092 L3INT Q931ProcNotifyTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02093 {
02094         L3INT ret = Q931E_NO_ERROR;
02095 #if 0
02096         /* Find the call using CRV */
02097         call = Q931GetCallByCRV(trunk, msg->CRV);
02098         if (!call)
02099                 return Q931E_INVALID_CRV;
02100 
02101         /* check if message is valid in this state */
02102         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02103                 return Q931E_UNEXPECTED_MESSAGE;
02104 #endif
02105         switch(from) {
02106         case Q931_MSG_FROM_L4:
02107                 /* TODO Add proc here */
02108                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02109                 break;
02110         case Q931_MSG_FROM_L2:
02111                 /* TODO Add proc here */
02112                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02113                 break;
02114         default:
02115                 ret = Q931E_ILLEGAL_MESSAGE;
02116         }
02117         return ret;
02118 }
02119 
02120 
02130 L3INT Q931ProcStatusTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02131 {
02132         L3INT ret = Q931E_NO_ERROR;
02133 #if 0
02134         /* Find the call using CRV */
02135         call = Q931GetCallByCRV(trunk, msg->CRV);
02136         if (!call)
02137                 return Q931E_INVALID_CRV;
02138 
02139         /* check if message is valid in this state */
02140         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02141                 return Q931E_UNEXPECTED_MESSAGE;
02142 #endif
02143         switch(from) {
02144         case Q931_MSG_FROM_L4:
02145                 /* TODO Add proc here */
02146                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02147                 break;
02148         case Q931_MSG_FROM_L2:
02149                 {
02150                         Q931ie_Cause *cause = Q931GetIEPtr(msg->Cause, msg->buf);
02151                         int state = Q931_U0;
02152 
02153                         if (Q931IsIEPresent(msg->CallState)) {
02154                                 Q931ie_CallState *cs = Q931GetIEPtr(msg->CallState, msg->buf);
02155                                 state = cs->CallState;
02156                         }
02157 
02158                         switch (Q931CallGetState(call)) {
02159                         case Q931_U0:
02160                                 if (Q931CallIsGlobal(call)) {
02161                                         return Q931E_NO_ERROR;
02162                                 } else {
02163                                         /* Reply with RELEASE COMPLETE */
02164                                         L3UCHAR tmp[Q931L4BUF];
02165                                         Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02166 
02167                                         Q931InitMesGeneric(gen);
02168                                         gen->MesType = Q931mes_DISCONNECT;
02169                                         gen->CRV     = Q931CallGetCRV(call);
02170 
02171                                         cause->Value = Q850_CAUSE_WRONG_CALL_STATE;
02172                                         gen->Cause = Q931AppendIE(gen, (L3UCHAR *)cause);
02173 
02174                                         Q931Rx43(trunk, gen, gen->Size);
02175                                 }
02176                                 break;
02177 
02178                         case Q931_U19:
02179                                 if (Q931CallIsGlobal(call)) {
02180                                         return Q931E_NO_ERROR;
02181                                 }
02182 
02183                                 if (state == Q931_U0) {
02184                                         /* Terminate call */
02185 
02186                                         /* STATUS INDICATION */
02187                                         ret = Q931Tx34(trunk, call, msg, msg->Size);
02188 
02189                                         {
02190                                                 /* Enqueue event */
02191                                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
02192 
02193                                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
02194                                                 event->type = Q931_EVENT_TYPE_MESSAGE;
02195                                                 event->data.message.type = msg->MesType;
02196                                                 event->data.message.data = msg;
02197 
02198                                                 Q931CallQueueEvent(call, event);
02199                                         }
02200 
02201                                         /* Release call ref */
02202                                         Q931CallSetState(call, Q931_U0);
02203                                         Q931CallRelease(call);
02204                                 }
02205                                 break;
02206 
02207                         /* TODO: RESTART / RESTART_REQ state */
02208 
02209                         default:
02210                                 if (Q931CallIsGlobal(call)) {
02211                                         return Q931E_NO_ERROR;
02212                                 }
02213 
02214                                 if (state == Q931_U0) {
02215                                         /* Terminate call */
02216 
02217                                         /* STATUS INDICATION */
02218                                         ret = Q931Tx34(trunk, call, msg, msg->Size);
02219 
02220                                         {
02221                                                 /* Enqueue event */
02222                                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
02223 
02224                                                 event->id   = Q931_EVENT_RELEASE_INDICATION;
02225                                                 event->type = Q931_EVENT_TYPE_MESSAGE;
02226                                                 event->data.message.type = msg->MesType;
02227                                                 event->data.message.data = msg;
02228 
02229                                                 Q931CallQueueEvent(call, event);
02230                                         }
02231 
02232                                         /* Release call ref */
02233                                         Q931CallSetState(call, Q931_U0);
02234                                         Q931CallRelease(call);
02235                                 }
02236                                 else if (state == Q931CallGetState(call)) {
02237                                         /* "Compatible" call state */
02238 
02239                                         switch (cause->Value) {
02240                                         case Q850_CAUSE_MANDATORY_IE_MISSING:
02241                                         case Q850_CAUSE_MESSAGE_TYPE_NONEXIST:
02242                                         case Q850_CAUSE_WRONG_MESSAGE:
02243                                         case Q850_CAUSE_IE_NONEXIST:
02244                                         case Q850_CAUSE_INVALID_IE_CONTENTS:
02245                                                 /* fatal */
02246                                                 break;
02247 
02248                                         default:
02249                                                 return Q931E_NO_ERROR;
02250                                         }
02251 
02252                                         /* STATUS indication (error) */
02253                                         ret = Q931Tx34(trunk, call, msg, msg->Size);
02254 
02255                                         {
02256                                                 /* Enqueue event */
02257                                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
02258 
02259                                                 event->id   = Q931_EVENT_STATUS_INDICATION;
02260                                                 event->type = Q931_EVENT_TYPE_MESSAGE;
02261                                                 event->error= 1;
02262                                                 event->data.message.type = msg->MesType;
02263                                                 event->data.message.data = msg;
02264 
02265                                                 Q931CallQueueEvent(call, event);
02266                                         }
02267 
02268                                         /* Send DISCONNECT */
02269                                         {
02270                                                 L3UCHAR tmp[Q931L4BUF];
02271                                                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02272 
02273                                                 Q931InitMesGeneric(gen);
02274                                                 gen->MesType = Q931mes_DISCONNECT;
02275                                                 gen->CRV     = Q931CallGetCRV(call);
02276 
02277                                                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)cause);
02278 
02279                                                 Q931Rx43(trunk, gen, gen->Size);
02280                                         }
02281 
02282                                         /* Start T305 */
02283                                         Q931CallStartTimer(call, Q931_TIMER_T305);
02284 
02285                                         /* => Disconnect request */
02286                                         Q931CallSetState(call, Q931_U11);
02287                                 }
02288                                 else {
02289                                         /* Call state not compatible */
02290 
02291                                         /* STATUS indication (error) */
02292                                         ret = Q931Tx34(trunk, call, msg, msg->Size);
02293 
02294                                         {
02295                                                 /* Enqueue event */
02296                                                 struct Q931_CallEvent *event = Q931CallNewEvent(call);
02297 
02298                                                 event->id   = Q931_EVENT_STATUS_INDICATION;
02299                                                 event->type = Q931_EVENT_TYPE_MESSAGE;
02300                                                 event->error= 1;
02301                                                 event->data.message.type = msg->MesType;
02302                                                 event->data.message.data = msg;
02303 
02304                                                 Q931CallQueueEvent(call, event);
02305                                         }
02306 
02307                                         /* Send DISCONNECT */
02308                                         {
02309                                                 L3UCHAR tmp[Q931L4BUF];
02310                                                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02311 
02312                                                 Q931InitMesGeneric(gen);
02313                                                 gen->MesType = Q931mes_DISCONNECT;
02314                                                 gen->CRV     = Q931CallGetCRV(call);
02315 
02316                                                 cause->Value = Q850_CAUSE_WRONG_CALL_STATE;
02317                                                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)cause);
02318 
02319                                                 Q931Rx43(trunk, gen, gen->Size);
02320                                         }
02321 
02322                                         /* Start T305 */
02323                                         Q931CallStartTimer(call, Q931_TIMER_T305);
02324 
02325                                         /* => Disconnect request */
02326                                         Q931CallSetState(call, Q931_U11);
02327                                 }
02328                         }
02329                 }
02330                 break;
02331         default:
02332                 ret = Q931E_ILLEGAL_MESSAGE;
02333         }
02334         return ret;
02335 }
02336 
02337 
02347 L3INT Q931ProcStatusEnquiryTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02348 {
02349         L3INT ret = Q931E_NO_ERROR;
02350 #if 0
02351         /* Find the call using CRV */
02352         call = Q931GetCallByCRV(trunk, msg->CRV);
02353         if (!call)
02354                 return Q931E_INVALID_CRV;
02355 
02356         /* check if message is valid in this state */
02357         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02358                 return Q931E_UNEXPECTED_MESSAGE;
02359 #endif
02360         switch(from) {
02361 #if 0
02362         case Q931_MSG_FROM_L4:
02363                 /* TODO Add proc here */
02364                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02365                 break;
02366 #endif
02367         case Q931_MSG_FROM_L2:
02368                 ret = Q931StatusEnquiryResponse(trunk, call, Q850_CAUSE_RESPONSE_TO_STATUS_ENQUIRY);
02369                 break;
02370         default:
02371                 ret = Q931E_ILLEGAL_MESSAGE;
02372         }
02373         return ret;
02374 }
02375 
02376 
02386 L3INT Q931ProcSegmentTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02387 {
02388         L3INT ret = Q931E_NO_ERROR;
02389 #if 0
02390         /* Find the call using CRV */
02391         call = Q931GetCallByCRV(trunk, msg->CRV);
02392         if (!call)
02393                 return Q931E_INVALID_CRV;
02394 
02395         /* check if message is valid in this state */
02396         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02397                 return Q931E_UNEXPECTED_MESSAGE;
02398 #endif
02399         switch(from) {
02400         case Q931_MSG_FROM_L4:
02401                 /* TODO Add proc here */
02402                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02403                 break;
02404         case Q931_MSG_FROM_L2:
02405                 /* TODO Add proc here */
02406                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02407                 break;
02408         default:
02409                 ret = Q931E_ILLEGAL_MESSAGE;
02410         }
02411         return ret;
02412 }
02413 
02416 /****************************************************************************/
02417 /******************* Q.932 - Supplementary Services *************************/
02418 /****************************************************************************/
02419 
02425 L3INT Q932ProcFacilityTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02426 {
02427         L3INT ret = Q931E_NO_ERROR;
02428 #if 0
02429         /* Find the call using CRV */
02430         call = Q931GetCallByCRV(trunk, msg->CRV);
02431         if (!call)
02432                 return Q931E_INVALID_CRV;
02433 
02434         /* check if message is valid in this state */
02435         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02436                 return Q931E_UNEXPECTED_MESSAGE;
02437 #endif
02438         switch(from) {
02439         case Q931_MSG_FROM_L4:
02440                 /* TODO Add proc here */
02441                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02442                 break;
02443         case Q931_MSG_FROM_L2:
02444                 /* TODO Add proc here */
02445                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02446                 break;
02447         default:
02448                 ret = Q931E_ILLEGAL_MESSAGE;
02449         }
02450         return ret;
02451 }
02452 
02453 L3INT Q932ProcHoldTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02454 {
02455         L3INT ret = Q931E_NO_ERROR;
02456 #if 0
02457         /* Find the call using CRV */
02458         call = Q931GetCallByCRV(trunk, msg->CRV);
02459         if (!call)
02460                 return Q931E_INVALID_CRV;
02461 
02462         /* check if message is valid in this state */
02463         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02464                 return Q931E_UNEXPECTED_MESSAGE;
02465 #endif
02466         switch(from) {
02467         case Q931_MSG_FROM_L4:
02468                 /* TODO Add proc here */
02469                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02470                 break;
02471         case Q931_MSG_FROM_L2:
02472                 /* TODO Add proc here */
02473                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02474                 break;
02475         default:
02476                 ret = Q931E_ILLEGAL_MESSAGE;
02477         }
02478         return ret;
02479 }
02480 
02481 L3INT Q932ProcHoldAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02482 {
02483         L3INT ret = Q931E_NO_ERROR;
02484 #if 0
02485         /* Find the call using CRV */
02486         call = Q931GetCallByCRV(trunk, msg->CRV);
02487         if (!call)
02488                 return Q931E_INVALID_CRV;
02489 
02490         /* check if message is valid in this state */
02491         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02492                 return Q931E_UNEXPECTED_MESSAGE;
02493 #endif
02494         switch(from) {
02495         case Q931_MSG_FROM_L4:
02496                 /* TODO Add proc here */
02497                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02498                 break;
02499         case Q931_MSG_FROM_L2:
02500                 /* TODO Add proc here */
02501                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02502                 break;
02503         default:
02504                 ret = Q931E_ILLEGAL_MESSAGE;
02505         }
02506         return ret;
02507 }
02508 
02509 L3INT Q932ProcHoldRejectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02510 {
02511         L3INT ret = Q931E_NO_ERROR;
02512 #if 0
02513         /* Find the call using CRV */
02514         call = Q931GetCallByCRV(trunk, msg->CRV);
02515         if (!call)
02516                 return Q931E_INVALID_CRV;
02517 
02518         /* check if message is valid in this state */
02519         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02520                 return Q931E_UNEXPECTED_MESSAGE;
02521 #endif
02522         switch(from) {
02523         case Q931_MSG_FROM_L4:
02524                 /* TODO Add proc here */
02525                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02526                 break;
02527         case Q931_MSG_FROM_L2:
02528                 /* TODO Add proc here */
02529                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02530                 break;
02531         default:
02532                 ret = Q931E_ILLEGAL_MESSAGE;
02533         }
02534         return ret;
02535 }
02536 
02537 L3INT Q932ProcRegisterTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02538 {
02539         L3INT ret = Q931E_NO_ERROR;
02540 #if 0
02541         /* Find the call using CRV */
02542         call = Q931GetCallByCRV(trunk, msg->CRV);
02543         if (!call)
02544                 return Q931E_INVALID_CRV;
02545 
02546         /* check if message is valid in this state */
02547         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02548                 return Q931E_UNEXPECTED_MESSAGE;
02549 #endif
02550         switch(from) {
02551         case Q931_MSG_FROM_L4:
02552                 /* TODO Add proc here */
02553                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02554                 break;
02555         case Q931_MSG_FROM_L2:
02556                 /* TODO Add proc here */
02557                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02558                 break;
02559         default:
02560                 ret = Q931E_ILLEGAL_MESSAGE;
02561         }
02562         return ret;
02563 }
02564 
02565 L3INT Q932ProcRetrieveTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02566 {
02567         L3INT ret = Q931E_NO_ERROR;
02568 #if 0
02569         /* Find the call using CRV */
02570         call = Q931GetCallByCRV(trunk, msg->CRV);
02571         if (!call)
02572                 return Q931E_INVALID_CRV;
02573 
02574         /* check if message is valid in this state */
02575         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02576                 return Q931E_UNEXPECTED_MESSAGE;
02577 #endif
02578         switch(from) {
02579         case Q931_MSG_FROM_L4:
02580                 /* TODO Add proc here */
02581                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02582                 break;
02583         case Q931_MSG_FROM_L2:
02584                 /* TODO Add proc here */
02585                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02586                 break;
02587         default:
02588                 ret = Q931E_ILLEGAL_MESSAGE;
02589         }
02590         return ret;
02591 }
02592 
02593 L3INT Q932ProcRetrieveAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02594 {
02595         L3INT ret = Q931E_NO_ERROR;
02596 #if 0
02597         /* Find the call using CRV */
02598         call = Q931GetCallByCRV(trunk, msg->CRV);
02599         if (!call)
02600                 return Q931E_INVALID_CRV;
02601 
02602         /* check if message is valid in this state */
02603         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02604                 return Q931E_UNEXPECTED_MESSAGE;
02605 #endif
02606         switch(from) {
02607         case Q931_MSG_FROM_L4:
02608                 /* TODO Add proc here */
02609                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02610                 break;
02611         case Q931_MSG_FROM_L2:
02612                 /* TODO Add proc here */
02613                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02614                 break;
02615         default:
02616                 ret = Q931E_ILLEGAL_MESSAGE;
02617         }
02618         return ret;
02619 }
02620 
02621 L3INT Q932ProcRetrieveRejectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
02622 {
02623         L3INT ret = Q931E_NO_ERROR;
02624 #if 0
02625         /* Find the call using CRV */
02626         call = Q931GetCallByCRV(trunk, msg->CRV);
02627         if (!call)
02628                 return Q931E_INVALID_CRV;
02629 
02630         /* check if message is valid in this state */
02631         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
02632                 return Q931E_UNEXPECTED_MESSAGE;
02633 #endif
02634         switch(from) {
02635         case Q931_MSG_FROM_L4:
02636                 /* TODO Add proc here */
02637                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
02638                 break;
02639         case Q931_MSG_FROM_L2:
02640                 /* TODO Add proc here */
02641                 ret = Q931Tx34(trunk, call, msg, msg->Size);
02642                 break;
02643         default:
02644                 ret = Q931E_ILLEGAL_MESSAGE;
02645         }
02646         return ret;
02647 }
02648 
02651 /************************************************************************************
02652  * Timer callbacks (TE side)
02653  ************************************************************************************/
02654 
02667 L3INT Q931ProcTimeoutT301TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02668 {
02669         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T301 timed out for call %d\n", call->CRV);
02670 
02671         if (Q931CallGetState(call) != Q931_U4) {
02672                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T301 in state %s (wrong state)\n", Q931CallGetStateName(call));
02673                 return Q931E_NO_ERROR;
02674         }
02675 
02676         return Q931E_NO_ERROR;
02677 }
02678 
02686 L3INT Q931ProcTimeoutT302TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02687 {
02688         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T302 timed out for call %d\n", call->CRV);
02689 
02690         if (Q931CallGetState(call) != Q931_U25) {
02691                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T302 in state %s (wrong state)\n", Q931CallGetStateName(call));
02692                 return Q931E_NO_ERROR;
02693         }
02694 
02695         /* TODO: Send Timeout indication */
02696         {
02697                 struct Q931_CallEvent event;
02698 
02699                 Q931CallInitEvent(&event);
02700                 event.id   = Q931_EVENT_TIMEOUT_INDICATION;
02701                 event.type = Q931_EVENT_TYPE_TIMER;
02702                 event.data.timer.id = Q931_TIMER_T302;
02703 
02704                 Q931CallSendEvent(call, &event);
02705         }
02706 
02707         return Q931E_NO_ERROR;
02708 }
02709 
02710 
02718 L3INT Q931ProcTimeoutT303TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02719 {
02720         L3UCHAR cnt = Q931CallGetTimerExpireCount(call);        /* T303 uses the counter */
02721 
02722         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T303 timed out for call %d (number of times: %hhu)\n", call->CRV, cnt);
02723 
02724         if (Q931CallGetState(call) != Q931_U1) {
02725                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T303 in state %s (wrong state)\n", Q931CallGetStateName(call));
02726                 return Q931E_NO_ERROR;
02727         }
02728 
02729         if (cnt == 1) {
02730                 /* TODO: Resend SETUP */
02731 
02732                 /* Restart T303 */
02733                 Q931CallRestartTimer(call, Q931_TIMER_T303);
02734 
02735                 /* No state change */
02736         } else {
02737                 struct Q931_CallEvent event;
02738 
02739                 /* (TODO:) Send SETUP CONFIRM Error */
02740                 Q931CallInitEvent(&event);
02741                 event.id    = Q931_EVENT_SETUP_CONFIRM;
02742                 event.type  = Q931_EVENT_TYPE_TIMER;
02743                 event.error = 1;
02744                 event.data.timer.id = Q931_TIMER_T303;
02745 
02746                 /* Send event immediately to layer 4 */
02747                 Q931CallSendEvent(call, &event);
02748 
02749                 /* Release CRV */
02750                 Q931CallSetState(call, Q931_U0);
02751                 Q931CallRelease(call);
02752         }
02753         return Q931E_NO_ERROR;
02754 }
02755 
02756 
02764 L3INT Q931ProcTimeoutT304TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02765 {
02766         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T304 timed out for call %d\n", call->CRV);
02767 
02768         if (Q931CallGetState(call) != Q931_U2) {
02769                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T304 in state %s (wrong state)\n", Q931CallGetStateName(call));
02770                 return Q931E_NO_ERROR;
02771         }
02772 
02773         /* TODO: Send DISCONNECT */
02774         {
02775                 L3UCHAR tmp[Q931L4BUF];
02776                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02777                 Q931ie_Cause cause;
02778 
02779                 Q931InitMesGeneric(gen);
02780                 gen->MesType = Q931mes_DISCONNECT;
02781                 gen->CRV     = Q931CallGetCRV(call);
02782 
02783                 /* TODO: use the correct cause code */
02784                 cause.IEId = Q931ie_CAUSE;
02785                 cause.Size = sizeof(Q931ie_Cause);
02786                 cause.CodStand = Q931_CODING_ITU;       /* ITU */
02787                 cause.Location = 1;     /* private network */
02788                 cause.Recom    = 1;     /* */
02789                 cause.Value = Q850_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
02790 
02791                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)&cause);
02792 
02793                 Q931Tx32(trunk, 0, gen, gen->Size);
02794         }
02795 
02796         /* (TODO:) Send SETUP CONFIRM error */
02797         {
02798                 struct Q931_CallEvent event;
02799 
02800                 Q931CallInitEvent(&event);
02801                 event.id    = Q931_EVENT_SETUP_CONFIRM;
02802                 event.type  = Q931_EVENT_TYPE_TIMER;
02803                 event.error = 1;
02804                 event.data.timer.id = Q931_TIMER_T304;
02805 
02806                 /* Send event immediately to layer 4 */
02807                 Q931CallSendEvent(call, &event);
02808         }
02809 
02810         /* Start T305 */
02811         Q931CallStartTimer(call, Q931_TIMER_T305);
02812 
02813         /* => 11: Disconnect request */
02814         Q931CallSetState(call, Q931_U11);
02815 
02816         return Q931E_NO_ERROR;
02817 }
02818 
02819 
02827 L3INT Q931ProcTimeoutT305TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02828 {
02829         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T305 timed out for call %d\n", call->CRV);
02830 
02831         if (Q931CallGetState(call) != Q931_U11) {
02832                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T305 in state %s (wrong state)\n", Q931CallGetStateName(call));
02833                 return Q931E_NO_ERROR;
02834         }
02835 
02836         /* Send RELEASE (cause) */
02837         {
02838                 L3UCHAR tmp[Q931L4BUF];
02839                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02840                 Q931ie_Cause cause;
02841 
02842                 Q931InitMesGeneric(gen);
02843                 gen->MesType = Q931mes_RELEASE;
02844                 gen->CRV     = Q931CallGetCRV(call);
02845 
02846                 /* TODO: use the original cause */
02847                 cause.IEId = Q931ie_CAUSE;
02848                 cause.Size = sizeof(Q931ie_Cause);
02849                 cause.CodStand = Q931_CODING_ITU;       /* ITU */
02850                 cause.Location = 1;     /* private network */
02851                 cause.Recom    = 1;     /* */
02852                 cause.Value = Q850_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
02853 
02854                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)&cause);
02855 
02856                 Q931Tx32(trunk, 0, gen, gen->Size);
02857         }
02858 
02859         /* Start T308 */
02860         Q931CallStartTimer(call, Q931_TIMER_T308);
02861 
02862         /* => 19: Release request */
02863         Q931CallSetState(call, Q931_U19);
02864 
02865         return Q931E_NO_ERROR;
02866 }
02867 
02868 
02876 L3INT Q931ProcTimeoutT308TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02877 {
02878         L3UCHAR cnt = Q931CallGetTimerExpireCount(call);        /* T308 uses the counter */
02879 
02880         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T308 timed out for call %d (number of times %hhu)\n", call->CRV, cnt);
02881 
02882         if (Q931CallGetState(call) != Q931_U19) {
02883                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T308 in state %s (wrong state)\n", Q931CallGetStateName(call));
02884                 return Q931E_NO_ERROR;
02885         }
02886 
02887         if (cnt == 1) {
02888                 /* TODO: Send RELEASE */
02889                 {
02890                         L3UCHAR tmp[Q931L4BUF];
02891                         Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02892                         Q931ie_Cause cause;
02893 
02894                         Q931InitMesGeneric(gen);
02895                         gen->MesType = Q931mes_RELEASE;
02896                         gen->CRV     = Q931CallGetCRV(call);
02897 
02898                         /* TODO: use the original cause */
02899                         cause.IEId = Q931ie_CAUSE;
02900                         cause.Size = sizeof(Q931ie_Cause);
02901                         cause.CodStand = Q931_CODING_ITU;       /* ITU */
02902                         cause.Location = 1;     /* private network */
02903                         cause.Recom    = 1;     /* */
02904                         cause.Value = Q850_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
02905 
02906                         gen->Cause = Q931AppendIE(gen, (L3UCHAR *)&cause);
02907 
02908                         Q931Tx32(trunk, 0, gen, gen->Size);
02909                 }
02910 
02911                 /* Restart T308 */
02912                 Q931CallRestartTimer(call, Q931_TIMER_T308);
02913 
02914                 /* No state change */
02915         } else {
02916                 /* TODO: Place B-Channel in maintenance (option, ?) */
02917 
02918                 /* (TODO:) Send RELEASE CONFIRM (error) indication */
02919                 {
02920                         struct Q931_CallEvent event;
02921 
02922                         Q931CallInitEvent(&event);
02923                         event.id    = Q931_EVENT_RELEASE_CONFIRM;
02924                         event.type  = Q931_EVENT_TYPE_TIMER;
02925                         event.error = 1;
02926                         event.data.timer.id = Q931_TIMER_T308;
02927 
02928                         /* Send event immediately to layer 4 */
02929                         Q931CallSendEvent(call, &event);
02930                 }
02931 
02932                 /* Release CRV */
02933                 Q931CallSetState(call, Q931_U0);
02934                 Q931CallRelease(call);
02935         }
02936         return Q931E_NO_ERROR;
02937 }
02938 
02939 
02947 L3INT Q931ProcTimeoutT309TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02948 {
02949         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T309 timed out for call %d\n", call->CRV);
02950 
02951         /* TODO: Send DATA LINK FAILURE indication */
02952 
02953         /* Release CRV */
02954         Q931CallSetState(call, Q931_U0);
02955         Q931CallRelease(call);
02956 
02957         return Q931E_NO_ERROR;
02958 }
02959 
02960 
02968 L3INT Q931ProcTimeoutT310TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02969 {
02970         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T310 timed out for call %d\n", call->CRV);
02971 
02972         if (Q931CallGetState(call) != Q931_U3) {
02973                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T310 in state %s (wrong state)\n", Q931CallGetStateName(call));
02974                 return Q931E_NO_ERROR;
02975         }
02976 
02977         /* TODO: Send DISCONNECT */
02978         {
02979                 L3UCHAR tmp[Q931L4BUF];
02980                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
02981                 Q931ie_Cause cause;
02982 
02983                 Q931InitMesGeneric(gen);
02984                 gen->MesType = Q931mes_DISCONNECT;
02985                 gen->CRV     = Q931CallGetCRV(call);
02986 
02987                 /* TODO: use the correct cause code */
02988                 cause.IEId = Q931ie_CAUSE;
02989                 cause.Size = sizeof(Q931ie_Cause);
02990                 cause.CodStand = Q931_CODING_ITU;       /* ITU */
02991                 cause.Location = 1;     /* private network */
02992                 cause.Recom    = 1;     /* */
02993                 cause.Value = Q850_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
02994 
02995                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)&cause);
02996 
02997                 Q931Tx32(trunk, 0, gen, gen->Size);
02998         }
02999 
03000         /* (TODO:) Send SETUP CONFIRM error */
03001         {
03002                 struct Q931_CallEvent event;
03003 
03004                 Q931CallInitEvent(&event);
03005                 event.id    = Q931_EVENT_SETUP_CONFIRM;
03006                 event.type  = Q931_EVENT_TYPE_TIMER;
03007                 event.error = 1;
03008                 event.data.timer.id = Q931_TIMER_T310;
03009 
03010                 /* Send event immediately to layer 4 */
03011                 Q931CallSendEvent(call, &event);
03012         }
03013 
03014         /* Start T305 */
03015         Q931CallStartTimer(call, Q931_TIMER_T305);
03016 
03017         /* => 11: Disconnect request */
03018         Q931CallSetState(call, Q931_U11);
03019 
03020         return Q931E_NO_ERROR;
03021 }
03022 
03023 
03031 L3INT Q931ProcTimeoutT311TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03032 {
03033         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T311 timed out for call %d\n", call->CRV);
03034         return Q931E_NO_ERROR;
03035 }
03036 
03037 
03045 L3INT Q931ProcTimeoutT313TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03046 {
03047         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T313 timed out for call %d\n", call->CRV);
03048 
03049         if (Q931CallGetState(call) != Q931_U8) {
03050                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T313 in state %s (wrong state)\n", Q931CallGetStateName(call));
03051                 return Q931E_NO_ERROR;
03052         }
03053 
03054         /* TODO: Send DISCONNECT */
03055         {
03056                 L3UCHAR tmp[Q931L4BUF];
03057                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
03058                 Q931ie_Cause cause;
03059 
03060                 Q931InitMesGeneric(gen);
03061                 gen->MesType = Q931mes_DISCONNECT;
03062                 gen->CRV     = Q931CallGetCRV(call);
03063 
03064                 /* TODO: use the correct cause code */
03065                 cause.IEId = Q931ie_CAUSE;
03066                 cause.Size = sizeof(Q931ie_Cause);
03067                 cause.CodStand = Q931_CODING_ITU;       /* ITU */
03068                 cause.Location = 1;     /* private network */
03069                 cause.Recom    = 1;     /* */
03070                 cause.Value = Q850_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03071 
03072                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)&cause);
03073 
03074                 Q931Tx32(trunk, 0, gen, gen->Size);
03075         }
03076 
03077         /* (TODO:) Send SETUP COMPLETE error */
03078         {
03079                 struct Q931_CallEvent event;
03080 
03081                 Q931CallInitEvent(&event);
03082                 event.id    = Q931_EVENT_SETUP_COMPLETE_INDICATION;
03083                 event.type  = Q931_EVENT_TYPE_TIMER;
03084                 event.error = 1;
03085                 event.data.timer.id = Q931_TIMER_T313;
03086 
03087                 /* Send event immediately to layer 4 */
03088                 Q931CallSendEvent(call, &event);
03089         }
03090 
03091         /* Start T305 */
03092         Q931CallStartTimer(call, Q931_TIMER_T305);
03093 
03094         /* => 11: Disconnect request */
03095         Q931CallSetState(call, Q931_U11);
03096 
03097         return Q931E_NO_ERROR;
03098 }
03099 
03100 
03109 L3INT Q931ProcTimeoutT314TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03110 {
03111         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T314 timed out for call %d\n", call->CRV);
03112         return Q931E_NO_ERROR;
03113 }
03114 
03115 
03123 L3INT Q931ProcTimeoutT316TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03124 {
03125         L3UCHAR cnt = Q931CallGetTimerExpireCount(call);
03126 
03127         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T316 timed out for call %d (number of times: %hhu)\n", call->CRV, cnt);
03128 
03129         /* TODO: Only valid in state REST1 */
03130 
03131         if (cnt < 2) {
03132                 /* TODO: Send RESTART */
03133 
03134                 /* Restart T316 */
03135                 Q931CallRestartTimer(call, Q931_TIMER_T316);
03136         } else {
03137                 /* TODO: Maintenance action (?) */
03138         }
03139         return Q931E_NO_ERROR;
03140 }
03141 
03142 
03150 L3INT Q931ProcTimeoutT317TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03151 {
03152         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T317 timed out for call %d\n", call->CRV);
03153 
03154         /* TODO: Only valid in states REST1 + REST2 */
03155 
03156         /* TODO: Maintenance action (?) */
03157 
03158         return Q931E_NO_ERROR;
03159 }
03160 
03161 
03169 L3INT Q931ProcTimeoutT318TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03170 {
03171         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T318 timed out for call %d\n", call->CRV);
03172 
03173         if (Q931CallGetState(call) != Q931_U17) {
03174                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T318 in state %s (wrong state)\n", Q931CallGetStateName(call));
03175                 return Q931E_NO_ERROR;
03176         }
03177 
03178         /* Send RELEASE (cause) */
03179         {
03180                 L3UCHAR tmp[Q931L4BUF];
03181                 Q931mes_Generic *gen = (Q931mes_Generic *)tmp;
03182                 Q931ie_Cause cause;
03183 
03184                 Q931InitMesGeneric(gen);
03185                 gen->MesType = Q931mes_RELEASE;
03186                 gen->CRV     = Q931CallGetCRV(call);
03187 
03188                 /* TODO: use the original cause */
03189                 cause.IEId = Q931ie_CAUSE;
03190                 cause.Size = sizeof(Q931ie_Cause);
03191                 cause.CodStand = Q931_CODING_ITU;       /* ITU */
03192                 cause.Location = 1;     /* private network */
03193                 cause.Recom    = 1;     /* */
03194                 cause.Value = Q850_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03195 
03196                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *)&cause);
03197 
03198                 Q931Tx32(trunk, 0, gen, gen->Size);
03199         }
03200 
03201         /* Send RESUME CONFIRM (error) indication */
03202         {
03203                 struct Q931_CallEvent event;
03204 
03205                 Q931CallInitEvent(&event);
03206                 event.id    = Q931_EVENT_RESUME_CONFIRM;
03207                 event.type  = Q931_EVENT_TYPE_TIMER;
03208                 event.error = 1;
03209                 event.data.timer.id = Q931_TIMER_T318;
03210 
03211                 /* Send event immediately to layer 4 */
03212                 Q931CallSendEvent(call, &event);
03213         }
03214 
03215         /* Start T308 */
03216         Q931CallStartTimer(call, Q931_TIMER_T308);
03217 
03218         /* => 19: Release request */
03219         Q931CallSetState(call, Q931_U19);
03220 
03221         return Q931E_NO_ERROR;
03222 }
03223 
03224 
03232 L3INT Q931ProcTimeoutT319TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03233 {
03234         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T319 timed out for call %d\n", call->CRV);
03235 
03236         if (Q931CallGetState(call) != Q931_U15) {
03237                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T319 in state %s (wrong state)\n", Q931CallGetStateName(call));
03238                 return Q931E_NO_ERROR;
03239         }
03240 
03241         /* (TODO:) Send SUSPEND CONFIRM (error) indication */
03242         {
03243                 struct Q931_CallEvent event;
03244 
03245                 Q931CallInitEvent(&event);
03246                 event.id    = Q931_EVENT_SUSPEND_CONFIRM;
03247                 event.type  = Q931_EVENT_TYPE_TIMER;
03248                 event.error = 1;
03249                 event.data.timer.id = Q931_TIMER_T319;
03250 
03251                 /* Send event immediately to layer 4 */
03252                 Q931CallSendEvent(call, &event);
03253         }
03254 
03255         /* => 10: Active */
03256         Q931CallSetState(call, Q931_U10);
03257 
03258         return Q931E_NO_ERROR;
03259 }
03260 
03261 
03270 L3INT Q931ProcTimeoutT321TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03271 {
03272 
03273         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T321 timed out for call %d\n", call->CRV);
03274 
03275         /* TODO: ??? */
03276         {
03277                 struct Q931_CallEvent event;
03278 
03279                 Q931CallInitEvent(&event);
03280                 event.id   = Q931_EVENT_TIMEOUT_INDICATION;
03281                 event.type = Q931_EVENT_TYPE_TIMER;
03282                 event.data.timer.id = Q931_TIMER_T321;
03283 
03284                 Q931CallSendEvent(call, &event);
03285         }
03286 
03287         return Q931E_NO_ERROR;
03288 }
03289 
03290 
03299 L3INT Q931ProcTimeoutT322TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
03300 {
03301         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T322 timed out for call %d\n", call->CRV);
03302 
03303         /* TODO: ??? */
03304         {
03305                 struct Q931_CallEvent event;
03306 
03307                 Q931CallInitEvent(&event);
03308                 event.id   = Q931_EVENT_TIMEOUT_INDICATION;
03309                 event.type = Q931_EVENT_TYPE_TIMER;
03310                 event.data.timer.id = Q931_TIMER_T322;
03311 
03312                 /* Send event immediately to layer 4 */
03313                 Q931CallSendEvent(call, &event);
03314         }
03315 
03316         return Q931E_NO_ERROR;
03317 }
03318