diff --git a/libs/openzap/msvc/openzap.vcproj b/libs/openzap/msvc/openzap.vcproj index 67565dbb90..c8d612a40f 100644 --- a/libs/openzap/msvc/openzap.vcproj +++ b/libs/openzap/msvc/openzap.vcproj @@ -162,6 +162,10 @@ + + @@ -190,6 +194,18 @@ + + + + + + diff --git a/libs/openzap/src/isdn/DMSStateNT.c b/libs/openzap/src/isdn/DMSStateNT.c new file mode 100644 index 0000000000..6c75029665 --- /dev/null +++ b/libs/openzap/src/isdn/DMSStateNT.c @@ -0,0 +1,126 @@ +/***************************************************************************** + + FileName: DMSStateNT.c + + Contents: DMS-100 ISDN State Engine for NT (Network Mode). + + The controlling state engine for Q.931 is the state engine + on the NT side. The state engine on the TE side is a slave + of this. The TE side maintain it's own states as described in + ITU-T Q931, but will in raise conditions be overridden by + the NT side. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Copyright (c) 2007, Michael Jerris. All rights reserved. + email:mike@jerris.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "DMS.h" + +/***************************************************************************** + Function: DMSCreateNT + + Description: Will create the National ISDN NT as a Dialect in the stack. The first + bulk set up the message handlers, the second bulk the IE + encoders/coders, and the last bulk set up the state table. + + Parameters: i Dialect index +*****************************************************************************/ +void DMSCreateNT(L3UCHAR i) +{ + Q931SetMesProc(Q931mes_ALERTING, i,Q931ProcAlertingNT, Q931Umes_Alerting, Q931Pmes_Alerting); + Q931SetMesProc(Q931mes_CALL_PROCEEDING, i,Q931ProcCallProceedingNT, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); + Q931SetMesProc(Q931mes_CONNECT, i,Q931ProcConnectNT, Q931Umes_Connect, Q931Pmes_Connect); + Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i,Q931ProcConnectAckNT, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); + Q931SetMesProc(Q931mes_PROGRESS, i,Q931ProcProgressNT, Q931Umes_Progress, Q931Pmes_Progress); + Q931SetMesProc(Q931mes_SETUP, i,Q931ProcSetupNT, DMSUmes_Setup, DMSPmes_Setup); + Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i,Q931ProcSetupAckNT, Q931Umes_SetupAck, Q931Pmes_SetupAck); + Q931SetMesProc(Q931mes_RESUME, i,Q931ProcResumeNT, Q931Umes_Resume, Q931Pmes_Resume); + Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i,Q931ProcResumeAckNT, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); + Q931SetMesProc(Q931mes_RESUME_REJECT, i,Q931ProcResumeRejectNT, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); + Q931SetMesProc(Q931mes_SUSPEND, i,Q931ProcSuspendNT, Q931Umes_Suspend, Q931Pmes_Suspend); + Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i,Q931ProcSuspendAckNT, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); + Q931SetMesProc(Q931mes_SUSPEND_REJECT, i,Q931ProcSuspendRejectNT, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); + Q931SetMesProc(Q931mes_USER_INFORMATION, i,Q931ProcUserInformationNT, Q931Umes_UserInformation, Q931Pmes_UserInformation); + Q931SetMesProc(Q931mes_DISCONNECT, i,Q931ProcDisconnectNT, Q931Umes_Disconnect, Q931Pmes_Disconnect); + Q931SetMesProc(Q931mes_RELEASE, i,Q931ProcReleaseNT, Q931Umes_Release, Q931Pmes_Release); + Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i,Q931ProcReleaseCompleteNT, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); + Q931SetMesProc(Q931mes_RESTART, i,Q931ProcRestartNT, Q931Umes_Restart, Q931Pmes_Restart); + Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i,Q931ProcRestartAckNT, Q931Umes_RestartAck, Q931Pmes_RestartAck); + Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i,Q931ProcCongestionControlNT, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); + Q931SetMesProc(Q931mes_INFORMATION, i,Q931ProcInformationNT, Q931Umes_Information, Q931Pmes_Information); + Q931SetMesProc(Q931mes_NOTIFY, i,Q931ProcNotifyNT, Q931Umes_Notify, Q931Pmes_Notify); + Q931SetMesProc(Q931mes_STATUS, i,Q931ProcStatusNT, Q931Umes_Status, Q931Pmes_Status); + Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i,Q931ProcStatusEnquiryNT, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); + Q931SetMesProc(Q931mes_SEGMENT, i,Q931ProcSegmentNT, Q931Umes_Segment, Q931Pmes_Segment); + + Q931SetMesProc(Q932mes_FACILITY, i,Q932ProcFacilityNT, Q932Umes_Facility, Q932Pmes_Facility); + Q931SetMesProc(Q932mes_HOLD, i,Q932ProcHoldNT, Q932Umes_Hold, Q932Pmes_Hold); + Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i,Q932ProcHoldAckNT, Q932Umes_HoldAck, Q932Pmes_HoldAck); + Q931SetMesProc(Q932mes_HOLD_REJECT, i,Q932ProcHoldRejectNT, Q932Umes_HoldReject, Q932Pmes_HoldReject); + Q931SetMesProc(Q932mes_REGISTER, i,Q932ProcRegisterNT, Q932Umes_Register, Q932Pmes_Register); + Q931SetMesProc(Q932mes_RETRIEVE, i,Q932ProcRetrieveNT, Q932Umes_Retrieve, Q932Pmes_Retrieve); + Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE,i,Q932ProcRetrieveAckNT, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); + Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i,Q932ProcRetrieveRejectNT, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); + + /* Set up the IE encoder/decoder handle table.*/ + Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i,Q931Pie_Segment, Q931Uie_Segment); + Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i,Q931Pie_BearerCap, Q931Uie_BearerCap); + Q931SetIEProc(Q931ie_CAUSE, i,Q931Pie_Cause, Q931Uie_Cause); + Q931SetIEProc(Q931ie_CALL_IDENTITY, i,Q931Pie_CallID, Q931Uie_CallID); + Q931SetIEProc(Q931ie_CALL_STATE, i,Q931Pie_CallState, Q931Uie_CallState); + Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i,Q931Pie_ChanID, Q931Uie_ChanID); + Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i,Q931Pie_ProgInd, Q931Uie_ProgInd); + Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i,Q931Pie_NetFac, Q931Uie_NetFac); + Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i,Q931Pie_NotifInd, Q931Uie_NotifInd); + Q931SetIEProc(Q931ie_DISPLAY, i,Q931Pie_Display, Q931Uie_Display); + Q931SetIEProc(Q931ie_DATETIME, i,Q931Pie_DateTime, Q931Uie_DateTime); + Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i,Q931Pie_KeypadFac, Q931Uie_KeypadFac); + Q931SetIEProc(Q931ie_SIGNAL, i,Q931Pie_Signal, Q931Uie_Signal); + Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i,Q931Pie_CallingNum, Q931Uie_CallingNum); + Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i,Q931Pie_CallingSub, Q931Uie_CallingSub); + Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i,Q931Pie_CalledNum, Q931Uie_CalledNum); + Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i,Q931Pie_CalledSub, Q931Uie_CalledSub); + Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_RESTART_INDICATOR, i,Q931Pie_RestartInd, Q931Uie_RestartInd); + Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i,Q931Pie_LLComp, Q931Uie_LLComp); + Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i,Q931Pie_HLComp, Q931Uie_HLComp); + Q931SetIEProc(Q931ie_USER_USER, i,Q931Pie_UserUser, Q931Uie_UserUser); + Q931SetIEProc(Q931ie_GENERIC_DIGITS, i,Q931Pie_GenericDigits, Q931Uie_GenericDigits); + + /* The following define a state machine. The point is that the Message */ + /* procs can when search this to find out if the message/state */ + /* combination is legale. If not, the proc for unexpected message apply.*/ + + /* TODO define state table here */ +} diff --git a/libs/openzap/src/isdn/DMSStateTE.c b/libs/openzap/src/isdn/DMSStateTE.c new file mode 100644 index 0000000000..e508e1ce53 --- /dev/null +++ b/libs/openzap/src/isdn/DMSStateTE.c @@ -0,0 +1,291 @@ +/***************************************************************************** + + FileName: nationalStateTE.c + + Contents: National ISDN State Engine for TE (User Mode). + + The controlling state engine for Q.931 is the state engine + on the NT side. The state engine on the TE side is a slave + of this. The TE side maintain it's own states as described in + ITU-T Q931, but will in raise conditions be overridden by + the NT side. + + This reference implementation uses a process per message, + meaning that each message must check call states. This + is easier for dialect maintenance as each message proc + can be replaced individually. A new TE variant only + need to copy the Q931CreateTE and replace those procs or + need to override. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Copyright (c) 2007, Michael Jerris. All rights reserved. + email:mike@jerris.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "DMS.h" +extern L3INT Q931L4HeaderSpace; + +/***************************************************************************** + Function: DMSCreateTE + + Description: Will create the National TE as a Dialect in the stack. The first + bulk set up the message handlers, the second bulk the IE + encoders/coders, and the last bulk set up the state table. + + Parameters: i Dialect index +*****************************************************************************/ +void DMSCreateTE(L3UCHAR i) +{ + Q931SetMesProc(Q931mes_ALERTING, i,Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); + Q931SetMesProc(Q931mes_CALL_PROCEEDING, i,Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); + Q931SetMesProc(Q931mes_CONNECT, i,DMSProc0x07TE, DMSUmes_0x07, DMSPmes_0x07); + Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i,DMSProc0x0fTE, DMSUmes_0x0f, DMSPmes_0x0f); + Q931SetMesProc(Q931mes_PROGRESS, i,Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); + Q931SetMesProc(Q931mes_SETUP, i,Q931ProcSetupTE, DMSUmes_Setup, DMSPmes_Setup); + Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i,Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); + Q931SetMesProc(Q931mes_RESUME, i,Q931ProcResumeTE, Q931Umes_Resume, Q931Pmes_Resume); + Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i,Q931ProcResumeAckTE, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); + Q931SetMesProc(Q931mes_RESUME_REJECT, i,Q931ProcResumeRejectTE, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); + Q931SetMesProc(Q931mes_SUSPEND, i,Q931ProcSuspendTE, Q931Umes_Suspend, Q931Pmes_Suspend); + Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i,Q931ProcSuspendAckTE, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); + Q931SetMesProc(Q931mes_SUSPEND_REJECT, i,Q931ProcSuspendRejectTE, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); + Q931SetMesProc(Q931mes_USER_INFORMATION, i,Q931ProcUserInformationTE, Q931Umes_UserInformation, Q931Pmes_UserInformation); + Q931SetMesProc(Q931mes_DISCONNECT, i,Q931ProcDisconnectTE, Q931Umes_Disconnect, Q931Pmes_Disconnect); + Q931SetMesProc(Q931mes_RELEASE, i,Q931ProcReleaseTE, Q931Umes_Release, Q931Pmes_Release); + Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i,Q931ProcReleaseCompleteTE, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); + Q931SetMesProc(Q931mes_RESTART, i,Q931ProcRestartTE, Q931Umes_Restart, Q931Pmes_Restart); + Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i,Q931ProcRestartAckTE, Q931Umes_RestartAck, Q931Pmes_RestartAck); + Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i,Q931ProcCongestionControlTE, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); + Q931SetMesProc(Q931mes_INFORMATION, i,Q931ProcInformationTE, Q931Umes_Information, Q931Pmes_Information); + Q931SetMesProc(Q931mes_NOTIFY, i,Q931ProcNotifyTE, Q931Umes_Notify, Q931Pmes_Notify); + Q931SetMesProc(Q931mes_STATUS, i,Q931ProcStatusTE, Q931Umes_Status, Q931Pmes_Status); + Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i,Q931ProcStatusEnquiryTE, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); + Q931SetMesProc(Q931mes_SEGMENT, i,Q931ProcSegmentTE, Q931Umes_Segment, Q931Pmes_Segment); + + Q931SetMesProc(Q932mes_FACILITY, i,Q932ProcFacilityTE, Q932Umes_Facility, Q932Pmes_Facility); + Q931SetMesProc(Q932mes_HOLD, i,Q932ProcHoldTE, Q932Umes_Hold, Q932Pmes_Hold); + Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i,Q932ProcHoldAckTE, Q932Umes_HoldAck, Q932Pmes_HoldAck); + Q931SetMesProc(Q932mes_HOLD_REJECT, i,Q932ProcHoldRejectTE, Q932Umes_HoldReject, Q932Pmes_HoldReject); + Q931SetMesProc(Q932mes_REGISTER, i,Q932ProcRegisterTE, Q932Umes_Register, Q932Pmes_Register); + Q931SetMesProc(Q932mes_RETRIEVE, i,Q932ProcRetrieveTE, Q932Umes_Retrieve, Q932Pmes_Retrieve); + Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE,i,Q932ProcRetrieveAckTE, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); + Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i,Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); + + /* Set up the IE encoder/decoder handle table.*/ + Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i,Q931Pie_Segment, Q931Uie_Segment); + Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i,Q931Pie_BearerCap, Q931Uie_BearerCap); + Q931SetIEProc(Q931ie_CAUSE, i,Q931Pie_Cause, Q931Uie_Cause); + Q931SetIEProc(Q931ie_CALL_IDENTITY, i,Q931Pie_CallID, Q931Uie_CallID); + Q931SetIEProc(Q931ie_CALL_STATE, i,Q931Pie_CallState, Q931Uie_CallState); + Q931SetIEProc(Q931ie_CHANGE_STATUS, i,Q931Pie_ChangeStatus, Q931Uie_ChangeStatus); + Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i,Q931Pie_ChanID, Q931Uie_ChanID); + Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i,Q931Pie_ProgInd, Q931Uie_ProgInd); + Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i,Q931Pie_NetFac, Q931Uie_NetFac); + Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i,Q931Pie_NotifInd, Q931Uie_NotifInd); + Q931SetIEProc(Q931ie_DISPLAY, i,Q931Pie_Display, Q931Uie_Display); + Q931SetIEProc(Q931ie_DATETIME, i,Q931Pie_DateTime, Q931Uie_DateTime); + Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i,Q931Pie_KeypadFac, Q931Uie_KeypadFac); + Q931SetIEProc(Q931ie_SIGNAL, i,Q931Pie_Signal, Q931Uie_Signal); + Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i,Q931Pie_CallingNum, Q931Uie_CallingNum); + Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i,Q931Pie_CallingSub, Q931Uie_CallingSub); + Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i,Q931Pie_CalledNum, Q931Uie_CalledNum); + Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i,Q931Pie_CalledSub, Q931Uie_CalledSub); + Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_RESTART_INDICATOR, i,Q931Pie_RestartInd, Q931Uie_RestartInd); + Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i,Q931Pie_LLComp, Q931Uie_LLComp); + Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i,Q931Pie_HLComp, Q931Uie_HLComp); + Q931SetIEProc(Q931ie_USER_USER, i,Q931Pie_UserUser, Q931Uie_UserUser); + Q931SetIEProc(Q931ie_GENERIC_DIGITS, i,Q931Pie_GenericDigits, Q931Uie_GenericDigits); + + /* The following define a state machine. The point is that the Message */ + /* procs can when search this to find out if the message/state */ + /* combination is legale. If not, the proc for unexpected message apply.*/ + + /* State 0 Idle */ + Q931AddStateEntry(i,Q931_U0, Q931mes_RESUME, 2); + Q931AddStateEntry(i,Q931_U0, Q931mes_SETUP, 4); + Q931AddStateEntry(i,Q931_U0, Q931mes_SETUP, 2); + Q931AddStateEntry(i,Q931_U0, Q931mes_STATUS, 4); + Q931AddStateEntry(i,Q931_U0, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U0, Q931mes_RELEASE_COMPLETE,4); + + /* State 1 Call Initiating */ + Q931AddStateEntry(i,Q931_U1, Q931mes_DISCONNECT, 2); + Q931AddStateEntry(i,Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, 4); + Q931AddStateEntry(i,Q931_U1, Q931mes_RELEASE_COMPLETE,4); + Q931AddStateEntry(i,Q931_U1, Q931mes_CALL_PROCEEDING, 4); + Q931AddStateEntry(i,Q931_U1, Q931mes_ALERTING, 4); + Q931AddStateEntry(i,Q931_U1, Q931mes_CONNECT, 4); + + /* State 2 Overlap Sending */ + Q931AddStateEntry(i,Q931_U2, Q931mes_INFORMATION, 2); + Q931AddStateEntry(i,Q931_U2, Q931mes_CALL_PROCEEDING, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_ALERTING, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_PROGRESS, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_CONNECT, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_RELEASE, 2); + + /* State 3 Outgoing Call Proceeding */ + Q931AddStateEntry(i,Q931_U3, Q931mes_PROGRESS, 4); + Q931AddStateEntry(i,Q931_U3, Q931mes_ALERTING, 4); + Q931AddStateEntry(i,Q931_U3, Q931mes_CONNECT, 4); + Q931AddStateEntry(i,Q931_U3, Q931mes_RELEASE, 2); + + /* State 4 Call Delivered */ + Q931AddStateEntry(i,Q931_U4, Q931mes_CONNECT, 4); + + /* State 6 Call Precent */ + Q931AddStateEntry(i,Q931_U6, Q931mes_INFORMATION, 2); + Q931AddStateEntry(i,Q931_U6, Q931mes_ALERTING, 2); + Q931AddStateEntry(i,Q931_U6, Q931mes_CALL_PROCEEDING,2); + Q931AddStateEntry(i,Q931_U6, Q931mes_CONNECT, 2); + Q931AddStateEntry(i,Q931_U6, Q931mes_RELEASE_COMPLETE,2); + Q931AddStateEntry(i,Q931_U6, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U6, Q931mes_DISCONNECT, 4); + + /* State 7 Call Received */ + Q931AddStateEntry(i,Q931_U7, Q931mes_CONNECT, 2); + + /* State 8 Connect request */ + Q931AddStateEntry(i,Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, 4); + + /* State 9 Incoming Call Proceeding */ + Q931AddStateEntry(i,Q931_U9, Q931mes_CONNECT, 2); + Q931AddStateEntry(i,Q931_U9, Q931mes_ALERTING, 2); + Q931AddStateEntry(i,Q931_U9, Q931mes_PROGRESS, 2); + + /* State 10 Active */ + Q931AddStateEntry(i,Q931_U10, Q931mes_SUSPEND, 2); + Q931AddStateEntry(i,Q931_U10, Q931mes_NOTIFY, 4); + Q931AddStateEntry(i,Q931_U10, Q931mes_NOTIFY, 2); + + /* State 11 Disconnect Request */ + Q931AddStateEntry(i,Q931_U11, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U11, Q931mes_DISCONNECT, 4); + Q931AddStateEntry(i,Q931_U11, Q931mes_NOTIFY, 4); + + /* State 12 Disconnect Ind */ + Q931AddStateEntry(i,Q931_U12, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U12, Q931mes_RELEASE, 2); + + /* State 15 Suspend Request */ + Q931AddStateEntry(i,Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, 4); + Q931AddStateEntry(i,Q931_U15, Q931mes_SUSPEND_REJECT, 4); + Q931AddStateEntry(i,Q931_U15, Q931mes_DISCONNECT, 4); + Q931AddStateEntry(i,Q931_U15, Q931mes_RELEASE, 4); + +/* TODO + Q931AddStateEntry(i,Q931_U17, + Q931AddStateEntry(i,Q931_U19, + Q931AddStateEntry(i,Q931_U25, +*/ +} + +/***************************************************************************** + + Function: DMSProc0x0fTE + +*****************************************************************************/ +L3INT DMSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + if (pMes->ProtDisc == 8) { + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + } + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + + if (pMes->ProtDisc == 3 && pTrunk->autoServiceAck) { + Q931AckService(pTrunk, buf); + } + + } + return ret; + +} + +/***************************************************************************** + + Function: DMSProc0x07TE + +*****************************************************************************/ +L3INT DMSProc0x07TE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + if (pMes->ProtDisc == 8) { + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + } + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; + +} diff --git a/libs/openzap/src/isdn/DMSmes.c b/libs/openzap/src/isdn/DMSmes.c new file mode 100644 index 0000000000..57aeddfb0d --- /dev/null +++ b/libs/openzap/src/isdn/DMSmes.c @@ -0,0 +1,338 @@ +/***************************************************************************** + + FileName: DMSmes.c + + Contents: Pack/Unpack functions. These functions will unpack a DMS-100 ISDN + message from the bit packed original format into structs + that contains variables sized by the user. It will also pack + the struct back into a Q.931 message as required. + + See national.h for description. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Copyright (c) 2007, Michael Jerris. All rights reserved. + email:mike@jerris.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*****************************************************************************/ + +#include "DMS.h" + +/***************************************************************************** + + Function: DMSUmes_Setup + +*****************************************************************************/ +L3INT DMSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) +{ + L3INT ir=0; + L3INT OOff=0; + L3INT rc=Q931E_NO_ERROR; + L3UCHAR last_codeset = 0, codeset = 0; + L3UCHAR shift_lock = 1; + + while(IOff < Size) + { + if (!shift_lock) { + codeset = last_codeset; + } + + if ((IBuf[IOff] & 0xF0) == Q931ie_SHIFT ) { + shift_lock = (IBuf[IOff] & 0x08); + if (shift_lock) { + last_codeset = codeset; + } + codeset = ((IBuf[IOff] & 0x07)); + IOff++; + } + + if (codeset == 0) { + switch(IBuf[IOff]) + { + case Q931ie_SENDING_COMPLETE: + case Q931ie_BEARER_CAPABILITY: + case Q931ie_CHANNEL_IDENTIFICATION: + case Q931ie_PROGRESS_INDICATOR: + case Q931ie_NETWORK_SPECIFIC_FACILITIES: + case Q931ie_DISPLAY: + case Q931ie_DATETIME: + case Q931ie_KEYPAD_FACILITY: + case Q931ie_SIGNAL: + case Q931ie_CALLING_PARTY_NUMBER: + case Q931ie_CALLING_PARTY_SUBADDRESS: + case Q931ie_CALLED_PARTY_NUMBER: + case Q931ie_CALLED_PARTY_SUBADDRESS: + case Q931ie_TRANSIT_NETWORK_SELECTION: + case Q931ie_LOW_LAYER_COMPATIBILITY: + case Q931ie_HIGH_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_REPEAT_INDICATOR: + if(ir < 2) { + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + ir++; + } else { + return Q931E_ILLEGAL_IE; + } + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } else if (codeset == 6) { + switch(IBuf[IOff]) + { + case Q931ie_GENERIC_DIGITS: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + + } else { + return Q931E_ILLEGAL_IE; + } + } + mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: DMSPmes_Setup + + Decription: Pack a Q931mes_Generic into a real Q.931 message. The user will + set up a SETUP message and issue this to the stack where it + is processed by Q931ProcSetup that processes and validates + it before it actually sends it out. This function is called + to compute the real Q.931 message. + + Parameters: IBuf[IN] Ptr to un-packed struct + ISize[IN] Size of input buffer (unpacked message). + OBuf[OUT] Ptr to packed 'octet' wise message. + OSize[OUT] Size of packed message. + + Called By: Q931ProcSetup + +*****************************************************************************/ +L3INT DMSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8) | (pMes->CRVFlag << 7); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Sending Complete */ + if(Q931IsIEPresent(pMes->SendComplete)) + OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); + + /* Repeat Indicator */ + if(Q931IsIEPresent(pMes->RepeatInd)) + OBuf[Octet++] = (L3UCHAR)(pMes->RepeatInd & 0x00ff); + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + else + { + rc=Q931E_BEARERCAP; + } + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Network spesific facilities */ + if(Q931IsIEPresent(pMes->NetFac)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_NETWORK_SPECIFIC_FACILITIES](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Date/Time */ + if(Q931IsIEPresent(pMes->DateTime)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Keypad Facility */ + if(Q931IsIEPresent(pMes->KeypadFac)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Calling Party Number */ + if(Q931IsIEPresent(pMes->CallingNum)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Calling Party Subaddress */ + if(Q931IsIEPresent(pMes->CallingSub)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Called Party number */ + if(Q931IsIEPresent(pMes->CalledNum)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Called party subaddress */ + if(Q931IsIEPresent(pMes->CalledSub)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Transit network selection */ + if(Q931IsIEPresent(pMes->TransNetSel)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_TRANSIT_NETWORK_SELECTION](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Repeat Indicator */ + if(Q931IsIEPresent(pMes->LLRepeatInd)) + rc = Q931E_UNKNOWN_IE;/* TODO */ + + /* Low Layer Compatibility */ + if(Q931IsIEPresent(pMes->LLComp)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* High Layer Compatibility */ + if(Q931IsIEPresent(pMes->HLComp)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + *OSize = Octet; + + return rc; +} + + +/***************************************************************************** + + Function: DMSUmes_0x0f + +*****************************************************************************/ +L3INT DMSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) +{ + if (mes->ProtDisc == 8) { + return Q931Umes_ConnectAck(pTrunk, IBuf, mes, IOff, Size); + } + + if (mes->ProtDisc == 3) { + return Q931Umes_Service(pTrunk, IBuf, mes, IOff, Size); + } + + return Q931E_UNKNOWN_MESSAGE; +} + +/***************************************************************************** + + Function: DMSPmes_0x0f + +*****************************************************************************/ +L3INT DMSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + Q931mes_Generic *mes = (Q931mes_Generic *)IBuf; + + if (mes->ProtDisc == 8) { + return Q931Pmes_ConnectAck(pTrunk, IBuf, ISize, OBuf, OSize); + } + + if (mes->ProtDisc == 3) { + return Q931Pmes_Service(pTrunk, IBuf, ISize, OBuf, OSize); + } + + return Q931E_UNKNOWN_MESSAGE; +} + +/***************************************************************************** + + Function: DMSUmes_0x07 + +*****************************************************************************/ +L3INT DMSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) +{ + if (mes->ProtDisc == 8) { + return Q931Umes_Connect(pTrunk, IBuf, mes, IOff, Size); + } + + if (mes->ProtDisc == 3) { + return Q931Umes_ServiceAck(pTrunk, IBuf, mes, IOff, Size); + } + + return Q931E_UNKNOWN_MESSAGE; +} + +/***************************************************************************** + + Function: DMSPmes_0x07 + +*****************************************************************************/ +L3INT DMSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + Q931mes_Generic *mes = (Q931mes_Generic *)IBuf; + + if (mes->ProtDisc == 8) { + return Q931Pmes_Connect(pTrunk, IBuf, ISize, OBuf, OSize); + } + + if (mes->ProtDisc == 3) { + return Q931Pmes_ServiceAck(pTrunk, IBuf, ISize, OBuf, OSize); + } + + return Q931E_UNKNOWN_MESSAGE; +} diff --git a/libs/openzap/src/isdn/Q931.c b/libs/openzap/src/isdn/Q931.c index 232b2122c3..098c1a44b3 100644 --- a/libs/openzap/src/isdn/Q931.c +++ b/libs/openzap/src/isdn/Q931.c @@ -38,6 +38,7 @@ #include "Q931.h" #include "national.h" +#include "DMS.h" /***************************************************************************** @@ -261,6 +262,12 @@ void Q931Initialize() if(Q931CreateDialectCB[Q931_Dialect_National + Q931_NT] == NULL) Q931AddDialect(Q931_Dialect_National + Q931_NT, nationalCreateNT); + if(Q931CreateDialectCB[Q931_Dialect_DMS + Q931_TE] == NULL) + Q931AddDialect(Q931_Dialect_DMS + Q931_TE, DMSCreateTE); + + if(Q931CreateDialectCB[Q931_Dialect_DMS + Q931_NT] == NULL) + Q931AddDialect(Q931_Dialect_DMS + Q931_NT, DMSCreateNT); + /* The last step we do is to call the callbacks to create the dialects */ for(x=0; x< Q931MAXDLCT; x++) { diff --git a/libs/openzap/src/isdn/Q931api.c b/libs/openzap/src/isdn/Q931api.c index 541b28d428..0a6d3a6733 100644 --- a/libs/openzap/src/isdn/Q931api.c +++ b/libs/openzap/src/isdn/Q931api.c @@ -562,5 +562,20 @@ L3INT Q931AckConnect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) return RetCode; } +L3INT Q931AckService(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) +{ + L3INT RetCode; + + Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; + ptr->MesType = Q931mes_SERVICE_ACKNOWLEDGE; + if (ptr->CRV) { + ptr->CRVFlag = !(ptr->CRVFlag); + } + + RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4); + + return RetCode; +} + Q931_ENUM_NAMES(DIALECT_TYPE_NAMES, DIALECT_STRINGS) Q931_STR2ENUM(q931_str2Q931Diaelct_type, q931_Q931Diaelct_type2str, Q931Dialect_t, DIALECT_TYPE_NAMES, Q931_Dialect_Count) diff --git a/libs/openzap/src/isdn/Q931ie.c b/libs/openzap/src/isdn/Q931ie.c index 2f4fa60b07..1973d20c41 100644 --- a/libs/openzap/src/isdn/Q931ie.c +++ b/libs/openzap/src/isdn/Q931ie.c @@ -3079,3 +3079,80 @@ L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OB return Q931E_NO_ERROR; } + +/***************************************************************************** + + Function: Q931Uie_ChangeStatus + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_ChangeStatus * pie = (Q931ie_ChangeStatus*)OBuf; + ie *pIE = &pMsg->ChangeStatus; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->Preference = (IBuf[Octet+Off] >> 6) & 0x01; + pie->Spare = IBuf[Octet+Off] & 0x38; + pie->NewStatus = IBuf[Octet+Off] & 0x07; + + Octet++; + + Q931SetIE(*pIE, *OOff); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_ChangeStatus); + pie->Size = sizeof(Q931ie_ChangeStatus); + + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_ChangeStatus + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_ChangeStatus * pIE = (Q931ie_ChangeStatus*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_CHANGE_STATUS; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = 0x80 | pIE->NewStatus | ((pIE->Preference & 0x01) << 6); + + OBuf[li] = (L3UCHAR)((*Octet)-Beg) - 2; + return rc; +} diff --git a/libs/openzap/src/isdn/Q931mes.c b/libs/openzap/src/isdn/Q931mes.c index d4229fe958..497e6c1a94 100644 --- a/libs/openzap/src/isdn/Q931mes.c +++ b/libs/openzap/src/isdn/Q931mes.c @@ -1770,3 +1770,134 @@ L3INT Q931Pmes_UserInformation(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, return RetCode; } +/***************************************************************************** + + Function: Q931Umes_Service + +*****************************************************************************/ +L3INT Q931Umes_Service(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) +{ + L3INT OOff=0; + L3INT rc=Q931E_NO_ERROR; + + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CHANGE_STATUS: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Service + +*****************************************************************************/ +L3INT Q931Pmes_Service(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8) | (pMes->CRVFlag << 7); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Display */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + if(Q931IsIEPresent(pMes->ChangeStatus)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CHANGE_STATUS](pTrunk, Q931GetIEPtr(pMes->ChangeStatus,pMes->buf), OBuf, &Octet))!=0) + return rc; + + *OSize = Octet; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_ServiceAck + +*****************************************************************************/ +L3INT Q931Umes_ServiceAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) +{ + L3INT OOff=0; + L3INT rc=Q931E_NO_ERROR; + + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CHANGE_STATUS: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_ServiceAck + +*****************************************************************************/ +L3INT Q931Pmes_ServiceAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8) | (pMes->CRVFlag << 7); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Display */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + if(Q931IsIEPresent(pMes->ChangeStatus)) + if((rc=Q931Pie[pTrunk->Dialect][Q931ie_CHANGE_STATUS](pTrunk, Q931GetIEPtr(pMes->ChangeStatus,pMes->buf), OBuf, &Octet))!=0) + return rc; + + *OSize = Octet; + + return rc; +} diff --git a/libs/openzap/src/isdn/include/DMS.h b/libs/openzap/src/isdn/include/DMS.h new file mode 100644 index 0000000000..35d10d7b5b --- /dev/null +++ b/libs/openzap/src/isdn/include/DMS.h @@ -0,0 +1,95 @@ +/****************************************************************************** + + FileName: national.h + + Contents: Header and definition for the National ISDN dialect. The + header contents the following parts: + + - Definition of codes + - Definition of information elements (nationalie_). + - Definition of messages (nationalmes_). + - Function prototypes. + + Description: The National ISDN dialect here covers ???? + + Related Files: national.h National ISDN Definitions + nationalie.c National ISDN IE encoders/coders + nationalStateTE.c National ISDN TE State Engine + nationalStateNT.c National ISDN NT State Engine + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Copyright (c) 2007, Michael Jerris. All rights reserved. + email:mike@jerris.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +******************************************************************************/ + +#ifndef _DMS_NL +#define _DMS_NL + +#include "Q931.h" + +/***************************************************************************** + + Q.931 Message codes + Only National specific message and ie types + here the rest are inherited from national.h + +*****************************************************************************/ + + +/***************************************************************************** + + Q.931 Message Pack/Unpack functions. Implemented in nationalmes.c + +*****************************************************************************/ +L3INT DMSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); +L3INT DMSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT DMSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); +L3INT DMSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT DMSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); +L3INT DMSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); + + + +/***************************************************************************** + + Q.931 Process Function Prototyping. Implemented in nationalStateTE.c + +*****************************************************************************/ + +L3INT DMSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); +L3INT DMSProc0x07TE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); + + +void DMSCreateTE(L3UCHAR i); +void DMSCreateNT(L3UCHAR i); + +#endif /* _DMS_NL */ diff --git a/libs/openzap/src/isdn/include/Q931.h b/libs/openzap/src/isdn/include/Q931.h index ce74a4e0fc..ee92e48b26 100644 --- a/libs/openzap/src/isdn/include/Q931.h +++ b/libs/openzap/src/isdn/include/Q931.h @@ -283,7 +283,7 @@ typedef L3USHORT ie; /* Special data type to hold a dynamic */ /* WARNING! Initialize Q931CreateDialectCB[] will NULL when increasing the */ /* Q931MAXDLCT value to avoid Q931Initialize from crashing if one entry is */ /* not used. */ -#define Q931MAXDLCT 4 /* Max dialects included in this */ +#define Q931MAXDLCT 6 /* Max dialects included in this */ /* compile. User and Network count as */ /* one dialect each. */ @@ -377,6 +377,9 @@ typedef L3USHORT ie; /* Special data type to hold a dynamic */ #define Q931mes_STATUS_ENQUIRY 0x75 /* 0111 0101 */ #define Q931mes_SEGMENT 0x60 /* 0110 0000 */ +#define Q931mes_SERVICE 0x0f /* 0000 1111 */ +#define Q931mes_SERVICE_ACKNOWLEDGE 0x07 /* 0000 0111 */ + /***************************************************************************** @@ -422,6 +425,7 @@ typedef struct ie CallState; /* Call State */ ie CallID; /* Call Identity */ ie ChanID; /* Channel Identification */ + ie ChangeStatus; /* Change Staus */ ie ProgInd; /* Progress Indicator */ ie NetFac; /* Network Spesific Facilities */ ie NotifInd; /* Notification Indicator */ @@ -488,10 +492,11 @@ typedef enum /* Dialect enum */ { Q931_Dialect_Q931 = 0, Q931_Dialect_National = 2, + Q931_Dialect_DMS = 4, Q931_Dialect_Count } Q931Dialect_t; -#define DIALECT_STRINGS "q931", "", "national" +#define DIALECT_STRINGS "q931", "", "national", "", "dms" Q931_STR2ENUM_P(q931_str2Q931Diaelct_type, q931_Q931Diaelct_type2str, Q931Dialect_t) typedef enum /* Trunk Line Type. */ @@ -557,7 +562,10 @@ struct Q931_TrunkInfo L3BOOL autoRestartAck; /* Indicate if the stack should send */ /* RESTART ACK or not. 0=No, 1=Yes. */ - /* channel array holding info per channel. Usually defined to 32 */ + L3BOOL autoServiceAck; /* Indicate if the stack should send */ + /* SERVICE ACK or not. 0=No, 1=Yes. */ + + /* channel array holding info per channel. Usually defined to 32 */ /* channels to fit an E1 since T1/J1 and BRI will fit inside a E1. */ struct _charray { @@ -786,6 +794,9 @@ L3INT Q931Pmes_Notify(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISi L3INT Q931Pmes_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); L3INT Q931Pmes_Status(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); L3INT Q931Pmes_StatusEnquiry(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Service(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_ServiceAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); + L3INT Q931Umes_Alerting(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); L3INT Q931Umes_CallProceeding(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); @@ -812,6 +823,9 @@ L3INT Q931Umes_Notify(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * L3INT Q931Umes_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); L3INT Q931Umes_Status(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); L3INT Q931Umes_StatusEnquiry(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Service(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); +L3INT Q931Umes_ServiceAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); + /***************************************************************************** @@ -943,6 +957,7 @@ L3INT Q931ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); L3INT Q931AckRestart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); L3INT Q931AckConnect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); L3INT Q931AckSetup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); +L3INT Q931AckService(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); L3INT Q931Api_InitTrunk(Q931_TrunkInfo_t *pTrunk, Q931Dialect_t Dialect, diff --git a/libs/openzap/src/isdn/include/Q931ie.h b/libs/openzap/src/isdn/include/Q931ie.h index dbca5b3990..5b0e7314a5 100644 --- a/libs/openzap/src/isdn/include/Q931ie.h +++ b/libs/openzap/src/isdn/include/Q931ie.h @@ -1068,6 +1068,18 @@ typedef struct /* 111 All interfaces */ }Q931ie_RestartInd; +typedef struct +{ + L3UCHAR IEId; /* 01110100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Preference; /* Preference 0 = reserved, 1 = channel */ + L3UCHAR Spare; /* Spare */ + L3UCHAR NewStatus; /* NewStatus */ + /* 000 In service */ + /* 001 Maintenance */ + /* 010 Out of service */ +}Q931ie_ChangeStatus; + /***************************************************************************** Struct: Q931ie_GenericDigits @@ -1090,7 +1102,7 @@ typedef struct Q.931 Information Element Pack/Unpack functions. Implemented in Q931ie.c *****************************************************************************/ - +q931pie_func_t Q931Pie_ChangeStatus; q931pie_func_t Q931Pie_BearerCap; q931pie_func_t Q931Pie_ChanID; q931pie_func_t Q931Pie_ProgInd; @@ -1121,6 +1133,7 @@ q931pie_func_t Q931Pie_GenericDigits; L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk,L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff); +q931uie_func_t Q931Uie_ChangeStatus; q931uie_func_t Q931Uie_BearerCap; q931uie_func_t Q931Uie_ChanID; q931uie_func_t Q931Uie_ProgInd; diff --git a/libs/openzap/src/isdn/include/national.h b/libs/openzap/src/isdn/include/national.h index 983a6de1dc..c47daf4ed9 100644 --- a/libs/openzap/src/isdn/include/national.h +++ b/libs/openzap/src/isdn/include/national.h @@ -72,7 +72,8 @@ *****************************************************************************/ L3INT nationalUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); L3INT nationalPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT DMSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); + +#include "DMS.h" /***************************************************************************** diff --git a/libs/openzap/src/isdn/nationalStateTE.c b/libs/openzap/src/isdn/nationalStateTE.c index 289e9c9de9..efd1d81ea2 100644 --- a/libs/openzap/src/isdn/nationalStateTE.c +++ b/libs/openzap/src/isdn/nationalStateTE.c @@ -53,7 +53,6 @@ #include "national.h" extern L3INT Q931L4HeaderSpace; -L3INT DMSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); /***************************************************************************** Function: nationalCreateTE @@ -68,8 +67,8 @@ void nationalCreateTE(L3UCHAR i) { Q931SetMesProc(Q931mes_ALERTING, i,Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); Q931SetMesProc(Q931mes_CALL_PROCEEDING, i,Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i,Q931ProcConnectTE, Q931Umes_Connect, Q931Pmes_Connect); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i,DMSProc0x0fTE, DMSUmes_0x0f, Q931Pmes_ConnectAck); + Q931SetMesProc(Q931mes_CONNECT, i,DMSProc0x07TE, DMSUmes_0x07, DMSPmes_0x07); + Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i,DMSProc0x0fTE, DMSUmes_0x0f, DMSPmes_0x0f); Q931SetMesProc(Q931mes_PROGRESS, i,Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); Q931SetMesProc(Q931mes_SETUP, i,Q931ProcSetupTE, nationalUmes_Setup, nationalPmes_Setup); Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i,Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); @@ -107,6 +106,7 @@ void nationalCreateTE(L3UCHAR i) Q931SetIEProc(Q931ie_CAUSE, i,Q931Pie_Cause, Q931Uie_Cause); Q931SetIEProc(Q931ie_CALL_IDENTITY, i,Q931Pie_CallID, Q931Uie_CallID); Q931SetIEProc(Q931ie_CALL_STATE, i,Q931Pie_CallState, Q931Uie_CallState); + Q931SetIEProc(Q931ie_CHANGE_STATUS, i,Q931Pie_ChangeStatus, Q931Uie_ChangeStatus); Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i,Q931Pie_ChanID, Q931Uie_ChanID); Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i,Q931Pie_ProgInd, Q931Uie_ProgInd); Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i,Q931Pie_NetFac, Q931Uie_NetFac); @@ -211,39 +211,3 @@ void nationalCreateTE(L3UCHAR i) */ } -/***************************************************************************** - - Function: Q931ProcConnectAckTE - -*****************************************************************************/ -L3INT DMSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - L3INT callIndex; - L3INT ret=Q931E_NO_ERROR; - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - - if (pMes->ProtDisc == 8) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if(ret != Q931E_NO_ERROR) - return ret; - - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, 303); - } - if(iFrom == 4) - { - /* TODO Add proc here*/ - ret = Q931Tx32(pTrunk,buf,pMes->Size); - } - else if (iFrom ==2) - { - /* TODO Add proc here*/ - ret = Q931Tx34(pTrunk,buf,pMes->Size); - } - return ret; - -} diff --git a/libs/openzap/src/isdn/nationalmes.c b/libs/openzap/src/isdn/nationalmes.c index 75e313d90d..81361bd70d 100644 --- a/libs/openzap/src/isdn/nationalmes.c +++ b/libs/openzap/src/isdn/nationalmes.c @@ -261,40 +261,3 @@ L3INT nationalPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT } -/***************************************************************************** - - Function: DMSUmes_0x0f - -*****************************************************************************/ -L3INT DMSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -//L3INT Q931Umes_ConnectAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff=0; - L3INT rc=Q931E_NO_ERROR; - - if (mes->ProtDisc == 8) { - return Q931Umes_ConnectAck(pTrunk, IBuf, mes, IOff, Size); - } - - while(IOff < Size) - { - switch(IBuf[IOff]) - { - case Q931ie_CHANNEL_IDENTIFICATION: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if(rc != Q931E_NO_ERROR) - return rc; - break; - case Q931ie_CHANGE_STATUS: - rc = Q931Uie[pTrunk->Dialect][Q931ie_RESTART_INDICATOR](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if(rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} diff --git a/libs/openzap/src/zap_isdn.c b/libs/openzap/src/zap_isdn.c index db5ffdfadb..e898a7927b 100644 --- a/libs/openzap/src/zap_isdn.c +++ b/libs/openzap/src/zap_isdn.c @@ -46,7 +46,7 @@ static L2ULONG zap_time_now() { - return zap_current_time_in_ms(); + return (L2ULONG)zap_current_time_in_ms(); } static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call) @@ -79,86 +79,129 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) } zap_log(ZAP_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d]\n", gen->MesType, gen->Size); - switch(gen->MesType) { - case Q931mes_RESTART: - { - if (zchan) { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); - } else { - uint32_t i; - for (i = 0; i < span->chan_count; i++) { - zap_set_state_locked((&span->channels[i]), ZAP_CHANNEL_STATE_RESTART); + +#if 0 + typedef struct +{ + L3UCHAR IEId; /* 01110100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Preference; /* Preference 0 = reserved, 1 = channel */ + L3UCHAR Spare; /* Spare */ + L3UCHAR NewStatus; /* NewStatus */ + /* 000 In service */ + /* 001 Maintenance */ + /* 010 Out of service */ +}Q931ie_ChangeStatus; + +#endif + if (gen->ProtDisc == 3) { + switch(gen->MesType) { + case Q931mes_SERVICE: + { + Q931ie_ChangeStatus *changestatus = Q931GetIEPtr(gen->ChangeStatus, gen->buf); + /* TODO: Handle this properly */ + if (zchan) { + switch (changestatus->NewStatus) { + case 0: /* change status to "in service" */ + //zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); + break; + case 1: /* change status to "maintenance" */ + //zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); + break; + case 2: /* change status to "out of service" */ + //zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); + break; + default: /* unknown */ + break; + } } } + break; + default: + break; } - break; - case Q931mes_RELEASE_COMPLETE: - { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); - } - break; - case Q931mes_DISCONNECT: - { - Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf); - zchan->caller_data.hangup_cause = cause->Value; - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING); - } - break; - case Q931mes_ALERTING: - { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); - } - break; - case Q931mes_PROGRESS: - { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS); - } - break; - case Q931mes_CONNECT: - { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_UP); - } - break; - case Q931mes_SETUP: - { - - Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf); - Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf); - zap_status_t status; - int fail = 1; - uint32_t cplen = mlen; - - - if ((status = zap_channel_open(span->span_id, chan_id, &zchan) == ZAP_SUCCESS)) { - if (zchan->state == ZAP_CHANNEL_STATE_DOWN) { - memset(&zchan->caller_data, 0, sizeof(zchan->caller_data)); - - zap_set_string(zchan->caller_data.cid_num, (char *)callingnum->Digit); - zap_set_string(zchan->caller_data.cid_name, (char *)callingnum->Digit); - zap_set_string(zchan->caller_data.ani, (char *)callingnum->Digit); - zap_set_string(zchan->caller_data.dnis, (char *)callednum->Digit); - - zchan->caller_data.CRV = gen->CRV; - if (cplen > sizeof(zchan->caller_data.raw_data)) { - cplen = sizeof(zchan->caller_data.raw_data); + } else { + switch(gen->MesType) { + case Q931mes_RESTART: + { + if (zchan) { + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); + } else { + uint32_t i; + for (i = 0; i < span->chan_count; i++) { + zap_set_state_locked((&span->channels[i]), ZAP_CHANNEL_STATE_RESTART); } - gen->CRVFlag = !(gen->CRVFlag); - memcpy(zchan->caller_data.raw_data, msg, cplen); - zchan->caller_data.raw_data_len = cplen; - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING); - fail = 0; - } - } - - if (fail) { - zap_log(ZAP_LOG_CRIT, "FIX ME!\n"); - // add me + } } - + break; + case Q931mes_RELEASE_COMPLETE: + { + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); + } + break; + case Q931mes_DISCONNECT: + { + Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf); + zchan->caller_data.hangup_cause = cause->Value; + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING); + } + break; + case Q931mes_ALERTING: + { + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); + } + break; + case Q931mes_PROGRESS: + { + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS); + } + break; + case Q931mes_CONNECT: + { + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_UP); + } + break; + case Q931mes_SETUP: + { + + Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf); + Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf); + zap_status_t status; + int fail = 1; + uint32_t cplen = mlen; + + + if ((status = zap_channel_open(span->span_id, chan_id, &zchan) == ZAP_SUCCESS)) { + if (zchan->state == ZAP_CHANNEL_STATE_DOWN) { + memset(&zchan->caller_data, 0, sizeof(zchan->caller_data)); + + zap_set_string(zchan->caller_data.cid_num, (char *)callingnum->Digit); + zap_set_string(zchan->caller_data.cid_name, (char *)callingnum->Digit); + zap_set_string(zchan->caller_data.ani, (char *)callingnum->Digit); + zap_set_string(zchan->caller_data.dnis, (char *)callednum->Digit); + + zchan->caller_data.CRV = gen->CRV; + if (cplen > sizeof(zchan->caller_data.raw_data)) { + cplen = sizeof(zchan->caller_data.raw_data); + } + gen->CRVFlag = !(gen->CRVFlag); + memcpy(zchan->caller_data.raw_data, msg, cplen); + zchan->caller_data.raw_data_len = cplen; + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING); + fail = 0; + } + } + + if (fail) { + zap_log(ZAP_LOG_CRIT, "FIX ME!\n"); + // add me + } + + } + break; + default: + break; } - break; - default: - break; } return 0; @@ -632,6 +675,7 @@ zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931D isdn_data->q931.autoRestartAck = 1; isdn_data->q931.autoConnectAck = 1; + isdn_data->q931.autoServiceAck = 1; span->signal_data = isdn_data; span->signal_type = ZAP_SIGTYPE_ISDN; span->outgoing_call = isdn_outgoing_call;