libisdn
5ESSStateTE.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   FileName:     5ESSStateTE.c
00004 
00005   Contents:     AT&T 5ESS ISDN 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   Copyright (c) 2007, Michael Jerris. All rights reserved.
00026   email:mike@jerris.com
00027 
00028   Copyright (c) 2007, Michael S. Collins, All rights reserved.
00029   email:mcollins@fcnetwork.com
00030 
00031   Redistribution and use in source and binary forms, with or without
00032   modification, are permitted provided that the following conditions are
00033   met:
00034 
00035         * Redistributions of source code must retain the above copyright notice,
00036         this list of conditions and the following disclaimer.
00037         * Redistributions in binary form must reproduce the above copyright notice,
00038         this list of conditions and the following disclaimer in the documentation
00039         and/or other materials provided with the distribution.
00040         * Neither the name of the Case Labs, Ltd nor the names of its contributors
00041         may be used to endorse or promote products derived from this software
00042         without specific prior written permission.
00043 
00044   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00045   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00046   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00047   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00048   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00049   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00050   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00051   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00052   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00053   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00054   POSSIBILITY OF SUCH DAMAGE.
00055 *****************************************************************************/
00056 #include "Q931.h"
00057 #include "Q931priv.h"
00058 #include "Q932.h"
00059 #include "5ESS.h"
00060 
00061 extern L3INT Q931L4HeaderSpace;
00062 extern struct Q931MessageIE ATT5ESSMessageIEs[];
00063 
00064 /*
00065  * ProtDisc 3 (Service/ServiceAck) and 8 (Connect/ConnectAck) share the same message IDs
00066  * Use custom functions to handle them
00067  *
00068  * TODO: Fix this
00069  */
00070 static L3INT ATT5ESSProc0x07TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from);
00071 static L3INT ATT5ESSProc0x0fTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from);
00072 
00073 static L3INT ATT5ESSProcFacilityAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from);
00074 static L3INT ATT5ESSProcFacilityRejectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from);
00075 
00076 void ATT5ESSCreateTE(struct Q931Dialect *dlct)
00077 {
00078         Q931DialectSetName(dlct, "5ESS TE");
00079 
00080         /*
00081          * Flags
00082          */
00083         Q931DialectSetFlag(dlct, 0);
00084 
00085         /*
00086          * Codesets
00087          */
00088         Q931DialectAddCodeset(dlct, Q931_CODESET_0);
00089         Q931DialectAddCodeset(dlct, Q931_CODESET_6);
00090         Q931DialectAddCodeset(dlct, Q931_CODESET_7);
00091 
00092         /*
00093          *
00094          */
00095         Q931DialectSetMesProc(dlct, Q931mes_ALERTING,             Q931ProcAlertingTE,          Q931Umes_Generic, Q931Pmes_Generic);
00096         Q931DialectSetMesProc(dlct, Q931mes_CALL_PROCEEDING,      Q931ProcCallProceedingTE,    Q931Umes_Generic, Q931Pmes_Generic);
00097         Q931DialectSetMesProc(dlct, Q931mes_CONNECT,              ATT5ESSProc0x0fTE,           Q931Umes_Generic, Q931Pmes_Generic);
00098         Q931DialectSetMesProc(dlct, Q931mes_CONNECT_ACKNOWLEDGE,  ATT5ESSProc0x07TE,           Q931Umes_Generic, Q931Pmes_Generic);
00099         Q931DialectSetMesProc(dlct, Q931mes_PROGRESS,             Q931ProcProgressTE,          Q931Umes_Generic, Q931Pmes_Generic);
00100         Q931DialectSetMesProc(dlct, Q931mes_SETUP,                Q931ProcSetupTE,             Q931Umes_Generic, Q931Pmes_Generic);
00101         Q931DialectSetMesProc(dlct, Q931mes_USER_INFORMATION,     Q931ProcUserInformationTE,   Q931Umes_Generic, Q931Pmes_Generic);
00102         Q931DialectSetMesProc(dlct, Q931mes_DISCONNECT,           Q931ProcDisconnectTE,        Q931Umes_Generic, Q931Pmes_Generic);
00103         Q931DialectSetMesProc(dlct, Q931mes_RELEASE,              Q931ProcReleaseTE,           Q931Umes_Generic, Q931Pmes_Generic);
00104         Q931DialectSetMesProc(dlct, Q931mes_RELEASE_COMPLETE,     Q931ProcReleaseCompleteTE,   Q931Umes_Generic, Q931Pmes_Generic);
00105         Q931DialectSetMesProc(dlct, Q931mes_RESTART,              Q931ProcRestartTE,           Q931Umes_Generic, Q931Pmes_Generic);
00106         Q931DialectSetMesProc(dlct, Q931mes_RESTART_ACKNOWLEDGE,  Q931ProcRestartAckTE,        Q931Umes_Generic, Q931Pmes_Generic);
00107         Q931DialectSetMesProc(dlct, Q931mes_CONGESTION_CONTROL,   Q931ProcCongestionControlTE, Q931Umes_Generic, Q931Pmes_Generic);
00108         Q931DialectSetMesProc(dlct, Q931mes_STATUS,               Q931ProcStatusTE,            Q931Umes_Generic, Q931Pmes_Generic);
00109         Q931DialectSetMesProc(dlct, Q931mes_STATUS_ENQUIRY,       Q931ProcStatusEnquiryTE,     Q931Umes_Generic, Q931Pmes_Generic);
00110 
00111         Q931DialectSetMesProc(dlct, Q931mes_FACILITY,             Q932ProcFacilityTE,          Q932Umes_Facility, Q932Pmes_Facility);
00112         Q931DialectSetMesProc(dlct, Q931mes_FACILITY_ACKNOWLEDGE, ATT5ESSProcFacilityAckTE,    Q931Umes_Generic, Q931Pmes_Generic);
00113         Q931DialectSetMesProc(dlct, Q931mes_FACILITY_REJECT,      ATT5ESSProcFacilityRejectTE, Q931Umes_Generic, Q931Pmes_Generic);
00114         Q931DialectSetMesProc(dlct, Q931mes_REGISTER,             Q932ProcRegisterTE,          Q931Umes_Generic, Q931Pmes_Generic);
00115 
00116         /*
00117          * Unknown / Invalid (Unexpected) Message handler
00118          */
00119         Q931DialectSetUnknownMesProc(dlct, Q931ProcUnknownMessage);
00120         Q931DialectSetInvalidMesProc(dlct, Q931ProcUnexpectedMessage);
00121 
00122 
00123         /*
00124          * Set up the IE encoder/decoder handle table.
00125          */
00126         /* Codeset 0 */
00127         Q931DialectSetIEProc(dlct, Q931ie_BEARER_CAPABILITY,                Q931Pie_BearerCap,     Q931Uie_BearerCap,     Q931Die_BearerCap);
00128         Q931DialectSetIEProc(dlct, Q931ie_CAUSE,                            Q931Pie_Cause,         Q931Uie_Cause,         Q931Die_Cause);
00129         Q931DialectSetIEProc(dlct, Q931ie_CALL_STATE,                       Q931Pie_CallState,     Q931Uie_CallState,     Q931Die_CallState);
00130         Q931DialectSetIEProc(dlct, Q931ie_CHANNEL_IDENTIFICATION,           Q931Pie_ChanID,        Q931Uie_ChanID,        Q931Die_ChanID);
00131         Q931DialectSetIEProc(dlct, Q931ie_PROGRESS_INDICATOR,               Q931Pie_ProgInd,       Q931Uie_ProgInd,       Q931Die_ProgInd);
00132         Q931DialectSetIEProc(dlct, Q931ie_NETWORK_SPECIFIC_FACILITIES,      Q931Pie_NetFac,        Q931Uie_NetFac,        Q931Die_Generic);
00133         Q931DialectSetIEProc(dlct, Q931ie_CALLING_PARTY_NUMBER,             Q931Pie_CallingNum,    Q931Uie_CallingNum,    Q931Die_CallingNum);
00134         Q931DialectSetIEProc(dlct, Q931ie_CALLING_PARTY_SUBADDRESS,         Q931Pie_CallingSub,    Q931Uie_CallingSub,    Q931Die_CallingSub);
00135         Q931DialectSetIEProc(dlct, Q931ie_CALLED_PARTY_NUMBER,              Q931Pie_CalledNum,     Q931Uie_CalledNum,     Q931Die_CalledNum);
00136         Q931DialectSetIEProc(dlct, Q931ie_CALLED_PARTY_SUBADDRESS,          Q931Pie_CalledSub,     Q931Uie_CalledSub,     Q931Die_CalledSub);
00137         Q931DialectSetIEProc(dlct, Q931ie_TRANSIT_NETWORK_SELECTION,        Q931Pie_TransNetSel,   Q931Uie_TransNetSel,   Q931Die_Generic);
00138         Q931DialectSetIEProc(dlct, Q931ie_RESTART_INDICATOR,                Q931Pie_RestartInd,    Q931Uie_RestartInd,    Q931Die_RestartInd);
00139         Q931DialectSetIEProc(dlct, Q931ie_LOW_LAYER_COMPATIBILITY,          Q931Pie_LLComp,        Q931Uie_LLComp,        Q931Die_LLComp);
00140         Q931DialectSetIEProc(dlct, Q931ie_HIGH_LAYER_COMPATIBILITY,         Q931Pie_HLComp,        Q931Uie_HLComp,        Q931Die_HLComp);
00141         Q931DialectSetIEProc(dlct, Q931ie_USER_USER,                        Q931Pie_UserUser,      Q931Uie_UserUser,      Q931Die_UserUser);
00142 
00143         Q931DialectSetIEProc(dlct, Q931ie_CONNECTED_NUMBER,                 Q931Pie_Generic,       Q931Uie_Generic,       Q931Die_Generic);
00144         Q931DialectSetIEProc(dlct, Q931ie_REDIRECTING_NUMBER,               Q931Pie_Generic,       Q931Uie_Generic,       Q931Die_Generic);
00145 
00146         /* Codeset 6 */
00147         Q931DialectSetIEProc(dlct, Q932ie_FACILITY,                           Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00148         Q931DialectSetIEProc(dlct, ATT5ESSie_GENERIC_BILLING_DATA,            Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00149         Q931DialectSetIEProc(dlct, ATT5ESSie_ITEM,                            Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00150         Q931DialectSetIEProc(dlct, ATT5ESSie_ORIGINATING_ACCESS_SERVICE_TYPE, Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00151         Q931DialectSetIEProc(dlct, ATT5ESSie_ORIGINATING_LINE_INFORMATION,    Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00152         Q931DialectSetIEProc(dlct, ATT5ESSie_SPECIFIC_EVENT,                  Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00153         Q931DialectSetIEProc(dlct, ATT5ESSie_USER_ENTERED_CODE,               Q931Pie_Generic,      Q931Uie_Generic,      Q931Die_Generic);
00154 
00155         /* Codeset 7 */
00156 
00157 
00158         /* TODO: Restart indicator, */
00159 
00160         /*
00161          * State Table
00162          */
00163 
00164         /*
00165          * Q.931 message <-> ie table
00166          */
00167         Q931DialectSetMesIEMap(dlct, ATT5ESSMessageIEs);
00168 }
00169 
00170 /*****************************************************************************
00171 
00172   Function:             ATT5ESSProc0x0fTE
00173 
00174 *****************************************************************************/
00175 static L3INT ATT5ESSProc0x0fTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00176 {
00177         L3INT ret = Q931E_NO_ERROR;
00178 
00179         switch (msg->ProtDisc) {
00180         case 8:
00181                 return Q931ProcConnectAckTE(trunk, call, msg, from);
00182 
00183         case 3:
00184                 if (from == Q931_MSG_FROM_L4) {
00185                         /* TODO Add proc here*/
00186                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00187                 }
00188                 else if (from == Q931_MSG_FROM_L2) {
00189                         /* TODO Add proc here*/
00190                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00191 
00192                         if (Q931TrunkIsSetFlag(trunk, Q931_TFLAG_AUTO_SERVICE_ACK)) {
00193                                 Q931Log(trunk, Q931_LOG_DEBUG, "autoServiceAck is on, responding to Service Req from network...\n");
00194                                 Q931AckService(trunk, msg);
00195                         }
00196                 }
00197                 return ret;
00198 
00199         default:
00200                 break;
00201         }
00202         return Q931E_NO_ERROR;
00203 }
00204 
00205 /*****************************************************************************
00206 
00207   Function:             ATT5ESSProc0x07TE
00208 
00209 *****************************************************************************/
00210 static L3INT ATT5ESSProc0x07TE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00211 {
00212         L3INT ret = Q931E_NO_ERROR;
00213 
00214         switch (msg->ProtDisc) {
00215         case 8:
00216                 return Q931ProcConnectTE(trunk, call, msg, from);
00217 
00218         case 3:
00219                 if (from == Q931_MSG_FROM_L4) {
00220                         /* TODO Add proc here*/
00221                         ret = Q931Tx32(trunk, 0, msg, msg->Size);
00222                 }
00223                 else if (from == Q931_MSG_FROM_L2) {
00224                         /* TODO Add proc here*/
00225                         ret = Q931Tx34(trunk, call, msg, msg->Size);
00226                 }
00227                 return ret;
00228 
00229         default:
00230                 break;
00231         }
00232         return Q931E_NO_ERROR;
00233 }
00234 
00235 static L3INT ATT5ESSProcFacilityAckTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00236 {
00237         return Q931E_NO_ERROR;
00238 }
00239 
00240 static L3INT ATT5ESSProcFacilityRejectTE(Q931_TrunkInfo_t *trunk, struct Q931_Call *call, Q931mes_Generic *msg, q931_msg_from_t from)
00241 {
00242         return Q931E_NO_ERROR;
00243 }