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

Generated on Tue Apr 7 17:38:19 2009 for mod_ssh by  doxygen 1.5.4