libisdn
Q931StateNT.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   FileName:             q931StateNT.c
00004 
00005   Contents:             Q.931 State Engine for NT (Network 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   License/Copyright:
00014 
00015   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
00016   email:janvb@caselaboratories.com
00017 
00018   Redistribution and use in source and binary forms, with or without
00019   modification, are permitted provided that the following conditions are
00020   met:
00021 
00022         * Redistributions of source code must retain the above copyright notice,
00023           this list of conditions and the following disclaimer.
00024         * Redistributions in binary form must reproduce the above copyright notice,
00025           this list of conditions and the following disclaimer in the documentation
00026           and/or other materials provided with the distribution.
00027         * Neither the name of the Case Labs, Ltd nor the names of its contributors
00028           may be used to endorse or promote products derived from this software
00029           without specific prior written permission.
00030 
00031   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00032   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00033   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00034   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00035   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00036   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00037   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00038   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00039   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00040   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00041   POSSIBILITY OF SUCH DAMAGE.
00042 *****************************************************************************/
00043 #include <stdlib.h>
00044 
00045 #include "Q931.h"
00046 #include "Q931priv.h"
00047 #include "Q932.h"
00048 
00049 extern L3INT Q931L4HeaderSpace;
00050 extern struct Q931MessageIE Q931MessageIEs[];
00051 
00052 /*****************************************************************************
00053   Function:             Q931CreateNT
00054 
00055   Description:  Will create the Q931 NT as a Dialect in the stack. The first
00056                                 bulk set up the message handlers, the second bulk the IE
00057                                 encoders/coders, and the last bulk set up the state table.
00058 
00059   Parameters:   i               Dialect index
00060 *****************************************************************************/
00061 void Q931CreateNT(struct Q931Dialect *d)
00062 {
00063         Q931DialectSetName(d, "Q.931 NT");
00064 
00065         /*
00066          * Flags
00067          */
00068         Q931DialectSetFlag(d, 0);
00069 
00070         /*
00071          * Codesets
00072          */
00073         Q931DialectAddCodeset(d, Q931_CODESET_0);
00074 
00075         /*
00076          * Q.931 Message encoder/decoder/handler table
00077          */
00078         Q931DialectSetMesProc(d, Q931mes_ALERTING,             Q931ProcAlertingNT,          Q931Umes_Generic, Q931Pmes_Generic);
00079         Q931DialectSetMesProc(d, Q931mes_CALL_PROCEEDING,      Q931ProcCallProceedingNT,    Q931Umes_Generic, Q931Pmes_Generic);
00080         Q931DialectSetMesProc(d, Q931mes_CONNECT,              Q931ProcConnectNT,           Q931Umes_Generic, Q931Pmes_Generic);
00081         Q931DialectSetMesProc(d, Q931mes_CONNECT_ACKNOWLEDGE,  Q931ProcConnectAckNT,        Q931Umes_Generic, Q931Pmes_Generic);
00082         Q931DialectSetMesProc(d, Q931mes_PROGRESS,             Q931ProcProgressNT,          Q931Umes_Generic, Q931Pmes_Generic);
00083         Q931DialectSetMesProc(d, Q931mes_SETUP,                Q931ProcSetupNT,             Q931Umes_Generic, Q931Pmes_Generic);
00084         Q931DialectSetMesProc(d, Q931mes_SETUP_ACKNOWLEDGE,    Q931ProcSetupAckNT,          Q931Umes_Generic, Q931Pmes_Generic);
00085         Q931DialectSetMesProc(d, Q931mes_RESUME,               Q931ProcResumeNT,            Q931Umes_Generic, Q931Pmes_Generic);
00086         Q931DialectSetMesProc(d, Q931mes_RESUME_ACKNOWLEDGE,   Q931ProcResumeAckNT,         Q931Umes_Generic, Q931Pmes_Generic);
00087         Q931DialectSetMesProc(d, Q931mes_RESUME_REJECT,        Q931ProcResumeRejectNT,      Q931Umes_Generic, Q931Pmes_Generic);
00088         Q931DialectSetMesProc(d, Q931mes_SUSPEND,              Q931ProcSuspendNT,           Q931Umes_Generic, Q931Pmes_Generic);
00089         Q931DialectSetMesProc(d, Q931mes_SUSPEND_ACKNOWLEDGE,  Q931ProcSuspendAckNT,        Q931Umes_Generic, Q931Pmes_Generic);
00090         Q931DialectSetMesProc(d, Q931mes_SUSPEND_REJECT,       Q931ProcSuspendRejectNT,     Q931Umes_Generic, Q931Pmes_Generic);
00091         Q931DialectSetMesProc(d, Q931mes_USER_INFORMATION,     Q931ProcUserInformationNT,   Q931Umes_Generic, Q931Pmes_Generic);
00092         Q931DialectSetMesProc(d, Q931mes_DISCONNECT,           Q931ProcDisconnectNT,        Q931Umes_Generic, Q931Pmes_Generic);
00093         Q931DialectSetMesProc(d, Q931mes_RELEASE,              Q931ProcReleaseNT,           Q931Umes_Generic, Q931Pmes_Generic);
00094         Q931DialectSetMesProc(d, Q931mes_RELEASE_COMPLETE,     Q931ProcReleaseCompleteNT,   Q931Umes_Generic, Q931Pmes_Generic);
00095         Q931DialectSetMesProc(d, Q931mes_RESTART,              Q931ProcRestartNT,           Q931Umes_Generic, Q931Pmes_Generic);
00096         Q931DialectSetMesProc(d, Q931mes_RESTART_ACKNOWLEDGE,  Q931ProcRestartAckNT,        Q931Umes_Generic, Q931Pmes_Generic);
00097         Q931DialectSetMesProc(d, Q931mes_CONGESTION_CONTROL,   Q931ProcCongestionControlNT, Q931Umes_Generic, Q931Pmes_Generic);
00098         Q931DialectSetMesProc(d, Q931mes_INFORMATION,          Q931ProcInformationNT,       Q931Umes_Generic, Q931Pmes_Generic);
00099         Q931DialectSetMesProc(d, Q931mes_NOTIFY,               Q931ProcNotifyNT,            Q931Umes_Generic, Q931Pmes_Generic);
00100         Q931DialectSetMesProc(d, Q931mes_STATUS,               Q931ProcStatusNT,            Q931Umes_Generic, Q931Pmes_Generic);
00101         Q931DialectSetMesProc(d, Q931mes_STATUS_ENQUIRY,       Q931ProcStatusEnquiryNT,     Q931Umes_Generic, Q931Pmes_Generic);
00102         Q931DialectSetMesProc(d, Q931mes_SEGMENT,              Q931ProcSegmentNT,           Q931Umes_Generic, Q931Pmes_Generic);
00103 
00104         /*
00105          * Q.932
00106          */
00107         Q931DialectSetMesProc(d, Q932mes_FACILITY,             Q932ProcFacilityNT,          Q932Umes_Facility,          Q932Pmes_Facility);
00108         Q931DialectSetMesProc(d, Q932mes_HOLD,                 Q932ProcHoldNT,              Q932Umes_Hold,              Q932Pmes_Hold);
00109         Q931DialectSetMesProc(d, Q932mes_HOLD_ACKNOWLEDGE,     Q932ProcHoldAckNT,           Q932Umes_HoldAck,           Q932Pmes_HoldAck);
00110         Q931DialectSetMesProc(d, Q932mes_HOLD_REJECT,          Q932ProcHoldRejectNT,        Q932Umes_HoldReject,        Q932Pmes_HoldReject);
00111         Q931DialectSetMesProc(d, Q932mes_REGISTER,             Q932ProcRegisterNT,          Q932Umes_Register,          Q932Pmes_Register);
00112         Q931DialectSetMesProc(d, Q932mes_RETRIEVE,             Q932ProcRetrieveNT,          Q932Umes_Retrieve,          Q932Pmes_Retrieve);
00113         Q931DialectSetMesProc(d, Q932mes_RETRIEVE_ACKNOWLEDGE, Q932ProcRetrieveAckNT,       Q932Umes_RetrieveAck,       Q932Pmes_RetrieveAck);
00114         Q931DialectSetMesProc(d, Q932mes_RETRIEVE_REJECT,      Q932ProcRetrieveRejectNT,    Q932Umes_RetrieveReject,    Q932Pmes_RetrieveReject);
00115 
00116 
00117         /*
00118          * Unknown / Invalid (Unexpected) Message handler
00119          */
00120         Q931DialectSetUnknownMesProc(d, Q931ProcUnknownMessage);
00121         Q931DialectSetInvalidMesProc(d, Q931ProcUnexpectedMessage);
00122 
00123 
00124         /*
00125          * Q.931 IE encoder/decoder table
00126          */
00127         Q931DialectSetIEProc(d, Q931ie_SEGMENTED_MESSAGE,                Q931Pie_Segment,     Q931Uie_Segment,      Q931Die_Segment);
00128         Q931DialectSetIEProc(d, Q931ie_BEARER_CAPABILITY,                Q931Pie_BearerCap,   Q931Uie_BearerCap,    Q931Die_BearerCap);
00129         Q931DialectSetIEProc(d, Q931ie_CAUSE,                            Q931Pie_Cause,       Q931Uie_Cause,        Q931Die_Cause);
00130         Q931DialectSetIEProc(d, Q931ie_CALL_IDENTITY,                    Q931Pie_CallID,      Q931Uie_CallID,       Q931Die_CallID);
00131         Q931DialectSetIEProc(d, Q931ie_CALL_STATE,                       Q931Pie_CallState,   Q931Uie_CallState,    Q931Die_CallState);
00132         Q931DialectSetIEProc(d, Q931ie_CHANNEL_IDENTIFICATION,           Q931Pie_ChanID,      Q931Uie_ChanID,       Q931Die_ChanID);
00133         Q931DialectSetIEProc(d, Q931ie_PROGRESS_INDICATOR,               Q931Pie_ProgInd,     Q931Uie_ProgInd,      Q931Die_ProgInd);
00134         Q931DialectSetIEProc(d, Q931ie_NETWORK_SPECIFIC_FACILITIES,      Q931Pie_NetFac,      Q931Uie_NetFac,       Q931Die_Generic);
00135         Q931DialectSetIEProc(d, Q931ie_NOTIFICATION_INDICATOR,           Q931Pie_NotifInd,    Q931Uie_NotifInd,     Q931Die_Generic);
00136         Q931DialectSetIEProc(d, Q931ie_DISPLAY,                          Q931Pie_Display,     Q931Uie_Display,      Q931Die_Display);
00137         Q931DialectSetIEProc(d, Q931ie_DATETIME,                         Q931Pie_DateTime,    Q931Uie_DateTime,     Q931Die_DateTime);
00138         Q931DialectSetIEProc(d, Q931ie_KEYPAD_FACILITY,                  Q931Pie_KeypadFac,   Q931Uie_KeypadFac,    Q931Die_Generic);
00139         Q931DialectSetIEProc(d, Q931ie_SIGNAL,                           Q931Pie_Signal,      Q931Uie_Signal,       Q931Die_Signal);
00140         Q931DialectSetIEProc(d, Q931ie_TRANSIT_DELAY_SELECTION_AND_IND,  Q931Pie_TransNetSel, Q931Uie_TransNetSel,  Q931Die_Generic);
00141         Q931DialectSetIEProc(d, Q931ie_CALLING_PARTY_NUMBER,             Q931Pie_CallingNum,  Q931Uie_CallingNum,   Q931Die_CallingNum);
00142         Q931DialectSetIEProc(d, Q931ie_CALLING_PARTY_SUBADDRESS,         Q931Pie_CallingSub,  Q931Uie_CallingSub,   Q931Die_CallingSub);
00143         Q931DialectSetIEProc(d, Q931ie_CALLED_PARTY_NUMBER,              Q931Pie_CalledNum,   Q931Uie_CalledNum,    Q931Die_CalledNum);
00144         Q931DialectSetIEProc(d, Q931ie_CALLED_PARTY_SUBADDRESS,          Q931Pie_CalledSub,   Q931Uie_CalledSub,    Q931Die_CalledSub);
00145         Q931DialectSetIEProc(d, Q931ie_TRANSIT_NETWORK_SELECTION,        Q931Pie_TransNetSel, Q931Uie_TransNetSel,  Q931Die_Generic);
00146         Q931DialectSetIEProc(d, Q931ie_RESTART_INDICATOR,                Q931Pie_RestartInd,  Q931Uie_RestartInd,   Q931Die_RestartInd);
00147         Q931DialectSetIEProc(d, Q931ie_LOW_LAYER_COMPATIBILITY,          Q931Pie_LLComp,      Q931Uie_LLComp,       Q931Die_LLComp);
00148         Q931DialectSetIEProc(d, Q931ie_HIGH_LAYER_COMPATIBILITY,         Q931Pie_HLComp,      Q931Uie_HLComp,       Q931Die_HLComp);
00149         Q931DialectSetIEProc(d, Q931ie_USER_USER,                        Q931Pie_UserUser,    Q931Uie_UserUser,     Q931Die_UserUser);
00150         Q931DialectSetIEProc(d, Q931ie_SENDING_COMPLETE,                 Q931Pie_SendComplete,Q931Uie_SendComplete, Q931Die_SendComplete);
00151         Q931DialectSetIEProc(d, Q931ie_CONNECTED_NUMBER,                 Q931Pie_Generic,     Q931Uie_Generic,      Q931Die_Generic);
00152         Q931DialectSetIEProc(d, Q931ie_CONNECTED_SUBADDRESS,             Q931Pie_Generic,     Q931Uie_Generic,      Q931Die_Generic);
00153 
00154         /*
00155          * Q.932
00156          */
00157         Q931DialectSetIEProc(d, Q932ie_FACILITY,                       Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00158         Q931DialectSetIEProc(d, Q932ie_EXTENDED_FACILITY,              Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00159         Q931DialectSetIEProc(d, Q932ie_FEATURE_ACTIVATION,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00160         Q931DialectSetIEProc(d, Q932ie_FEATURE_INDICATION,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00161         Q931DialectSetIEProc(d, Q932ie_SERVICE_PROFILE_IDENTIFICATION, Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00162         Q931DialectSetIEProc(d, Q932ie_ENDPOINT_IDENTIFIER,            Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00163 
00164         /*
00165          * Q.952
00166          */
00167         Q931DialectSetIEProc(d, Q931ie_REDIRECTING_NUMBER,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00168         Q931DialectSetIEProc(d, Q931ie_REDIRECTION_NUMBER,             Q931Pie_Generic,     Q931Uie_Generic,    Q931Die_Generic);
00169 
00170         /*
00171          * State -> Allowed message table
00172          */
00173         /* Any State */
00174         Q931DialectAddStateEntry(d, Q931_NANY, Q931mes_STATUS,           MSGF_FROM_BOTH);
00175         Q931DialectAddStateEntry(d, Q931_NANY, Q931mes_STATUS_ENQUIRY,   MSGF_FROM_L2);
00176         Q931DialectAddStateEntry(d, Q931_UANY, Q931mes_RESTART,             MSGF_FROM_BOTH);
00177         Q931DialectAddStateEntry(d, Q931_UANY, Q931mes_RESTART_ACKNOWLEDGE, MSGF_FROM_BOTH);
00178 
00179         /* State 0 Idle */
00180         Q931DialectAddStateEntry(d, Q931_N0, Q931mes_SETUP,            MSGF_FROM_BOTH);
00181         Q931DialectAddStateEntry(d, Q931_N0, Q931mes_RELEASE,          MSGF_FROM_BOTH);
00182         Q931DialectAddStateEntry(d, Q931_N0, Q931mes_RELEASE_COMPLETE, MSGF_FROM_BOTH);
00183         Q931DialectAddStateEntry(d, Q931_N0, Q931mes_RESUME,           MSGF_FROM_L2);
00184 
00185         /* State 1 Call Initiating */
00186         Q931DialectAddStateEntry(d, Q931_N1, Q931mes_DISCONNECT,        MSGF_FROM_BOTH);
00187         Q931DialectAddStateEntry(d, Q931_N1, Q931mes_SETUP_ACKNOWLEDGE, MSGF_FROM_L4);
00188         Q931DialectAddStateEntry(d, Q931_N1, Q931mes_RELEASE_COMPLETE,  MSGF_FROM_L4);
00189         Q931DialectAddStateEntry(d, Q931_N1, Q931mes_CALL_PROCEEDING,   MSGF_FROM_L4);
00190         Q931DialectAddStateEntry(d, Q931_N1, Q931mes_ALERTING,          MSGF_FROM_L4); /* ITU-T Q.931 Annex D */
00191         Q931DialectAddStateEntry(d, Q931_N1, Q931mes_CONNECT,           MSGF_FROM_L4); /* ITU-T Q.931 Annex D */
00192 
00193         /* State 2 Overlap Sending */
00194         Q931DialectAddStateEntry(d, Q931_N2, Q931mes_DISCONNECT,      MSGF_FROM_BOTH);
00195         Q931DialectAddStateEntry(d, Q931_N2, Q931mes_INFORMATION,     MSGF_FROM_BOTH);
00196         Q931DialectAddStateEntry(d, Q931_N2, Q931mes_CALL_PROCEEDING, MSGF_FROM_L4);
00197         Q931DialectAddStateEntry(d, Q931_N2, Q931mes_ALERTING,        MSGF_FROM_L4);
00198         Q931DialectAddStateEntry(d, Q931_N2, Q931mes_PROGRESS,        MSGF_FROM_L4);
00199         Q931DialectAddStateEntry(d, Q931_N2, Q931mes_CONNECT,         MSGF_FROM_L4);
00200 /*      Q931DialectAddStateEntry(d, Q931_N2, Q931mes_RELEASE,         MSGF_FROM_L4); ??? */
00201 
00202         /* State 3 Outgoing Call Proceeding */
00203         Q931DialectAddStateEntry(d, Q931_N3, Q931mes_DISCONNECT,     MSGF_FROM_BOTH);
00204         Q931DialectAddStateEntry(d, Q931_N3, Q931mes_PROGRESS,       MSGF_FROM_L4);
00205         Q931DialectAddStateEntry(d, Q931_N3, Q931mes_ALERTING,       MSGF_FROM_L4);
00206         Q931DialectAddStateEntry(d, Q931_N3, Q931mes_CONNECT,        MSGF_FROM_L4);
00207 /*      Q931DialectAddStateEntry(d, Q931_N3, Q931mes_RELEASE,        MSGF_FROM_L4); ??? */
00208         Q931DialectAddStateEntry(d, Q931_N3, Q931mes_INFORMATION,    MSGF_FROM_BOTH);
00209 
00210         /* State 4 Call Delivered */
00211         Q931DialectAddStateEntry(d, Q931_N4, Q931mes_DISCONNECT,     MSGF_FROM_BOTH);
00212         Q931DialectAddStateEntry(d, Q931_N4, Q931mes_CONNECT,        MSGF_FROM_L4);
00213         Q931DialectAddStateEntry(d, Q931_N4, Q931mes_PROGRESS,       MSGF_FROM_L4);
00214         Q931DialectAddStateEntry(d, Q931_N4, Q931mes_INFORMATION,    MSGF_FROM_BOTH);
00215 
00216         /* State 6 Call Present */
00217         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_CONNECT,           MSGF_FROM_L2);
00218         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_RELEASE_COMPLETE,  MSGF_FROM_L2);
00219         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_SETUP_ACKNOWLEDGE, MSGF_FROM_L2);
00220         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_INFORMATION,       MSGF_FROM_L4);
00221         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_ALERTING,          MSGF_FROM_L2);
00222         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_CALL_PROCEEDING,   MSGF_FROM_L2);
00223         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_RELEASE,           MSGF_FROM_L2);
00224         Q931DialectAddStateEntry(d, Q931_N6, Q931mes_DISCONNECT,        MSGF_FROM_L2);
00225 
00226         /* State 7 Call Received */
00227         Q931DialectAddStateEntry(d, Q931_N7, Q931mes_CONNECT,        MSGF_FROM_L2);
00228         Q931DialectAddStateEntry(d, Q931_N7, Q931mes_DISCONNECT,     MSGF_FROM_BOTH);
00229         Q931DialectAddStateEntry(d, Q931_N7, Q931mes_INFORMATION,    MSGF_FROM_BOTH);
00230 
00231         /* State 8 Connect request */
00232         Q931DialectAddStateEntry(d, Q931_N8, Q931mes_CONNECT_ACKNOWLEDGE, MSGF_FROM_L4);
00233         Q931DialectAddStateEntry(d, Q931_N8, Q931mes_DISCONNECT,          MSGF_FROM_BOTH);
00234         Q931DialectAddStateEntry(d, Q931_N8, Q931mes_INFORMATION,         MSGF_FROM_BOTH);
00235 
00236         /* State 9 Incoming Call Proceeding */
00237         Q931DialectAddStateEntry(d, Q931_N9, Q931mes_CONNECT,        MSGF_FROM_L2);
00238         Q931DialectAddStateEntry(d, Q931_N9, Q931mes_ALERTING,       MSGF_FROM_L2);
00239         Q931DialectAddStateEntry(d, Q931_N9, Q931mes_PROGRESS,       MSGF_FROM_L2);
00240         Q931DialectAddStateEntry(d, Q931_N9, Q931mes_DISCONNECT,     MSGF_FROM_BOTH);
00241         Q931DialectAddStateEntry(d, Q931_N9, Q931mes_INFORMATION,    MSGF_FROM_BOTH);
00242 
00243         /* State 10 Active */
00244         Q931DialectAddStateEntry(d, Q931_N10, Q931mes_DISCONNECT,          MSGF_FROM_BOTH);
00245         Q931DialectAddStateEntry(d, Q931_N10, Q931mes_CONNECT_ACKNOWLEDGE, MSGF_FROM_L2);
00246         Q931DialectAddStateEntry(d, Q931_N10, Q931mes_SUSPEND,             MSGF_FROM_L2);
00247         Q931DialectAddStateEntry(d, Q931_N10, Q931mes_NOTIFY,              MSGF_FROM_BOTH);
00248         Q931DialectAddStateEntry(d, Q931_N10, Q931mes_INFORMATION,         MSGF_FROM_BOTH);
00249         Q931DialectAddStateEntry(d, Q931_N10, Q932mes_FACILITY,            MSGF_FROM_BOTH);
00250 
00251         /* State 11 Disconnect Request */
00252         Q931DialectAddStateEntry(d, Q931_N11, Q931mes_RELEASE,        MSGF_FROM_L4);
00253         Q931DialectAddStateEntry(d, Q931_N11, Q931mes_DISCONNECT,     MSGF_FROM_L2);
00254 /*      Q931DialectAddStateEntry(d, Q931_N11, Q931mes_NOTIFY,         MSGF_FROM_L2); ??? */
00255         Q931DialectAddStateEntry(d, Q931_N11, Q931mes_INFORMATION,    MSGF_FROM_BOTH);
00256 
00257         /* State 12 Disconnect Ind */
00258         Q931DialectAddStateEntry(d, Q931_N12, Q931mes_RELEASE,        MSGF_FROM_L2);
00259         Q931DialectAddStateEntry(d, Q931_N12, Q931mes_DISCONNECT,     MSGF_FROM_L2);
00260         Q931DialectAddStateEntry(d, Q931_N12, Q931mes_INFORMATION,    MSGF_FROM_BOTH);
00261 
00262         /* State 15 Suspend Request */
00263         Q931DialectAddStateEntry(d, Q931_N15, Q931mes_SUSPEND_ACKNOWLEDGE, MSGF_FROM_L4);
00264         Q931DialectAddStateEntry(d, Q931_N15, Q931mes_SUSPEND_REJECT,      MSGF_FROM_L4);
00265         Q931DialectAddStateEntry(d, Q931_N15, Q931mes_DISCONNECT,          MSGF_FROM_BOTH);
00266 /*      Q931DialectAddStateEntry(d, Q931_N15, Q931mes_RELEASE,             MSGF_FROM_L2); ??? */
00267         Q931DialectAddStateEntry(d, Q931_N15, Q931mes_INFORMATION,         MSGF_FROM_BOTH);
00268 
00269         /* State 17 Resume Request */
00270         Q931DialectAddStateEntry(d, Q931_N17, Q931mes_RESUME_ACKNOWLEDGE,  MSGF_FROM_L4);
00271         Q931DialectAddStateEntry(d, Q931_N17, Q931mes_RESUME_REJECT,       MSGF_FROM_L4);
00272         Q931DialectAddStateEntry(d, Q931_N17, Q931mes_DISCONNECT,          MSGF_FROM_BOTH);
00273 
00274         /* State 19 Release Request */
00275         Q931DialectAddStateEntry(d, Q931_N19, Q931mes_RELEASE_COMPLETE,    MSGF_FROM_L2);
00276         Q931DialectAddStateEntry(d, Q931_N19, Q931mes_RELEASE,             MSGF_FROM_L2);
00277 
00278         /* State 25 Overlap Receiving */
00279 /*      Q931DialectAddStateEntry(d, Q931_N25, Q931mes_SETUP_ACKNOWLEDGE,   MSGF_FROM_L4); */
00280 /*      Q931DialectAddStateEntry(d, Q931_N25, Q931mes_RELEASE_COMPLETE,    MSGF_FROM_L4); */
00281         Q931DialectAddStateEntry(d, Q931_N25, Q931mes_CALL_PROCEEDING,     MSGF_FROM_L2);
00282         Q931DialectAddStateEntry(d, Q931_N25, Q931mes_ALERTING,            MSGF_FROM_L2);
00283         Q931DialectAddStateEntry(d, Q931_N25, Q931mes_PROGRESS,            MSGF_FROM_L2);
00284         Q931DialectAddStateEntry(d, Q931_N25, Q931mes_CONNECT,             MSGF_FROM_L2);
00285         Q931DialectAddStateEntry(d, Q931_N25, Q931mes_INFORMATION,         MSGF_FROM_L4);
00286         Q931DialectAddStateEntry(d, Q931_N25, Q931mes_DISCONNECT,          MSGF_FROM_BOTH);
00287 
00288 
00289         /*
00290          * Timer default values
00291          */
00292         Q931DialectSetTimerProcAll(d, Q931TimeoutDummy);
00293 
00294         /* Per-timer timeout callbacks, per-mode for now, until i know if they can be shared (and which) */
00295 #if __WIP__
00296         Q931DialectSetTimerProc(d, Q931_TIMER_T301, Q931ProcTimeoutT301NT);
00297         Q931DialectSetTimerProc(d, Q931_TIMER_T302, Q931ProcTimeoutT302NT);
00298 #endif
00299         Q931DialectSetTimerProc(d, Q931_TIMER_T303, Q931ProcTimeoutT303NT);
00300 #if __WIP__
00301         Q931DialectSetTimerProc(d, Q931_TIMER_T304, Q931ProcTimeoutT304NT);
00302         Q931DialectSetTimerProc(d, Q931_TIMER_T305, Q931ProcTimeoutT305NT);
00303         Q931DialectSetTimerProc(d, Q931_TIMER_T306, Q931ProcTimeoutT305NT);
00304         Q931DialectSetTimerProc(d, Q931_TIMER_T307, Q931ProcTimeoutT305NT);
00305         Q931DialectSetTimerProc(d, Q931_TIMER_T308, Q931ProcTimeoutT308NT);
00306         Q931DialectSetTimerProc(d, Q931_TIMER_T309, Q931ProcTimeoutT309NT);
00307         Q931DialectSetTimerProc(d, Q931_TIMER_T310, Q931ProcTimeoutT310NT);
00308         Q931DialectSetTimerProc(d, Q931_TIMER_T312, Q931ProcTimeoutT311NT);
00309         Q931DialectSetTimerProc(d, Q931_TIMER_T314, Q931ProcTimeoutT314NT);
00310         Q931DialectSetTimerProc(d, Q931_TIMER_T316, Q931ProcTimeoutT316NT);
00311         Q931DialectSetTimerProc(d, Q931_TIMER_T317, Q931ProcTimeoutT317NT);
00312         Q931DialectSetTimerProc(d, Q931_TIMER_T320, Q931ProcTimeoutT319NT);
00313         Q931DialectSetTimerProc(d, Q931_TIMER_T321, Q931ProcTimeoutT321NT);
00314         Q931DialectSetTimerProc(d, Q931_TIMER_T322, Q931ProcTimeoutT322NT);
00315 #endif
00316 
00317         Q931DialectSetTimeout(d, Q931_TIMER_T301, 180000);      /* T301: 180s */
00318         Q931DialectSetTimeout(d, Q931_TIMER_T302,  15000);      /* T302:  15s */
00319         Q931DialectSetTimeout(d, Q931_TIMER_T303,   4000);      /* T303:   4s */
00320         Q931DialectSetTimeout(d, Q931_TIMER_T304,  20000);      /* T304:  20s */
00321         Q931DialectSetTimeout(d, Q931_TIMER_T305,  30000);      /* T305:  30s */
00322         Q931DialectSetTimeout(d, Q931_TIMER_T306,  30000);      /* T306:  30s */
00323         Q931DialectSetTimeout(d, Q931_TIMER_T307, 180000);      /* T307: 180s */
00324         Q931DialectSetTimeout(d, Q931_TIMER_T308,   4000);      /* T308:   4s */
00325         Q931DialectSetTimeout(d, Q931_TIMER_T309,  60000);      /* T309:  60s */
00326         Q931DialectSetTimeout(d, Q931_TIMER_T310,  10000);      /* T310:  10s */
00327         Q931DialectSetTimeout(d, Q931_TIMER_T312,  12000);      /* T312:  12s */
00328         Q931DialectSetTimeout(d, Q931_TIMER_T314,   4000);      /* T314:   4s */
00329         Q931DialectSetTimeout(d, Q931_TIMER_T316, 120000);      /* T316: 120s */
00330         Q931DialectSetTimeout(d, Q931_TIMER_T317,  90000);      /* T317:  90s */
00331         Q931DialectSetTimeout(d, Q931_TIMER_T320,  30000);      /* T320:  30s */
00332         Q931DialectSetTimeout(d, Q931_TIMER_T321,  30000);      /* T321:  30s */
00333         Q931DialectSetTimeout(d, Q931_TIMER_T322,   4000);      /* T322:   4s */
00334 
00335         /*
00336          * Q.931 message <-> ie table
00337          */
00338         Q931DialectSetMesIEMap(d, Q931MessageIEs);
00339 }
00340 
00341 /*****************************************************************************
00342 
00343   Function:             Q931ProcAlertingNT
00344 
00345 *****************************************************************************/
00346 L3INT Q931ProcAlertingNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00347 {
00348         L3INT ret = Q931E_NO_ERROR;
00349 #if 0
00350         /* Find the call using CRV (TODO: move one level up,
00351          * change function signature(s) to use Q931_Call * instead of
00352          * Q931_TrunkInfo_t *)
00353          */
00354         call = Q931GetCallByCRV(trunk, msg->CRV);
00355         if (!call)
00356                 return Q931E_INVALID_CRV;
00357 
00358         /* check if message is valid in this state (TODO: move one level up) */
00359         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00360                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00361                 return Q931E_UNEXPECTED_MESSAGE;
00362         }
00363 #endif
00364         switch (from) {
00365         case Q931_MSG_FROM_L4:
00366                 switch (Q931CallGetState(call)) {
00367                 case Q931_N2:  /* Alerting request */
00368                         /* Stop T302 */
00369                         Q931CallStopTimer(call, Q931_TIMER_T302);
00370                 case Q931_N3:
00371                         /* Send ALERTING */
00372                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00373 
00374                         /* => N4 Call delivered */
00375                         Q931CallSetState(call, Q931_N4);
00376                         break;
00377                 default:
00378                         break;
00379                 }
00380                 break;
00381         case Q931_MSG_FROM_L2:
00382                 switch (Q931CallGetState(call)) {
00383                 case Q931_N6:
00384                         /* Stop T303 */
00385                         Q931CallStopTimer(call, Q931_TIMER_T303);
00386 
00387                         /* => N7 Call received */
00388                         Q931CallSetState(call, Q931_N7);
00389 
00390                         /* TODO: Invoke new event CB: Alerting indication */
00391                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00392 
00393                         /* Start T301 */
00394                         Q931CallStartTimer(call, Q931_TIMER_T301);
00395                         break;
00396 
00397                 case Q931_N9:
00398                         /* Stop T310 */
00399                         Q931CallStopTimer(call, Q931_TIMER_T310);
00400 
00401                         /* => N7 Call received */
00402                         Q931CallSetState(call, Q931_N7);
00403 
00404                         /* TODO: Invoke new event CB: Alerting indication */
00405                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00406 
00407                         /* Start T301 */
00408                         Q931CallStartTimer(call, Q931_TIMER_T301);
00409                         break;
00410 
00411                 default:
00412                         break;
00413                 }
00414                 break;
00415         default:
00416                 ret = Q931E_INTERNAL;
00417         }
00418         return ret;
00419 }
00420 
00421 /*****************************************************************************
00422 
00423   Function:             Q931ProcCallProceedingNT
00424 
00425 *****************************************************************************/
00426 L3INT Q931ProcCallProceedingNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00427 {
00428         L3INT ret = Q931E_NO_ERROR;
00429 #if 0
00430         /* Find the call using CRV (TODO: move one level up,
00431          * change function signature(s) to use Q931_Call * instead of
00432          * Q931_TrunkInfo_t *)
00433          */
00434         call = Q931GetCallByCRV(trunk, msg->CRV);
00435         if (!call)
00436                 return Q931E_INVALID_CRV;
00437 
00438         /* check if message is valid in this state (TODO: move one level up) */
00439         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00440                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00441                 return Q931E_UNEXPECTED_MESSAGE;
00442         }
00443 #endif
00444         switch (from) {
00445         case Q931_MSG_FROM_L4:
00446                 switch (Q931CallGetState(call)) {
00447                 case Q931_N1:   /* Call proceeding request */
00448                         /* Send CALL PROCEEDING */
00449                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00450 
00451                         /* => N3 Outgoing call proceeding */
00452                         Q931CallSetState(call, Q931_N3);
00453                         break;
00454 
00455                 case Q931_N2:
00456                         /* Stop T302 */
00457                         Q931CallStopTimer(call, Q931_TIMER_T302);
00458 
00459                         /* Send CALL PROCEEDING */
00460                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00461 
00462                         /* => N3 Outgoing call proceeding */
00463                         Q931CallSetState(call, Q931_N3);
00464                         break;
00465                 default:
00466                         break;
00467                 }
00468                 break;
00469         case Q931_MSG_FROM_L2:
00470                 switch (Q931CallGetState(call)) {
00471                 case Q931_N6:
00472                         /* Stop T303 */
00473                         Q931CallStopTimer(call, Q931_TIMER_T303);
00474 
00475                         /* Start T310 */
00476                         Q931CallStartTimer(call, Q931_TIMER_T310);
00477 
00478                         /* => N9 Incoming call proceeding */
00479                         Q931CallSetState(call, Q931_N9);
00480 
00481                         /* TODO: Invoke new event CB: Proceeding indication */
00482                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00483                         break;
00484                 default:
00485                         break;
00486                 }
00487                 break;
00488         default:
00489                 ret = Q931E_INTERNAL;
00490         }
00491         return ret;
00492 }
00493 
00494 /*****************************************************************************
00495 
00496   Function:             Q931ProcConnectNT
00497 
00498 *****************************************************************************/
00499 L3INT Q931ProcConnectNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00500 {
00501         L3INT ret = Q931E_NO_ERROR;
00502 #if 0
00503         /* Find the call using CRV */
00504         call = Q931GetCallByCRV(trunk, msg->CRV);
00505         if (!call)
00506                 return Q931E_INVALID_CRV;
00507 
00508         /* check if message is valid in this state */
00509         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00510                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00511                 return Q931E_UNEXPECTED_MESSAGE;
00512         }
00513 #endif
00514         switch (from) {
00515         case Q931_MSG_FROM_L4:
00516                 switch (Q931CallGetState(call)) {
00517                 case Q931_N2:   /* Setup response */
00518                         /* Stop T302 */
00519                         Q931CallStopTimer(call, Q931_TIMER_T302);
00520 
00521                 case Q931_N3:
00522                 case Q931_N4:
00523                         /* Send CONNECT */
00524                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00525 
00526                         /* => N10 Active */
00527                         Q931CallSetState(call, Q931_N10);
00528                         break;
00529                 default:
00530                         break;
00531                 }
00532                 break;
00533         case Q931_MSG_FROM_L2:
00534                 switch (Q931CallGetState(call)) {
00535                 case Q931_N6:
00536                         /* Stop T303 */
00537                         Q931CallStopTimer(call, Q931_TIMER_T303);
00538 
00539                 case Q931_N7:
00540                         /* Stop T301 */
00541                         Q931CallStopTimer(call, Q931_TIMER_T301);
00542 
00543                 case Q931_N9:
00544                         /* Stop T310 */
00545                         Q931CallStopTimer(call, Q931_TIMER_T310);
00546 
00547                         /* => N8 Connect request */
00548                         Q931CallSetState(call, Q931_N8);
00549 
00550                         /* TODO: Send Setup confirm */
00551                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00552                         break;
00553 
00554                 default:
00555                         break;
00556                 }
00557                 break;
00558         default:
00559                 ret = Q931E_INTERNAL;
00560         }
00561         return ret;
00562 }
00563 
00564 /*****************************************************************************
00565 
00566   Function:             Q931ProcConnectAckNT
00567 
00568 *****************************************************************************/
00569 L3INT Q931ProcConnectAckNT(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                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00581                 return Q931E_UNEXPECTED_MESSAGE;
00582         }
00583 #endif
00584         switch (from) {
00585         case Q931_MSG_FROM_L4:
00586                 switch (Q931CallGetState(call)) {
00587                 case Q931_N8:   /* Setup comp request */
00588                         /* Send CONNECT ACKNOWLEDGE */
00589                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00590 
00591                         /* => N10 Active */
00592                         Q931CallSetState(call, Q931_N10);
00593                         break;
00594                 default:
00595                         break;
00596                 }
00597                 break;
00598         case Q931_MSG_FROM_L2:
00599                 switch (Q931CallGetState(call)) {
00600                 case Q931_N10:
00601                         /* == N10 Active */
00602                         break;
00603 
00604                 default:
00605                         break;
00606                 }
00607                 break;
00608         default:
00609                 ret = Q931E_INTERNAL;
00610         }
00611         return ret;
00612 }
00613 
00614 /*****************************************************************************
00615 
00616   Function:             Q931ProcProgressNT
00617 
00618 *****************************************************************************/
00619 L3INT Q931ProcProgressNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00620 {
00621         L3INT ret = Q931E_NO_ERROR;
00622 #if 0
00623         /* Find the call using CRV */
00624         call = Q931GetCallByCRV(trunk, msg->CRV);
00625         if (!call)
00626                 return Q931E_INVALID_CRV;
00627 
00628         /* check if message is valid in this state */
00629         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00630                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00631                 return Q931E_UNEXPECTED_MESSAGE;
00632         }
00633 #endif
00634         switch (from) {
00635         case Q931_MSG_FROM_L4:
00636                 switch (Q931CallGetState(call)) {
00637                 case Q931_N2:   /* Progress request */
00638                         /* Stop T302 */
00639                         Q931CallStopTimer(call, Q931_TIMER_T302);
00640 
00641                 case Q931_N3:
00642                 case Q931_N4:
00643                         /* Send PROGRESS */
00644                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00645 
00646                         /* == N2 Overlap sending
00647                          * == N3 Outgoing call proceeding
00648                          * == N4 Call delivered
00649                          */
00650                         break;
00651                 default:
00652                         break;
00653                 }
00654                 break;
00655         case Q931_MSG_FROM_L2:
00656                 switch (Q931CallGetState(call)) {
00657                 case Q931_N9:
00658                         /* Send proceeding indication */
00659                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00660 
00661                         /* == N9 Incoming call proceeding */
00662                         break;
00663                 default:
00664                         break;
00665                 }
00666                 break;
00667         default:
00668                 ret = Q931E_INTERNAL;
00669         }
00670         return ret;
00671 }
00672 
00673 /*****************************************************************************
00674 
00675   Function:             Q931ProcSetupNT
00676 
00677   Description:  Process a SETUP message.
00678 
00679  *****************************************************************************/
00680 L3INT Q931ProcSetupNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00681 {
00682         L3INT ret = Q931E_NO_ERROR;
00683 #if 0
00684         /* NOTE: handled by upper layers */
00685 
00686         /* Find the call using CRV */
00687         if (msg->CRV) {
00688                 call = Q931GetCallByCRV(trunk, msg->CRV);
00689                 if (call && Q931CallGetState(call) != Q931_N0) {
00690                         Q931Log(trunk, Q931_LOG_DEBUG, "SETUP on existing call\n");
00691 
00692                         /* Reject SETUP on existing calls */
00693                         Q931Disconnect(trunk, from, msg->CRV, 81);
00694                         return Q931E_UNEXPECTED_MESSAGE;
00695                 }
00696         }
00697 
00698         if (call) {
00699                 /* check if message is valid in this state */
00700                 if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00701                         Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00702                         return Q931E_UNEXPECTED_MESSAGE;
00703                 }
00704         }
00705 #endif
00706         switch (from) {
00707         case Q931_MSG_FROM_L4:          /* outgoing call (Setup request) */
00708                 if (!call) {
00709                         /* CR selection */
00710                         call = Q931CallNew(trunk);
00711                         if (!call) {
00712                                 return Q931E_INTERNAL;
00713                         }
00714                         msg->CRV = Q931CallGetCRV(call);
00715                 }
00716 
00717                 /* Broadcast SETUP message if in PTMP mode */
00718                 ret = Q931Tx32(trunk, Q931_IS_PTP(trunk) ? 0 : 1, msg, msg->Size);
00719                 if (ret)
00720                         return ret;
00721 
00722                 /* Start T303 */
00723                 Q931CallStartTimer(call, Q931_TIMER_T303);
00724 
00725                 /* => N6 Call present */
00726                 Q931CallSetState(call, Q931_N6);
00727                 break;
00728 
00729         case Q931_MSG_FROM_L2:          /* incoming call */
00730                 if (!call) {
00731                         call = Q931CallNewIncoming(trunk, msg->CRV);
00732                         if (!call) {
00733                                 /* Not possible to allocate CRV entry, so must reject call */
00734                                 Q931Disconnect(trunk, from, msg->CRV, 42);
00735                                 return Q931E_INTERNAL;
00736                         }
00737                 }
00738 
00739                 /* Store TEI */
00740                 call->Tei = msg->Tei;
00741 
00742                 /* => N1 Call initiated */
00743                 Q931CallSetState(call, Q931_N1);
00744 
00745                 /* Send setup indication to user */
00746                 ret = Q931Tx34(trunk, call, msg, msg->Size);
00747                 if (ret != Q931E_NO_ERROR) {
00748                         if (Q931TrunkIsSetFlag(trunk, Q931_TFLAG_AUTO_SETUP_ACK)) {
00749                                 Q931AckSetup(trunk, msg);
00750                         }
00751                         return ret;
00752                 } else {
00753                         /* Must be full queue, meaning we can't process the call */
00754                         /* so we must disconnect */
00755                         Q931Disconnect(trunk, from, msg->CRV, 81);
00756                         return ret;
00757                 }
00758                 break;
00759 
00760         default:
00761                 ret = Q931E_INTERNAL;
00762         }
00763         return ret;
00764 }
00765 
00766 /*****************************************************************************
00767 
00768   Function:             Q931ProcSetupAckNT
00769 
00770   Description:  Used to acknowedge a SETUP. Usually the first initial
00771                                 response recevide back used to buy some time.
00772 
00773                                 Note that ChanID (B Channel Assignment) might come here from
00774                                 NT side.
00775 
00776 *****************************************************************************/
00777 L3INT Q931ProcSetupAckNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00778 {
00779         L3INT ret = Q931E_NO_ERROR;
00780 #if 0
00781         /* Find the call using CRV */
00782         call = Q931GetCallByCRV(trunk, msg->CRV);
00783         if (!call)
00784                 return Q931E_INVALID_CRV;
00785 
00786         /* check if message is valid in this state */
00787         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00788                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00789                 return Q931E_UNEXPECTED_MESSAGE;
00790         }
00791 #endif
00792         switch (from) {
00793         case Q931_MSG_FROM_L4:
00794                 switch (Q931CallGetState(call)) {
00795                 case Q931_N1:   /* More info request */
00796                         /* Send SETUP ACK */
00797                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00798 
00799                         /* Start T302 */
00800                         Q931CallStartTimer(call, Q931_TIMER_T302);
00801 
00802                         /* => N2 Overlap sending */
00803                         Q931CallSetState(call, Q931_N2);
00804                         break;
00805                 default:
00806                         break;
00807                 }
00808                 break;
00809         case Q931_MSG_FROM_L2:
00810                 switch (Q931CallGetState(call)) {
00811                 case Q931_N6:
00812                         /* Stop T303 */
00813                         Q931CallStopTimer(call, Q931_TIMER_T303);
00814 
00815                         /* TODO: More information indication */
00816 
00817                         /* Start T304 */
00818                         Q931CallStartTimer(call, Q931_TIMER_T304);
00819 
00820                         /* => N25 Overlap receiving */
00821                         Q931CallSetState(call, Q931_N25);
00822                         break;
00823                 default:
00824                         break;
00825                 }
00826                 break;
00827         default:
00828                 ret = Q931E_INTERNAL;
00829         }
00830         return ret;
00831 }
00832 
00833 /*****************************************************************************
00834 
00835   Function:             Q931ProcResumeNT
00836 
00837 *****************************************************************************/
00838 L3INT Q931ProcResumeNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00839 {
00840         L3INT ret = Q931E_NO_ERROR;
00841 
00842         switch (from) {
00843         case Q931_MSG_FROM_L2:
00844                 /* Find the call using CRV */
00845                 call = Q931GetCallByCRV(trunk, msg->CRV);
00846                 if (!call) {
00847                         call = Q931CallNew(trunk);
00848                         if (!call) {
00849                                 return Q931E_INTERNAL;
00850                         }
00851 
00852                         /* Send resume indication to user */
00853                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00854                         if (ret != Q931E_NO_ERROR)
00855                                 return ret;
00856 
00857                         /* => N17 Resume request */
00858                         Q931CallSetState(call, Q931_N17);
00859                 } else {
00860                         return Q931E_ILLEGAL_MESSAGE;
00861                 }
00862                 break;
00863 
00864         default:
00865                 ret = Q931E_ILLEGAL_MESSAGE;
00866         }
00867         return ret;
00868 }
00869 
00870 /*****************************************************************************
00871 
00872   Function:             Q931ProcResumeAckNT
00873 
00874 *****************************************************************************/
00875 L3INT Q931ProcResumeAckNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00876 {
00877         L3INT ret = Q931E_NO_ERROR;
00878 #if 0
00879         /* Find the call using CRV */
00880         call = Q931GetCallByCRV(trunk, msg->CRV);
00881         if (!call)
00882                 return Q931E_INVALID_CRV;
00883 
00884         /* check if message is valid in this state */
00885         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00886                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00887                 return Q931E_UNEXPECTED_MESSAGE;
00888         }
00889 #endif
00890         switch (from) {
00891         case Q931_MSG_FROM_L4: /* Resume response */
00892                 /* Send RESUME ACKNOWLEDGE */
00893                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
00894 
00895                 /* Stop T307 */
00896                 Q931CallStopTimer(call, Q931_TIMER_T307);
00897 
00898                 /* Release CallID??? */
00899 
00900                 /* => N10 Active */
00901                 Q931CallSetState(call, Q931_N10);
00902                 break;
00903         default:
00904                 ret = Q931E_ILLEGAL_MESSAGE;
00905         }
00906         return ret;
00907 }
00908 
00909 /*****************************************************************************
00910 
00911   Function:             Q931ProcResumeRejectNT
00912 
00913 *****************************************************************************/
00914 L3INT Q931ProcResumeRejectNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00915 {
00916         L3INT ret = Q931E_NO_ERROR;
00917 #if 0
00918         /* Find the call using CRV */
00919         call = Q931GetCallByCRV(trunk, msg->CRV);
00920         if (!call)
00921                 return Q931E_INVALID_CRV;
00922 
00923         /* check if message is valid in this state */
00924         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00925                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00926                 return Q931E_UNEXPECTED_MESSAGE;
00927         }
00928 #endif
00929         switch (from) {
00930         case Q931_MSG_FROM_L4: /* Resume response */
00931                 /* Send RESUME REJECT */
00932                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
00933 
00934                 /* Release CRV */
00935                 Q931CallSetState(call, Q931_N0);
00936                 Q931CallRelease(call);
00937                 break;
00938         default:
00939                 ret = Q931E_ILLEGAL_MESSAGE;
00940         }
00941         return ret;
00942 }
00943 
00944 /*****************************************************************************
00945 
00946   Function:             Q931ProcSuspendNT
00947 
00948 *****************************************************************************/
00949 L3INT Q931ProcSuspendNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00950 {
00951         L3INT ret = Q931E_NO_ERROR;
00952 #if 0
00953         /* Find the call using CRV */
00954         call = Q931GetCallByCRV(trunk, msg->CRV);
00955         if (!call)
00956                 return Q931E_INVALID_CRV;
00957 
00958         /* check if message is valid in this state */
00959         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00960                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00961                 return Q931E_UNEXPECTED_MESSAGE;
00962         }
00963 #endif
00964         switch (from) {
00965         case Q931_MSG_FROM_L2:
00966                 /* Send Suspend indication */
00967                 ret = Q931Tx34(trunk, call, msg, msg->Size);
00968 
00969                 /* => N15 Suspend request */
00970                 Q931CallSetState(call, Q931_N15);
00971                 break;
00972         default:
00973                 ret = Q931E_ILLEGAL_MESSAGE;
00974         }
00975         return ret;
00976 }
00977 
00978 /*****************************************************************************
00979 
00980   Function:             Q931ProcSuspendAckNT
00981 
00982 *****************************************************************************/
00983 L3INT Q931ProcSuspendAckNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00984 {
00985         L3INT ret = Q931E_NO_ERROR;
00986 #if 0
00987         /* Find the call using CRV */
00988         call = Q931GetCallByCRV(trunk, msg->CRV);
00989         if (!call)
00990                 return Q931E_INVALID_CRV;
00991 
00992         /* check if message is valid in this state */
00993         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
00994                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
00995                 return Q931E_UNEXPECTED_MESSAGE;
00996         }
00997 #endif
00998         switch (from) {
00999         case Q931_MSG_FROM_L4:  /* Suspend response */
01000                 /* Send SUSPEND ACKNOWLEDGE */
01001                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01002 
01003                 /* Start T307 */
01004                 Q931CallStartTimer(call, Q931_TIMER_T307);
01005 
01006                 /* TODO: Spec says to release the CRV, but that'd mean we loose the call handle
01007                  * ==> Add per-call flag Q931_CALL_SUSPENDED
01008                  */
01009                 /* Q931CallSetFlag(call, Q931_CALL_SUSPENDED); */
01010 
01011                 /* => N0 Null */
01012                 Q931CallSetState(call, Q931_N0);
01013                 break;
01014         default:
01015                 ret = Q931E_ILLEGAL_MESSAGE;
01016         }
01017         return ret;
01018 }
01019 
01020 /*****************************************************************************
01021 
01022   Function:             Q931ProcSuspendRejectNT
01023 
01024 *****************************************************************************/
01025 L3INT Q931ProcSuspendRejectNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01026 {
01027         L3INT ret = Q931E_NO_ERROR;
01028 #if 0
01029         /* Find the call using CRV */
01030         call = Q931GetCallByCRV(trunk, msg->CRV);
01031         if (!call)
01032                 return Q931E_INVALID_CRV;
01033 
01034         /* check if message is valid in this state */
01035         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from)) {
01036                 Q931Log(trunk, Q931_LOG_DEBUG, "Message %d from %d not allowed in this state %s\n", msg->MesType, from, Q931CallGetStateName(call));
01037                 return Q931E_UNEXPECTED_MESSAGE;
01038         }
01039 #endif
01040         switch (from) {
01041         case Q931_MSG_FROM_L4:  /* Suspend reject request */
01042                 /* Send SUSPEND REJECT */
01043                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01044 
01045                 /* == N10 Active */
01046                 break;
01047         default:
01048                 ret = Q931E_ILLEGAL_MESSAGE;
01049         }
01050         return ret;
01051 }
01052 
01053 /*****************************************************************************
01054 
01055   Function:             Q931ProcInformationNT
01056 
01057 *****************************************************************************/
01058 L3INT Q931ProcUserInformationNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01059 {
01060         L3INT ret = Q931E_NO_ERROR;
01061 
01062         /* TODO: ???? */
01063 #if 0
01064         /* Find the call using CRV */
01065         call = Q931GetCallByCRV(trunk, msg->CRV);
01066         if (!call)
01067                 return Q931E_INVALID_CRV;
01068 
01069         /* check if message is valid in this state */
01070         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01071                 return Q931E_UNEXPECTED_MESSAGE;
01072 #endif
01073         switch (from) {
01074         case Q931_MSG_FROM_L4:
01075                 /* Send INFORMATION */
01076                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01077 
01078                 /* Start / Restart T304 */
01079                 Q931CallStartTimer(call, Q931_TIMER_T304);
01080 
01081                 /* == U2 (Overlap sending) */
01082                 break;
01083         case Q931_MSG_FROM_L2:
01084                 /* TODO: send Info indication */
01085                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01086 
01087                 /* Start T302 */
01088                 Q931CallStartTimer(call, Q931_TIMER_T302);
01089 
01090                 /* == U25 (Overlap receiving) */
01091                 break;
01092         default:
01093                 ret = Q931E_ILLEGAL_MESSAGE;
01094         }
01095         return ret;
01096 }
01097 
01098 /*****************************************************************************
01099 
01100   Function:             Q931ProcDisconnectNT
01101 
01102 *****************************************************************************/
01103 L3INT Q931ProcDisconnectNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01104 {
01105         L3INT ret = Q931E_NO_ERROR;
01106 
01107         Q931Log(trunk, Q931_LOG_DEBUG, "Processing DISCONNECT message from %s for CRV: %d (%#hx)\n",
01108                                                  from == 4 ? "Local" : "Remote", msg->CRV, msg->CRV);
01109 
01110         /* TODO: not complete... */
01111 #if 0
01112         /* Find the call using CRV */
01113         call = Q931GetCallByCRV(trunk, msg->CRV);
01114         if (!call)
01115                 return Q931E_INVALID_CRV;
01116 
01117         /* check if message is valid in this state */
01118         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01119                 return Q931E_UNEXPECTED_MESSAGE;
01120 #endif
01121         switch (from) {
01122         case Q931_MSG_FROM_L4:
01123                 switch (Q931CallGetState(call)) {
01124                 case Q931_N0:   /* Disconnect request */
01125                 case Q931_N6:
01126                 case Q931_N11:
01127                 case Q931_N12:
01128                 case Q931_N19:
01129                 case Q931_N22:
01130                         /* TODO: should never occur? */
01131                         break;
01132 
01133                 case Q931_N7:
01134                 case Q931_N8:
01135                 case Q931_N9:
01136                 default:
01137                         /* Stop all timers */
01138                         Q931CallStopAllTimers(call);
01139 
01140                         /* Tones are handled by L4!! */
01141 
01142                         /* Disconnect */
01143                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01144 
01145                         /* Start T305 */
01146                         Q931CallStartTimer(call, Q931_TIMER_T305);
01147 
01148                         /* => N12 Disconnect indication */
01149                         Q931CallSetState(call, Q931_N12);
01150                 }
01151                 break;
01152         case Q931_MSG_FROM_L2:
01153                 switch (Q931CallGetState(call)) {
01154                 case Q931_N0:
01155                 case Q931_N11:
01156                 case Q931_N12:
01157                 case Q931_N19:
01158                 case Q931_N22:
01159                         /* TODO: should never occur? */
01160                         break;
01161 
01162 #if 0
01163                 /* TODO: Move to release request */
01164                 case Q931_N12:
01165                         /* Stop T305 or T306 */
01166                         Q931CallStopTimer(call, Q931_TIMER_T305);
01167                         Q931CallStopTimer(call, Q931_TIMER_T306);
01168 
01169                         /* TODO: Send RELEASE */
01170 
01171                         /* Start T308 */
01172                         Q931CallStartTimer(call, Q931_TIMER_T308);
01173 
01174                         /* => N19 Release request */
01175                         Q931CallSetState(call, Q931_N19);
01176                         break;
01177 #endif
01178 
01179                 case Q931_N1:
01180                         /* B-Channel disconnect for states > N1 handled by L4!! */
01181                 case Q931_N7:
01182                 case Q931_N8:
01183                 case Q931_N9:
01184                 default:
01185                         /* Stop all timers */
01186                         Q931CallStopAllTimers(call);
01187 
01188                         /* TODO: Send Disconnect indication */
01189                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01190 
01191                         /* => N11 Disconnect request */
01192                         Q931CallSetState(call, Q931_N11);
01193                 }
01194                 break;
01195         default:
01196                 ret = Q931E_ILLEGAL_MESSAGE;
01197         }
01198         return ret;
01199 }
01200 
01201 /*****************************************************************************
01202 
01203   Function:             Q931ProcReleaseNT
01204 
01205 *****************************************************************************/
01206 L3INT Q931ProcReleaseNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01207 {
01208         L3INT ret = Q931E_NO_ERROR;
01209 
01210         /* TODO: not complete... */
01211 #if 0
01212         /* Find the call using CRV */
01213         call = Q931GetCallByCRV(trunk, msg->CRV);
01214         if (!call)
01215                 return Q931E_INVALID_CRV;
01216 
01217         /* check if message is valid in this state */
01218         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01219                 return Q931E_UNEXPECTED_MESSAGE;
01220 #endif
01221         switch (from) {
01222         case Q931_MSG_FROM_L4:
01223                 switch (Q931CallGetState(call)) {
01224                 case Q931_N11:  /* Release request */
01225                         /* Send RELEASE */
01226                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01227 
01228                         /* Start T308 */
01229                         Q931CallStartTimer(call, Q931_TIMER_T308);
01230 
01231                         /* => N19 Release request */
01232                         Q931CallSetState(call, Q931_N19);
01233                         break;
01234 
01235                 default:
01236                         break;
01237                 }
01238                 break;
01239         case Q931_MSG_FROM_L2:
01240                 switch (Q931CallGetState(call)) {
01241                 case Q931_N0:
01242                         /* Send RELEASE COMPLETE reply */
01243                         ret = Q931ReleaseComplete(trunk, call, 0);
01244 
01245                         /* Release Call */
01246                         Q931CallRelease(call);
01247                         break;
01248 
01249                 case Q931_N6:
01250                         /* Page 22 NC */
01251                         /* Stop all timers */
01252                         Q931CallStopAllTimers(call);
01253 
01254                         /* TODO: Send DISCONNECT */
01255 
01256                         /* Start T305 or T306 */
01257                         Q931CallStartTimer(call, Q931_TIMER_T305);
01258 
01259                         /* => N12 Disconnect indication */
01260                         Q931CallSetState(call, Q931_N12);
01261                         break;
01262 
01263                 case Q931_N12:
01264                         /* Stop T305 or T306 */
01265                         Q931CallStopTimer(call, Q931_TIMER_T305);
01266                         Q931CallStopTimer(call, Q931_TIMER_T306);
01267 
01268                         /* Send Relase indication */
01269                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01270 
01271                         /* B-Channel release handled by L4!! */
01272 
01273                         /* Send RELEASE COMPLETE reply */
01274                         ret = Q931ReleaseComplete(trunk, call, 0);
01275 
01276                         /* Release CRV */
01277                         Q931CallSetState(call, Q931_N0);
01278                         Q931CallRelease(call);
01279                         break;
01280 
01281                 case Q931_N19:
01282                         /* Stop T308 */
01283                         Q931CallStopTimer(call, Q931_TIMER_T308);
01284 
01285                         /* TODO: Release confirm */
01286                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01287 
01288                         /* B-channel release handled by L4!! */
01289 
01290                         /* Release CRV  */
01291                         Q931CallSetState(call, Q931_N0);
01292                         Q931CallRelease(call);
01293                         break;
01294 
01295                 default:
01296                         /* Stop all timers */
01297                         Q931CallStopAllTimers(call);
01298 
01299                         /* TODO: Release indication */
01300                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01301 
01302                         /* B-channel release handled by L4!! */
01303 
01304                         /* Send RELEASE COMPLETE reply */
01305                         ret = Q931ReleaseComplete(trunk, call, 0);
01306 
01307                         /* Release CRV  */
01308                         Q931CallSetState(call, Q931_N0);
01309                         Q931CallRelease(call);
01310                         break;
01311                 }
01312                 break;
01313         default:
01314                 ret = Q931E_ILLEGAL_MESSAGE;
01315         }
01316         return ret;
01317 }
01318 
01319 /*****************************************************************************
01320 
01321   Function:             Q931ProcReleaseCompleteNT
01322 
01323 *****************************************************************************/
01324 L3INT Q931ProcReleaseCompleteNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01325 {
01326         L3INT ret = Q931E_NO_ERROR;
01327 #if 0
01328         /* Find the call using CRV */
01329         call = Q931GetCallByCRV(trunk, msg->CRV);
01330         if (!call)
01331                 return Q931E_INVALID_CRV;
01332 
01333         /* check if message is valid in this state */
01334         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01335                 return Q931E_UNEXPECTED_MESSAGE;
01336 #endif
01337         switch (from) {
01338         case Q931_MSG_FROM_L4:
01339                 switch (Q931CallGetState(call)) {
01340                 case Q931_N1:   /* Reject request */
01341                         /* Send RELEASE COMPLETE */
01342                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
01343 
01344                         /* Release CRV (?) */
01345                         Q931CallSetState(call, Q931_N0);
01346                         Q931CallRelease(call);
01347                         break;
01348                 default:
01349                         break;
01350                 }
01351                 break;
01352         case Q931_MSG_FROM_L2:
01353                 switch (Q931CallGetState(call)) {
01354                 case Q931_N0:
01355                         /* Release call */
01356                         Q931CallRelease(call);
01357                         break;
01358 
01359                 case Q931_N6:
01360                         /* Stop T303 */
01361                         Q931CallStopTimer(call, Q931_TIMER_T303);
01362 
01363                         /* TODO: Send Reject indication */
01364                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01365 
01366                         /* Release CRV */
01367                         Q931CallSetState(call, Q931_N0);
01368                         Q931CallRelease(call);
01369                         break;
01370 
01371                 case Q931_N19:
01372                         /* Stop T308 */
01373                         Q931CallStopTimer(call, Q931_TIMER_T308);
01374 
01375                         /* TODO: Send release confirm */
01376                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01377 
01378                         /* Release CRV */
01379                         Q931CallSetState(call, Q931_N0);
01380                         Q931CallRelease(call);
01381                         break;
01382                 default:
01383                         /* TODO: Send release indication */
01384                         ret = Q931Tx34(trunk, call, msg, msg->Size);
01385 
01386                         /* B-channel release handled by L4!! */
01387 
01388                         /* Release CRV */
01389                         Q931CallSetState(call, Q931_N0);
01390                         Q931CallRelease(call);
01391                         break;
01392                 }
01393 
01394                 /* Release CRV */
01395                 Q931CallSetState(call, Q931_N0);
01396                 Q931CallRelease(call);
01397                 break;
01398         default:
01399                 ret = Q931E_ILLEGAL_MESSAGE;
01400         }
01401         return ret;
01402 }
01403 
01404 /*****************************************************************************
01405 
01406   Function:             Q931ProcRestartNT
01407 
01408 *****************************************************************************/
01409 L3INT Q931ProcRestartNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01410 {
01411         L3INT ret = Q931E_NO_ERROR;
01412 #if 0
01413         if (msg->CRV)
01414                 return Q931E_INVALID_CRV;
01415 
01416         /* Find the call using CRV */
01417         call = Q931GetCallByCRV(trunk, msg->CRV);
01418         if (!call)
01419                 return Q931E_INVALID_CRV;
01420 
01421         /* check if message is valid in this state */
01422         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01423                 return Q931E_UNEXPECTED_MESSAGE;
01424 #endif
01425         /* TODO: T317, proper handling etc. */
01426 
01427         switch (from) {
01428         case Q931_MSG_FROM_L4:
01429                 /* TODO Add proc here */
01430                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01431                 break;
01432         case Q931_MSG_FROM_L2:
01433                 /* TODO Add proc here */
01434                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01435 
01436                 if (Q931TrunkIsSetFlag(trunk, Q931_TFLAG_AUTO_RESTART_ACK)) {
01437                         Q931AckRestart(trunk, msg);
01438                 }
01439                 break;
01440         default:
01441                 ret = Q931E_ILLEGAL_MESSAGE;
01442         }
01443         return ret;
01444 }
01445 
01446 /*****************************************************************************
01447 
01448   Function:             Q931ProcRestartAckNT
01449 
01450 *****************************************************************************/
01451 L3INT Q931ProcRestartAckNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01452 {
01453         L3INT ret = Q931E_NO_ERROR;
01454 #if 0
01455         /* Find the call using CRV */
01456         call = Q931GetCallByCRV(trunk, msg->CRV);
01457         if (!call)
01458                 return Q931E_INVALID_CRV;
01459 
01460         /* check if message is valid in this state */
01461         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01462                 return Q931E_UNEXPECTED_MESSAGE;
01463 #endif
01464 #if 0
01465         if (msg->CRV) {
01466                 /* Find the call using CRV */
01467                 ret = Q931FindCRV(trunk, msg->CRV, &callIndex);
01468                 if (ret != Q931E_NO_ERROR)
01469                         return ret;
01470                 /* TODO - Set correct timer here */
01471                 Q931StartTimer(trunk, callIndex, 303);
01472         }
01473 #endif
01474 
01475         switch (from) {
01476         case Q931_MSG_FROM_L4:
01477                 /* TODO Add proc here */
01478                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01479                 break;
01480         case Q931_MSG_FROM_L2:
01481                 /* TODO Add proc here */
01482                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01483                 break;
01484         default:
01485                 ret = Q931E_ILLEGAL_MESSAGE;
01486         }
01487         return ret;
01488 }
01489 
01490 /*****************************************************************************
01491 
01492   Function:             Q931ProcCongestionControlNT
01493 
01494 *****************************************************************************/
01495 L3INT Q931ProcCongestionControlNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01496 {
01497         L3INT ret = Q931E_NO_ERROR;
01498 #if 0
01499         /* Find the call using CRV */
01500         call = Q931GetCallByCRV(trunk, msg->CRV);
01501         if (!call)
01502                 return Q931E_INVALID_CRV;
01503 
01504         /* check if message is valid in this state */
01505         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01506                 return Q931E_UNEXPECTED_MESSAGE;
01507 #endif
01508         switch (from) {
01509         case Q931_MSG_FROM_L4:
01510                 /* TODO Add proc here */
01511                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01512                 break;
01513         case Q931_MSG_FROM_L2:
01514                 /* TODO Add proc here */
01515                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01516                 break;
01517         default:
01518                 ret = Q931E_ILLEGAL_MESSAGE;
01519         }
01520         return ret;
01521 }
01522 
01523 /*****************************************************************************
01524 
01525   Function:             Q931ProcInformationNT
01526 
01527 *****************************************************************************/
01528 L3INT Q931ProcInformationNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01529 {
01530         L3INT ret = Q931E_NO_ERROR;
01531 #if 0
01532         /* Find the call using CRV */
01533         call = Q931GetCallByCRV(trunk, msg->CRV);
01534         if (!call)
01535                 return Q931E_INVALID_CRV;
01536 
01537         /* check if message is valid in this state */
01538         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01539                 return Q931E_UNEXPECTED_MESSAGE;
01540 #endif
01541         switch (from) {
01542         case Q931_MSG_FROM_L4:
01543                 /* TODO Add proc here */
01544                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01545                 break;
01546         case Q931_MSG_FROM_L2:
01547                 /* TODO Add proc here */
01548                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01549                 break;
01550         default:
01551                 ret = Q931E_ILLEGAL_MESSAGE;
01552         }
01553         return ret;
01554 }
01555 
01556 /*****************************************************************************
01557 
01558   Function:             Q931ProcNotifyNT
01559 
01560 *****************************************************************************/
01561 L3INT Q931ProcNotifyNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01562 {
01563         L3INT ret = Q931E_NO_ERROR;
01564 #if 0
01565         /* Find the call using CRV */
01566         call = Q931GetCallByCRV(trunk, msg->CRV);
01567         if (!call)
01568                 return Q931E_INVALID_CRV;
01569 
01570         /* check if message is valid in this state */
01571         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01572                 return Q931E_UNEXPECTED_MESSAGE;
01573 #endif
01574         switch (from) {
01575         case Q931_MSG_FROM_L4:
01576                 /* TODO Add proc here */
01577                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01578                 break;
01579         case Q931_MSG_FROM_L2:
01580                 /* TODO Add proc here */
01581                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01582                 break;
01583         default:
01584                 ret = Q931E_ILLEGAL_MESSAGE;
01585         }
01586         return ret;
01587 }
01588 
01589 /*****************************************************************************
01590 
01591   Function:             Q931ProcStatusNT
01592 
01593 *****************************************************************************/
01594 L3INT Q931ProcStatusNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01595 {
01596         L3INT ret = Q931E_NO_ERROR;
01597 #if 0
01598         /* Find the call using CRV */
01599         call = Q931GetCallByCRV(trunk, msg->CRV);
01600         if (!call)
01601                 return Q931E_INVALID_CRV;
01602 
01603         /* check if message is valid in this state */
01604         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01605                 return Q931E_UNEXPECTED_MESSAGE;
01606 #endif
01607         switch (from) {
01608         case Q931_MSG_FROM_L4:
01609                 /* TODO Add proc here */
01610                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01611                 break;
01612         case Q931_MSG_FROM_L2:
01613                 /* TODO Add proc here */
01614                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01615                 break;
01616         default:
01617                 ret = Q931E_ILLEGAL_MESSAGE;
01618         }
01619         return ret;
01620 }
01621 
01622 /*****************************************************************************
01623 
01624   Function:             Q931ProcStatusEnquiryNT
01625 
01626 *****************************************************************************/
01627 L3INT Q931ProcStatusEnquiryNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01628 {
01629         L3INT ret = Q931E_NO_ERROR;
01630 #if 0
01631         /* Find the call using CRV */
01632         call = Q931GetCallByCRV(trunk, msg->CRV);
01633         if (!call)
01634                 return Q931E_INVALID_CRV;
01635 
01636         /* check if message is valid in this state */
01637         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01638                 return Q931E_UNEXPECTED_MESSAGE;
01639 #endif
01640         switch (from) {
01641 #if 0
01642         case Q931_MSG_FROM_L4:
01643                 /* TODO Add proc here */
01644                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01645                 break;
01646 #endif
01647         case Q931_MSG_FROM_L2:
01648                 ret = Q931StatusEnquiryResponse(trunk, call, Q850_CAUSE_RESPONSE_TO_STATUS_ENQUIRY);
01649                 break;
01650         default:
01651                 ret = Q931E_ILLEGAL_MESSAGE;
01652         }
01653         return ret;
01654 }
01655 
01656 /*****************************************************************************
01657 
01658   Function:             Q931ProcSegmentNT
01659 
01660 *****************************************************************************/
01661 L3INT Q931ProcSegmentNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01662 {
01663         L3INT ret = Q931E_NO_ERROR;
01664 #if 0
01665         /* Find the call using CRV */
01666         call = Q931GetCallByCRV(trunk, msg->CRV);
01667         if (!call)
01668                 return Q931E_INVALID_CRV;
01669 
01670         /* check if message is valid in this state */
01671         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01672                 return Q931E_UNEXPECTED_MESSAGE;
01673 #endif
01674         switch (from) {
01675         case Q931_MSG_FROM_L4:
01676                 /* TODO Add proc here */
01677                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01678                 break;
01679         case Q931_MSG_FROM_L2:
01680                 /* TODO Add proc here */
01681                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01682                 break;
01683         default:
01684                 ret = Q931E_ILLEGAL_MESSAGE;
01685         }
01686         return ret;
01687 }
01688 
01689 /****************************************************************************/
01690 /******************* Q.932 - Supplementary Services *************************/
01691 /****************************************************************************/
01692 
01693 /*****************************************************************************
01694 
01695   Function:             Q932ProcFacilityNT
01696 
01697 *****************************************************************************/
01698 L3INT Q932ProcFacilityNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01699 {
01700         L3INT ret = Q931E_NO_ERROR;
01701 #if 0
01702         /* Find the call using CRV */
01703         call = Q931GetCallByCRV(trunk, msg->CRV);
01704         if (!call)
01705                 return Q931E_INVALID_CRV;
01706 
01707         /* check if message is valid in this state */
01708         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01709                 return Q931E_UNEXPECTED_MESSAGE;
01710 #endif
01711         switch (from) {
01712         case Q931_MSG_FROM_L4:
01713                 /* TODO Add proc here */
01714                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01715                 break;
01716         case Q931_MSG_FROM_L2:
01717                 /* TODO Add proc here */
01718                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01719                 break;
01720         default:
01721                 ret = Q931E_ILLEGAL_MESSAGE;
01722         }
01723         return ret;
01724 }
01725 
01726 /*****************************************************************************
01727 
01728   Function:             Q932ProcHoldNT
01729 
01730 *****************************************************************************/
01731 L3INT Q932ProcHoldNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01732 {
01733         L3INT ret = Q931E_NO_ERROR;
01734 #if 0
01735         /* Find the call using CRV */
01736         call = Q931GetCallByCRV(trunk, msg->CRV);
01737         if (!call)
01738                 return Q931E_INVALID_CRV;
01739 
01740         /* check if message is valid in this state */
01741         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01742                 return Q931E_UNEXPECTED_MESSAGE;
01743 #endif
01744         switch (from) {
01745         case Q931_MSG_FROM_L4:
01746                 /* TODO Add proc here */
01747                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01748                 break;
01749         case Q931_MSG_FROM_L2:
01750                 /* TODO Add proc here */
01751                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01752                 break;
01753         default:
01754                 ret = Q931E_ILLEGAL_MESSAGE;
01755         }
01756         return ret;
01757 }
01758 
01759 /*****************************************************************************
01760 
01761   Function:             Q932ProcHoldAckNT
01762 
01763 *****************************************************************************/
01764 L3INT Q932ProcHoldAckNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01765 {
01766         L3INT ret = Q931E_NO_ERROR;
01767 #if 0
01768         /* Find the call using CRV */
01769         call = Q931GetCallByCRV(trunk, msg->CRV);
01770         if (!call)
01771                 return Q931E_INVALID_CRV;
01772 
01773         /* check if message is valid in this state */
01774         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01775                 return Q931E_UNEXPECTED_MESSAGE;
01776 #endif
01777         switch (from) {
01778         case Q931_MSG_FROM_L4:
01779                 /* TODO Add proc here */
01780                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01781                 break;
01782         case Q931_MSG_FROM_L2:
01783                 /* TODO Add proc here */
01784                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01785                 break;
01786         default:
01787                 ret = Q931E_ILLEGAL_MESSAGE;
01788         }
01789         return ret;
01790 }
01791 
01792 /*****************************************************************************
01793 
01794   Function:             Q932ProcHoldRejectNT
01795 
01796 *****************************************************************************/
01797 L3INT Q932ProcHoldRejectNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01798 {
01799         L3INT ret = Q931E_NO_ERROR;
01800 #if 0
01801         /* Find the call using CRV */
01802         call = Q931GetCallByCRV(trunk, msg->CRV);
01803         if (!call)
01804                 return Q931E_INVALID_CRV;
01805 
01806         /* check if message is valid in this state */
01807         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01808                 return Q931E_UNEXPECTED_MESSAGE;
01809 #endif
01810         switch (from) {
01811         case Q931_MSG_FROM_L4:
01812                 /* TODO Add proc here */
01813                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01814                 break;
01815         case Q931_MSG_FROM_L2:
01816                 /* TODO Add proc here */
01817                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01818                 break;
01819         default:
01820                 ret = Q931E_ILLEGAL_MESSAGE;
01821         }
01822         return ret;
01823 }
01824 
01825 /*****************************************************************************
01826 
01827   Function:             Q932ProcRegisterTE
01828 
01829 *****************************************************************************/
01830 L3INT Q932ProcRegisterNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01831 {
01832         L3INT ret = Q931E_NO_ERROR;
01833 #if 0
01834         /* Find the call using CRV */
01835         call = Q931GetCallByCRV(trunk, msg->CRV);
01836         if (!call)
01837                 return Q931E_INVALID_CRV;
01838 
01839         /* check if message is valid in this state */
01840         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01841                 return Q931E_UNEXPECTED_MESSAGE;
01842 #endif
01843         switch (from) {
01844         case Q931_MSG_FROM_L4:
01845                 /* TODO Add proc here */
01846                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01847                 break;
01848         case Q931_MSG_FROM_L2:
01849                 /* TODO Add proc here */
01850                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01851                 break;
01852         default:
01853                 ret = Q931E_ILLEGAL_MESSAGE;
01854         }
01855         return ret;
01856 }
01857 
01858 /*****************************************************************************
01859 
01860   Function:             Q932ProcRetrieveNT
01861 
01862 *****************************************************************************/
01863 L3INT Q932ProcRetrieveNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01864 {
01865         L3INT ret = Q931E_NO_ERROR;
01866 #if 0
01867         /* Find the call using CRV */
01868         call = Q931GetCallByCRV(trunk, msg->CRV);
01869         if (!call)
01870                 return Q931E_INVALID_CRV;
01871 
01872         /* check if message is valid in this state */
01873         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01874                 return Q931E_UNEXPECTED_MESSAGE;
01875 #endif
01876         switch (from) {
01877         case Q931_MSG_FROM_L4:
01878                 /* TODO Add proc here */
01879                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01880                 break;
01881         case Q931_MSG_FROM_L2:
01882                 /* TODO Add proc here */
01883                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01884                 break;
01885         default:
01886                 ret = Q931E_ILLEGAL_MESSAGE;
01887         }
01888         return ret;
01889 }
01890 
01891 /*****************************************************************************
01892 
01893   Function:             Q931ProcRetrieveAckNT
01894 
01895 *****************************************************************************/
01896 L3INT Q932ProcRetrieveAckNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01897 {
01898         L3INT ret = Q931E_NO_ERROR;
01899 #if 0
01900         /* Find the call using CRV */
01901         call = Q931GetCallByCRV(trunk, msg->CRV);
01902         if (!call)
01903                 return Q931E_INVALID_CRV;
01904 
01905         /* check if message is valid in this state */
01906         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01907                 return Q931E_UNEXPECTED_MESSAGE;
01908 #endif
01909         switch (from) {
01910         case Q931_MSG_FROM_L4:
01911                 /* TODO Add proc here */
01912                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01913                 break;
01914         case Q931_MSG_FROM_L2:
01915                 /* TODO Add proc here */
01916                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01917                 break;
01918         default:
01919                 ret = Q931E_ILLEGAL_MESSAGE;
01920         }
01921         return ret;
01922 }
01923 
01924 /*****************************************************************************
01925 
01926   Function:             Q931ProcRetrieveRejectNT
01927 
01928 *****************************************************************************/
01929 L3INT Q932ProcRetrieveRejectNT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
01930 {
01931         L3INT ret = Q931E_NO_ERROR;
01932 #if 0
01933         /* Find the call using CRV */
01934         call = Q931GetCallByCRV(trunk, msg->CRV);
01935         if (!call)
01936                 return Q931E_INVALID_CRV;
01937 
01938         /* check if message is valid in this state */
01939         if (!Q931DialectIsEventLegal(trunk->Dialect, Q931CallGetState(call), msg->MesType, from))
01940                 return Q931E_UNEXPECTED_MESSAGE;
01941 #endif
01942         switch (from) {
01943         case Q931_MSG_FROM_L4:
01944                 /* TODO Add proc here */
01945                 ret = Q931Tx32(trunk, 0, msg, msg->Size);
01946                 break;
01947         case Q931_MSG_FROM_L2:
01948                 /* TODO Add proc here */
01949                 ret = Q931Tx34(trunk, call, msg, msg->Size);
01950                 break;
01951         default:
01952                 ret = Q931E_ILLEGAL_MESSAGE;
01953         }
01954         return ret;
01955 }
01956 
01957 
01958 /************************************************************************************
01959  * Timer callbacks (NT side)
01960  ************************************************************************************/
01961 
01962 L3INT Q931ProcTimeoutT301NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
01963 {
01964         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T301 timed out for call %d\n", call->CRV);
01965 
01966         if (Q931CallGetState(call) != Q931_N7) {
01967                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T301 in state %s (wrong state)\n", Q931CallGetStateName(call));
01968                 return Q931E_NO_ERROR;
01969         }
01970 
01971         /* TODO: Send TIMEOUT indication */
01972 
01973         return Q931E_NO_ERROR;
01974 }
01975 
01976 L3INT Q931ProcTimeoutT302NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
01977 {
01978         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T302 timed out for call %d\n", call->CRV);
01979 
01980         if (Q931CallGetState(call) != Q931_N2) {
01981                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T302 in state %s (wrong state)\n", Q931CallGetStateName(call));
01982                 return Q931E_NO_ERROR;
01983         }
01984 
01985         /* TODO: Send TIMEOUT indication */
01986 
01987         return Q931E_NO_ERROR;
01988 }
01989 
01990 L3INT Q931ProcTimeoutT303NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
01991 {
01992         L3UCHAR cnt = Q931CallGetTimerExpireCount(call);        /* T303 uses the counter */
01993 
01994         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T303 timed out for call %d (number of times: %hhu)\n", call->CRV, cnt);
01995 
01996         if (Q931CallGetState(call) != Q931_N6) {
01997                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T303 in state %s (wrong state)\n", Q931CallGetStateName(call));
01998                 return Q931E_NO_ERROR;
01999         }
02000 
02001         if (cnt == 1) {
02002                 /* TODO: Resend SETUP */
02003 
02004                 /* Restart T303 */
02005                 Q931CallRestartTimer(call, Q931_TIMER_T303);
02006 
02007                 /* No state change */
02008         } else {
02009                 struct Q931_CallEvent event;
02010 
02011                 /* (TODO:) Send RELEASE INDICATION */
02012                 Q931CallInitEvent(&event);
02013                 event.id    = Q931_EVENT_RELEASE_INDICATION;
02014                 event.type  = Q931_EVENT_TYPE_TIMER;
02015                 event.data.timer.id = Q931_TIMER_T303;
02016 
02017                 /* Send event immediately to layer 4 */
02018                 Q931CallSendEvent(call, &event);
02019 
02020                 /* Release CRV */
02021                 Q931CallSetState(call, Q931_N0);
02022                 Q931CallRelease(call);
02023         }
02024         return Q931E_NO_ERROR;
02025 }
02026 
02027 L3INT Q931ProcTimeoutT304NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02028 {
02029         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T304 timed out for call %d\n", call->CRV);
02030 
02031         if (Q931CallGetState(call) != Q931_N25) {
02032                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T304 in state %s (wrong state)\n", Q931CallGetStateName(call));
02033                 return Q931E_NO_ERROR;
02034         }
02035 
02036         /* TODO: Send TIMEOUT indication */
02037 
02038         return Q931E_NO_ERROR;
02039 }
02040 
02041 L3INT Q931ProcTimeoutT305NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02042 {
02043         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T305 timed out for call %d\n", call->CRV);
02044 
02045         if (Q931CallGetState(call) != Q931_N12) {
02046                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T305 in state %s (wrong state)\n", Q931CallGetStateName(call));
02047                 return Q931E_NO_ERROR;
02048         }
02049 
02050         /* TODO: Send RELEASE */
02051 
02052         /* Start T308 */
02053         Q931CallStartTimer(call, Q931_TIMER_T308);
02054 
02055         /* => 19: Release request */
02056         Q931CallSetState(call, Q931_N19);
02057 
02058         return Q931E_NO_ERROR;
02059 }
02060 
02061 L3INT Q931ProcTimeoutT306NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02062 {
02063         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T306 timed out for call %d\n", call->CRV);
02064 
02065         if (Q931CallGetState(call) != Q931_N12) {
02066                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T306 in state %s (wrong state)\n", Q931CallGetStateName(call));
02067                 return Q931E_NO_ERROR;
02068         }
02069 
02070         /* TODO: Send RELEASE */
02071 
02072         /* Start T308 */
02073         Q931CallStartTimer(call, Q931_TIMER_T308);
02074 
02075         /* => 19: Release request */
02076         Q931CallSetState(call, Q931_N19);
02077 
02078         return Q931E_NO_ERROR;
02079 }
02080 
02081 L3INT Q931ProcTimeoutT307NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02082 {
02083         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T307 timed out for call %d\n", call->CRV);
02084 
02085         if (Q931CallGetState(call) != Q931_N0) {
02086                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T307 in state %s (wrong state)\n", Q931CallGetStateName(call));
02087                 return Q931E_NO_ERROR;
02088         }
02089 
02090         /* Release CRV */
02091         Q931CallSetState(call, Q931_N0);
02092         Q931CallRelease(call);
02093 
02094         /* TODO: Release B-Channel */
02095 
02096         return Q931E_NO_ERROR;
02097 }
02098 
02099 L3INT Q931ProcTimeoutT308NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02100 {
02101         L3UCHAR cnt = Q931CallGetTimerExpireCount(call);        /* T308 uses the counter */
02102 
02103         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T308 timed out for call %d (number of times %hhu)\n", call->CRV, cnt);
02104 
02105         if (Q931CallGetState(call) != Q931_N19) {
02106                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T308 in state %s (wrong state)\n", Q931CallGetStateName(call));
02107                 return Q931E_NO_ERROR;
02108         }
02109 
02110         if (cnt == 1) {
02111                 /* TODO: Send RELEASE */
02112 
02113                 /* Restart T308 */
02114                 Q931CallRestartTimer(call, Q931_TIMER_T308);
02115 
02116                 /* No state change */
02117         } else {
02118                 /* TODO: Place B-Channel in maintenance */
02119 
02120                 /* TODO: Send RELEASE CONFIRM (error) indication */
02121 
02122                 /* Release CRV */
02123                 Q931CallSetState(call, Q931_N0);
02124                 Q931CallRelease(call);
02125         }
02126         return Q931E_NO_ERROR;
02127 }
02128 
02129 L3INT Q931ProcTimeoutT309NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02130 {
02131         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T309 timed out for call %d\n", call->CRV);
02132         return Q931E_NO_ERROR;
02133 }
02134 
02135 L3INT Q931ProcTimeoutT310NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02136 {
02137         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T310 timed out for call %d\n", call->CRV);
02138 
02139         if (Q931CallGetState(call) != Q931_N9) {
02140                 Q931Log(trunk, Q931_LOG_WARNING, "Ignoring timeout of T310 in state %s (wrong state)\n", Q931CallGetStateName(call));
02141                 return Q931E_NO_ERROR;
02142         }
02143 
02144         /* Stop all timers */
02145         Q931CallStopAllTimers(call);
02146 
02147         /* TODO: Tones option? */
02148         if (1) {
02149                 /* TODO: Start tone */
02150 
02151                 /* TODO: Send DISCONNECT */
02152 
02153                 /* Start T306 */
02154                 Q931CallStartTimer(call, Q931_TIMER_T306);
02155         } else {
02156                 /* TODO: Disconnect B-Channel */
02157 
02158                 /* TOOD: Send DISCONNECT */
02159 
02160                 /* Start T305 */
02161                 Q931CallStartTimer(call, Q931_TIMER_T305);
02162         }
02163 
02164         /* => 12: Disconnect indication */
02165         Q931CallSetState(call, Q931_N12);
02166 
02167         return Q931E_NO_ERROR;
02168 }
02169 
02170 L3INT Q931ProcTimeoutT312NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02171 {
02172         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T312 timed out for call %d\n", call->CRV);
02173         return Q931E_NO_ERROR;
02174 }
02175 
02176 L3INT Q931ProcTimeoutT313NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02177 {
02178         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T313 timed out for call %d\n", call->CRV);
02179         return Q931E_NO_ERROR;
02180 }
02181 
02182 L3INT Q931ProcTimeoutT314NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02183 {
02184         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T314 timed out for call %d\n", call->CRV);
02185         return Q931E_NO_ERROR;
02186 }
02187 
02188 L3INT Q931ProcTimeoutT316NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02189 {
02190         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T316 timed out for call %d\n", call->CRV);
02191         return Q931E_NO_ERROR;
02192 }
02193 
02194 L3INT Q931ProcTimeoutT317NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02195 {
02196         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T317 timed out for call %d\n", call->CRV);
02197         return Q931E_NO_ERROR;
02198 }
02199 
02200 L3INT Q931ProcTimeoutT320NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02201 {
02202         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T320 timed out for call %d\n", call->CRV);
02203         return Q931E_NO_ERROR;
02204 }
02205 
02206 L3INT Q931ProcTimeoutT321NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02207 {
02208         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T321 timed out for call %d\n", call->CRV);
02209         return Q931E_NO_ERROR;
02210 }
02211 
02212 L3INT Q931ProcTimeoutT322NT(Q931_TrunkInfo_t *trunk, struct Q931_Call *call)
02213 {
02214         Q931Log(trunk, Q931_LOG_NOTICE, "Timer T322 timed out for call %d\n", call->CRV);
02215         return Q931E_NO_ERROR;
02216 }
02217