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