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