cleanup of service message handling, add separate dialects for dms and national.

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@290 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Michael Jerris 2007-06-25 16:00:24 +00:00
parent 84e8ad398e
commit ce36f85c1d
15 changed files with 1252 additions and 156 deletions

View File

@ -162,6 +162,10 @@
<Filter
Name="Header Files"
>
<File
RelativePath="..\src\isdn\include\DMS.h"
>
</File>
<File
RelativePath="..\src\isdn\include\mfifo.h"
>
@ -190,6 +194,18 @@
<Filter
Name="Source Files"
>
<File
RelativePath="..\src\isdn\DMSmes.c"
>
</File>
<File
RelativePath="..\src\isdn\DMSStateNT.c"
>
</File>
<File
RelativePath="..\src\isdn\DMSStateTE.c"
>
</File>
<File
RelativePath="..\src\isdn\EuroISDNStateNT.c"
>

View File

@ -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 */
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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++)
{

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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,

View File

@ -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;

View File

@ -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"
/*****************************************************************************

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;