]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
cleanup of service message handling, add separate dialects for dms and national.
authorMichael Jerris <mike@jerris.com>
Mon, 25 Jun 2007 16:00:24 +0000 (16:00 +0000)
committerMichael Jerris <mike@jerris.com>
Mon, 25 Jun 2007 16:00:24 +0000 (16:00 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@290 a93c3328-9c30-0410-af19-c9cd2b2d52af

15 files changed:
libs/openzap/msvc/openzap.vcproj
libs/openzap/src/isdn/DMSStateNT.c [new file with mode: 0644]
libs/openzap/src/isdn/DMSStateTE.c [new file with mode: 0644]
libs/openzap/src/isdn/DMSmes.c [new file with mode: 0644]
libs/openzap/src/isdn/Q931.c
libs/openzap/src/isdn/Q931api.c
libs/openzap/src/isdn/Q931ie.c
libs/openzap/src/isdn/Q931mes.c
libs/openzap/src/isdn/include/DMS.h [new file with mode: 0644]
libs/openzap/src/isdn/include/Q931.h
libs/openzap/src/isdn/include/Q931ie.h
libs/openzap/src/isdn/include/national.h
libs/openzap/src/isdn/nationalStateTE.c
libs/openzap/src/isdn/nationalmes.c
libs/openzap/src/zap_isdn.c

index 67565dbb90a994304bad3b4df4dee898e5a5361c..c8d612a40f242c79f0d15e2d84f490c0596fb2ce 100644 (file)
                                <Filter\r
                                        Name="Header Files"\r
                                        >\r
+                                       <File\r
+                                               RelativePath="..\src\isdn\include\DMS.h"\r
+                                               >\r
+                                       </File>\r
                                        <File\r
                                                RelativePath="..\src\isdn\include\mfifo.h"\r
                                                >\r
                                <Filter\r
                                        Name="Source Files"\r
                                        >\r
+                                       <File\r
+                                               RelativePath="..\src\isdn\DMSmes.c"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
+                                               RelativePath="..\src\isdn\DMSStateNT.c"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
+                                               RelativePath="..\src\isdn\DMSStateTE.c"\r
+                                               >\r
+                                       </File>\r
                                        <File\r
                                                RelativePath="..\src\isdn\EuroISDNStateNT.c"\r
                                                >\r
diff --git a/libs/openzap/src/isdn/DMSStateNT.c b/libs/openzap/src/isdn/DMSStateNT.c
new file mode 100644 (file)
index 0000000..6c75029
--- /dev/null
@@ -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 (file)
index 0000000..e508e1c
--- /dev/null
@@ -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 (file)
index 0000000..57aeddf
--- /dev/null
@@ -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;
+}
index 232b2122c38d8be6f747e88977313d79815c6f05..098c1a44b30daff0545e4c0b03c78270482f5a29 100644 (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++)
        {
index 541b28d4281e1c6327f71bff92d1ed45f5af5d13..0a6d3a6733490c01ae33a4615b82744747373a86 100644 (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)
index 2f4fa60b0719c220f04007a5cc9e102ce513e12a..1973d20c41a4732649f34f9c14bdb5cea2449527 100644 (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;
+}
index d4229fe958addebf26604949bc7847dd1095a035..497e6c1a940ce073b3180df98ee3c25d9e0250e0 100644 (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;
+}
diff --git a/libs/openzap/src/isdn/include/DMS.h b/libs/openzap/src/isdn/include/DMS.h
new file mode 100644 (file)
index 0000000..35d10d7
--- /dev/null
@@ -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 */
index ce74a4e0fcf5aa5caf16e7c6bfcb5ffae3302029..ee92e48b2696b77c9db99064e9a7c51f046394bd 100644 (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,
index dbca5b399026d4c5cedf86f2517d66fd1bd99c00..5b0e7314a53468bc80c0ca73e6ab70df437a9864 100644 (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;
index 983a6de1dc8e1a61e5d125bab2c87d7621cca8b6..c47daf4ed90550aad46a33a414c77cd69218eeb4 100644 (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"
 
 
 /*****************************************************************************
index 289e9c9de9afec4003c41ae6b8828f12071bdf83..efd1d81ea2a23f1b604ebbe1e1f60ad0c37c8b73 100644 (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;
-
-}
index 75e313d90d259a43b6999e503fe177e19453eb03..81361bd70d815cfc09496a7acb316405f4eb8e03 100644 (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;
-}
index db5ffdfadb52fb7479064738b28b98f5cd19dbd7..e898a7927b432bde8a699e2197449be67e0cde6c 100644 (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;
+                               }
+                       }
+                       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 
+                               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;