Q931StateTE.c

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

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