Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/smpp-sharp-lib.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <Cluster@Cluster.FX>2013-09-09 22:59:33 +0400
committerunknown <Cluster@Cluster.FX>2013-09-09 22:59:33 +0400
commita1ab8c17ac61fb1b09ad41cfb527208697340ace (patch)
tree9fd05d42bc1aae2e85b557e535223bf32c486de6
First commitHEADmaster
-rw-r--r--SmppServerLib/Properties/AssemblyInfo.cs36
-rw-r--r--SmppServerLib/SmppClient.cs245
-rw-r--r--SmppServerLib/SmppLib.csproj84
-rw-r--r--SmppServerLib/SmppOptionalParameter.cs77
-rw-r--r--SmppServerLib/SmppPduAlertNotification.cs83
-rw-r--r--SmppServerLib/SmppPduBindReceiver.cs29
-rw-r--r--SmppServerLib/SmppPduBindReceiverResp.cs26
-rw-r--r--SmppServerLib/SmppPduBindTransceiver.cs29
-rw-r--r--SmppServerLib/SmppPduBindTransceiverResp.cs26
-rw-r--r--SmppServerLib/SmppPduBindTransmitter.cs29
-rw-r--r--SmppServerLib/SmppPduBindTransmitterResp.cs26
-rw-r--r--SmppServerLib/SmppPduCancelSm.cs94
-rw-r--r--SmppServerLib/SmppPduCancelSmResp.cs22
-rw-r--r--SmppServerLib/SmppPduDataSm.cs118
-rw-r--r--SmppServerLib/SmppPduDataSmResp.cs36
-rw-r--r--SmppServerLib/SmppPduDeliverSm.cs28
-rw-r--r--SmppServerLib/SmppPduDeliverSmResp.cs26
-rw-r--r--SmppServerLib/SmppPduEnquireLink.cs22
-rw-r--r--SmppServerLib/SmppPduEnquireLinkResp.cs22
-rw-r--r--SmppServerLib/SmppPduGenericNack.cs19
-rw-r--r--SmppServerLib/SmppPduOutbind.cs44
-rw-r--r--SmppServerLib/SmppPduQuerySm.cs58
-rw-r--r--SmppServerLib/SmppPduQuerySmResp.cs58
-rw-r--r--SmppServerLib/SmppPduReplaceSm.cs110
-rw-r--r--SmppServerLib/SmppPduReplaceSmResp.cs22
-rw-r--r--SmppServerLib/SmppPduSubmitSm.cs30
-rw-r--r--SmppServerLib/SmppPduSubmitSmResp.cs26
-rw-r--r--SmppServerLib/SmppPduUnbind.cs18
-rw-r--r--SmppServerLib/SmppPduUnbindResp.cs19
-rw-r--r--SmppServerLib/SmppUdhiParameter.cs29
-rw-r--r--SmppServerLib/_SmppPdu.cs338
-rw-r--r--SmppServerLib/_SmppPduBindBase.cs90
-rw-r--r--SmppServerLib/_SmppPduBindRespBase.cs46
-rw-r--r--SmppServerLib/_SmppPduSmBase.cs243
-rw-r--r--SmppServerLib/_SmppPduSmRespBase.cs37
-rw-r--r--SmppServerLib/bin/Release/SmppLib.dllbin0 -> 48640 bytes
36 files changed, 2245 insertions, 0 deletions
diff --git a/SmppServerLib/Properties/AssemblyInfo.cs b/SmppServerLib/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b36762a
--- /dev/null
+++ b/SmppServerLib/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется с помощью
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("SmppServerLib")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SmppServerLib")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
+// для COM-компонентов. Если требуется обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("6325e4aa-0915-4195-8f39-8d9046b6feff")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+// Основной номер версии
+// Дополнительный номер версии
+// Номер построения
+// Редакция
+//
+// Можно задать все значения или принять номер построения и номер редакции по умолчанию,
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SmppServerLib/SmppClient.cs b/SmppServerLib/SmppClient.cs
new file mode 100644
index 0000000..e90fb6d
--- /dev/null
+++ b/SmppServerLib/SmppClient.cs
@@ -0,0 +1,245 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppClient : IDisposable
+ {
+ TcpClient tcpClient;
+ Thread receiveThread;
+ MemoryStream data;
+ uint length = 0;
+
+ public bool Connected
+ {
+ get { return tcpClient != null && tcpClient.Connected; }
+ }
+ public delegate void OnConnectedDelegate(SmppClient sender);
+ public event OnConnectedDelegate OnConnected = delegate { };
+ public delegate void OnDisconnectedDelegate(SmppClient sender);
+ public event OnDisconnectedDelegate OnDisconnected = delegate { };
+ public delegate void OnSmppPduReceivedDelegate(SmppClient sender, SmppPdu pdu);
+ public event OnSmppPduReceivedDelegate OnSmppPduReceived = delegate { };
+ public delegate void OnBindTransmitterReceivedDelegate(SmppClient sender, SmppPduBindTransmitter pdu);
+ public event OnBindTransmitterReceivedDelegate OnBindTransmitterReceived = delegate { };
+ public delegate void OnBindTransmitterRespReceivedDelegate(SmppClient sender, SmppPduBindTransmitterResp pdu);
+ public event OnBindTransmitterRespReceivedDelegate OnBindTransmitterRespReceived = delegate { };
+ public delegate void OnBindReceiverReceivedDelegate(SmppClient sender, SmppPduBindReceiver pdu);
+ public event OnBindReceiverReceivedDelegate OnBindReceiverReceived = delegate { };
+ public delegate void OnBindReceiverRespReceivedDelegate(SmppClient sender, SmppPduBindReceiverResp pdu);
+ public event OnBindReceiverRespReceivedDelegate OnBindReceiverRespReceived = delegate { };
+ public delegate void OnBindTransceiverReceivedDelegate(SmppClient sender, SmppPduBindTransceiver pdu);
+ public event OnBindTransceiverReceivedDelegate OnBindTransceiverReceived = delegate { };
+ public delegate void OnBindTransceiverRespReceivedDelegate(SmppClient sender, SmppPduBindTransceiverResp pdu);
+ public event OnBindTransceiverRespReceivedDelegate OnBindTransceiverRespReceived = delegate { };
+ public delegate void OnUnbindReceivedDelegate(SmppClient sender, SmppPduUnbind pdu);
+ public event OnUnbindReceivedDelegate OnUnbindReceived = delegate { };
+ public delegate void OnUnbindRespReceivedDelegate(SmppClient sender, SmppPduUnbindResp pdu);
+ public event OnUnbindRespReceivedDelegate OnUnbindRespReceived = delegate { };
+ public delegate void OnGenerickNackReceivedDelegate(SmppClient sender, SmppPduGenerickNack pdu);
+ public event OnGenerickNackReceivedDelegate OnGenerickNackReceived = delegate { };
+ public delegate void OnSubmitSmReceivedDelegate(SmppClient sender, SmppPduSubmitSm pdu);
+ public event OnSubmitSmReceivedDelegate OnSubmitSmReceived = delegate { };
+ public delegate void OnSubmitSmRespReceivedDelegate(SmppClient sender, SmppPduSubmitSmResp pdu);
+ public event OnSubmitSmRespReceivedDelegate OnSubmitSmRespReceived = delegate { };
+ //public delegate void OnSubmitMultiReceivedDelegate(SmppClient sender, SmppPduSubmitMulti pdu);
+ //public delegate void OnSubmitMultiRespReceivedDelegate(SmppClient sender, SmppPduSubmitMultiResp pdu);
+ public delegate void OnDeliverSmReceivedDelegate(SmppClient sender, SmppPduDeliverSm pdu);
+ public event OnDeliverSmReceivedDelegate OnDeliverSmReceived = delegate { };
+ public delegate void OnDeliverSmRespReceivedDelegate(SmppClient sender, SmppPduDeliverSmResp pdu);
+ public event OnDeliverSmRespReceivedDelegate OnDeliverSmRespReceived = delegate { };
+ public delegate void OnDataSmReceivedDelegate(SmppClient sender, SmppPduDataSm pdu);
+ public event OnDataSmReceivedDelegate OnDataSmReceived = delegate { };
+ public delegate void OnDataSmRespReceivedDelegate(SmppClient sender, SmppPduDataSmResp pdu);
+ public event OnDataSmRespReceivedDelegate OnDataSmRespReceived = delegate { };
+ public delegate void OnQuerySmReceivedDelegate(SmppClient sender, SmppPduQuerySm pdu);
+ public event OnQuerySmReceivedDelegate OnQuerySmReceived = delegate { };
+ public delegate void OnQuerySmRespReceivedDelegate(SmppClient sender, SmppPduQuerySmResp pdu);
+ public event OnQuerySmRespReceivedDelegate OnQuerySmRespReceived = delegate { };
+ public delegate void OnCancelSmReceivedDelegate(SmppClient sender, SmppPduCancelSm pdu);
+ public event OnCancelSmReceivedDelegate OnCancelSmReceived = delegate { };
+ public delegate void OnCancelSmRespReceivedDelegate(SmppClient sender, SmppPduCancelSmResp pdu);
+ public event OnCancelSmRespReceivedDelegate OnCancelSmRespReceived = delegate { };
+ public delegate void OnReplaceSmReceivedDelegate(SmppClient sender, SmppPduReplaceSm pdu);
+ public event OnReplaceSmReceivedDelegate OnReplaceSmReceived = delegate { };
+ public delegate void OnReplaceSmRespReceivedDelegate(SmppClient sender, SmppPduReplaceSmResp pdu);
+ public event OnReplaceSmRespReceivedDelegate OnReplaceSmRespReceived = delegate { };
+ public delegate void OnEnquireLinkReceivedDelegate(SmppClient sender, SmppPduEnquireLink pdu);
+ public event OnEnquireLinkReceivedDelegate OnEnquireLinkReceived = delegate { };
+ public delegate void OnEnquireLinkRespReceivedDelegate(SmppClient sender, SmppPduEnquireLinkResp pdu);
+ public event OnEnquireLinkRespReceivedDelegate OnEnquireLinkRespReceived = delegate { };
+ public delegate void OnAlertNotificationReceivedDelegate(SmppClient sender, SmppPduAlertNotification pdu);
+ public event OnAlertNotificationReceivedDelegate OnAlertNotificationReceived = delegate { };
+
+ public SmppClient()
+ {
+ OnSmppPduReceived += SmppConnection_OnSmppPduReceived;
+ }
+
+ public void Connect(string host, int port, IPEndPoint localEndPoint = null)
+ {
+ Close();
+ tcpClient = new TcpClient(localEndPoint ?? new IPEndPoint(IPAddress.Any, 0));
+ tcpClient.ReceiveTimeout = 180000;
+ tcpClient.Connect(host, port);
+ data = new MemoryStream();
+ length = 0;
+ receiveThread = new Thread(ReceivingThread);
+ receiveThread.Start();
+ //enquireThread = new Thread(EnquireThread);
+ //enquireThread.Start();
+ OnConnected(this);
+ }
+
+ public void Close()
+ {
+ if (Connected)
+ tcpClient.Client.Disconnect(false);
+ }
+
+ private void ReceivingThread()
+ {
+ try
+ {
+ int b;
+ do
+ {
+ b = tcpClient.GetStream().ReadByte();
+ if (b >= 0)
+ {
+ data.WriteByte((byte)b);
+ if (data.Length == 4)
+ {
+ var buf = data.GetBuffer();
+ length = (uint)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
+ }
+ if (data.Length == length)
+ {
+ OnSmppPduReceived(this, SmppPdu.CreateFromBytes(data.GetBuffer(), length));
+ data = new MemoryStream();
+ length = 0;
+ }
+ }
+ } while (tcpClient != null && tcpClient.Connected && b >= 0);
+ }
+ catch { }
+ finally
+ {
+ if (tcpClient != null)
+ {
+ tcpClient.Close();
+ tcpClient = null;
+ }
+ receiveThread = null;
+ OnDisconnected(this);
+ }
+ }
+
+ private void EnquireThread()
+ {
+ while (tcpClient != null && tcpClient.Connected)
+ {
+ Thread.Sleep(55000);
+ try
+ {
+ SendPdu(new SmppPduEnquireLink());
+ }
+ catch { }
+ }
+ }
+
+ public void SendPdu(SmppPdu pdu)
+ {
+ if (tcpClient == null || !tcpClient.Connected) throw new Exception("Not connected");
+ tcpClient.GetStream().Write(pdu.GetData(), 0, (int)pdu.Length);
+#if DEBUG
+ Console.WriteLine("Sending: " + pdu);
+ Console.WriteLine();
+#endif
+ }
+
+ void SmppConnection_OnSmppPduReceived(SmppClient sender, SmppPdu pdu)
+ {
+ switch (pdu.CommandId)
+ {
+ case SmppPdu.SmppCommandType.bind_transmitter:
+ OnBindTransmitterReceived(this, (SmppPduBindTransmitter)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.bind_transmitter_resp:
+ OnBindTransmitterRespReceived(this, (SmppPduBindTransmitterResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.bind_receiver:
+ OnBindReceiverReceived(this, (SmppPduBindReceiver)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.bind_receiver_resp:
+ OnBindReceiverRespReceived(this, (SmppPduBindReceiverResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.bind_transceiver:
+ OnBindTransceiverReceived(this, (SmppPduBindTransceiver)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.bind_transceiver_resp:
+ OnBindTransceiverRespReceived(this, (SmppPduBindTransceiverResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.unbind:
+ OnUnbindReceived(this, (SmppPduUnbind)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.unbind_resp:
+ OnUnbindRespReceived(this, (SmppPduUnbindResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.generic_nack:
+ OnGenerickNackReceived(this, (SmppPduGenerickNack)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.submit_sm:
+ OnSubmitSmReceived(this, (SmppPduSubmitSm)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.submit_sm_resp:
+ OnSubmitSmRespReceived(this, (SmppPduSubmitSmResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.deliver_sm:
+ OnDeliverSmReceived(this, (SmppPduDeliverSm)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.deliver_sm_resp:
+ OnDeliverSmRespReceived(this, (SmppPduDeliverSmResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.data_sm:
+ OnDataSmReceived(this, (SmppPduDataSm)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.data_sm_resp:
+ OnDataSmRespReceived(this, (SmppPduDataSmResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.query_sm:
+ OnQuerySmReceived(this, (SmppPduQuerySm)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.query_sm_resp:
+ OnQuerySmRespReceived(this, (SmppPduQuerySmResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.cancel_sm:
+ OnCancelSmReceived(this, (SmppPduCancelSm)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.cancel_sm_resp:
+ OnCancelSmRespReceived(this, (SmppPduCancelSmResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.enquire_link:
+ OnEnquireLinkReceived(this, (SmppPduEnquireLink)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.enquire_link_resp:
+ OnEnquireLinkRespReceived(this, (SmppPduEnquireLinkResp)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ case SmppPdu.SmppCommandType.alert_notification:
+ OnAlertNotificationReceived(this, (SmppPduAlertNotification)SmppPdu.CreateFromBytes(pdu.GetData()));
+ break;
+ }
+ }
+
+ public void Dispose()
+ {
+ if (Connected) Close();
+ }
+ }
+}
diff --git a/SmppServerLib/SmppLib.csproj b/SmppServerLib/SmppLib.csproj
new file mode 100644
index 0000000..d15c229
--- /dev/null
+++ b/SmppServerLib/SmppLib.csproj
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{E869C250-AA19-4EEB-8713-FFD3FF012017}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Flex.Cluster.Smpp</RootNamespace>
+ <AssemblyName>SmppLib</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SmppOptionalParameter.cs" />
+ <Compile Include="_SmppPdu.cs" />
+ <Compile Include="SmppPduBindTransmitter.cs" />
+ <Compile Include="SmppClient.cs" />
+ <Compile Include="SmppPduBindTransceiver.cs" />
+ <Compile Include="SmppPduBindTransmitterResp.cs" />
+ <Compile Include="SmppPduBindTransceiverResp.cs" />
+ <Compile Include="SmppPduBindReceiver.cs" />
+ <Compile Include="SmppPduBindReceiverResp.cs" />
+ <Compile Include="SmppPduOutbind.cs" />
+ <Compile Include="SmppPduUnbind.cs" />
+ <Compile Include="SmppPduEnquireLinkResp.cs" />
+ <Compile Include="SmppPduEnquireLink.cs" />
+ <Compile Include="SmppPduGenericNack.cs" />
+ <Compile Include="_SmppPduSmBase.cs" />
+ <Compile Include="SmppPduUnbindResp.cs" />
+ <Compile Include="_SmppPduBindBase.cs" />
+ <Compile Include="_SmppPduBindRespBase.cs" />
+ <Compile Include="SmppPduDeliverSm.cs" />
+ <Compile Include="SmppPduSubmitSm.cs" />
+ <Compile Include="_SmppPduSmRespBase.cs" />
+ <Compile Include="SmppPduSubmitSmResp.cs" />
+ <Compile Include="SmppPduDeliverSmResp.cs" />
+ <Compile Include="SmppPduDataSm.cs" />
+ <Compile Include="SmppPduDataSmResp.cs" />
+ <Compile Include="SmppPduQuerySm.cs" />
+ <Compile Include="SmppPduQuerySmResp.cs" />
+ <Compile Include="SmppPduCancelSm.cs" />
+ <Compile Include="SmppPduCancelSmResp.cs" />
+ <Compile Include="SmppPduReplaceSm.cs" />
+ <Compile Include="SmppPduReplaceSmResp.cs" />
+ <Compile Include="SmppPduAlertNotification.cs" />
+ <Compile Include="SmppUdhiParameter.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/SmppServerLib/SmppOptionalParameter.cs b/SmppServerLib/SmppOptionalParameter.cs
new file mode 100644
index 0000000..31662d0
--- /dev/null
+++ b/SmppServerLib/SmppOptionalParameter.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppOptionalParameter
+ {
+ public enum ParameterTag : ushort
+ {
+ dest_addr_subunit = 0x0005, // GSM
+ dest_network_type = 0x0006, // Generic
+ dest_bearer_type = 0x0007, // Generic
+ dest_telematics_id = 0x0008, // GSM
+ source_addr_subunit = 0x000D, // GSM
+ source_network_type = 0x000E, // Generic
+ source_bearer_type = 0x000F, // Generic
+ source_telematics_id = 0x0010, // GSM
+ qos_time_to_live = 0x0017, // Generic
+ payload_type = 0x0019, // Generic
+ additional_status_info_text = 0x001D, // Generic
+ receipted_message_id = 0x001E, // Generic
+ ms_msg_wait_facilities = 0x0030, // GSM
+ privacy_indicator = 0x0201, // CDMA, TDMA
+ source_subaddress = 0x0202, // CDMA, TDMA
+ dest_subaddress = 0x0203, // CDMA, TDMA
+ user_message_reference = 0x0204, // 0x0204 Generic
+ user_response_code = 0x0205, // CDMA, TDMA
+ source_port = 0x020A, // Generic
+ destination_port = 0x020B, // Generic
+ sar_msg_ref_num = 0x020C, // Generic
+ language_indicator = 0x020D, // CDMA, TDMA
+ sar_total_segments = 0x020E, // Generic
+ sar_segment_seqnum = 0x020F, // Generic
+ SC_interface_version = 0x0210, // Generic
+ callback_num_pres_ind = 0x0302, // TDMA
+ callback_num_atag = 0x0303, // TDMA
+ number_of_messages = 0x0304, // CDMA
+ callback_num = 0x0381, // CDMA, TDMA, GSM, iDEN
+ dpf_result = 0x0420, // Generic
+ set_dpf = 0x0421, // Generic
+ ms_availability_status = 0x0422, // Generic
+ network_error_code = 0x0423, // Generic
+ message_payload = 0x0424, // Generic
+ delivery_failure_reason = 0x0425, // Generic
+ more_messages_to_send = 0x0426, // GSM
+ message_state = 0x0427, // Generic
+ ussd_service_op = 0x0501, // GSM (USSD)
+ display_time = 0x1201, // CDMA, TDMA
+ sms_signal = 0x1203, // TDMA
+ ms_validity = 0x1204, // CDMA, TDMA
+ alert_on_message_delivery = 0x130C, // CDMA
+ its_reply_type = 0x1380, // CDMA
+ its_session_info = 0x1383 // CDMA
+ }
+
+ public readonly ParameterTag Tag;
+ public readonly ushort Length;
+ public readonly byte[] Value;
+
+ public SmppOptionalParameter(ParameterTag tag, ushort length, byte[] value)
+ {
+ Tag = tag;
+ Length = length;
+ Value = value;
+ }
+
+ public override string ToString()
+ {
+ var data = new StringBuilder();
+ foreach(var b in Value)
+ data.AppendFormat("{0:X2} ",b);
+ return string.Format("Option: {0} = {1}", Tag, data.ToString());
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduAlertNotification.cs b/SmppServerLib/SmppPduAlertNotification.cs
new file mode 100644
index 0000000..d32b090
--- /dev/null
+++ b/SmppServerLib/SmppPduAlertNotification.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduAlertNotification : SmppPdu
+ {
+ uint offsetSourceAddrTon, offsetSourceAddrNpi, offsetSourceAddr, offsetEsmeAddrTon, offsetEsmeAddrNpi, offsetEsmeAddr, offsetOptionalParameters;
+
+ public byte SourceAddrTon
+ {
+ get { return ReadByte(offsetSourceAddrTon); }
+ }
+ public byte SourceAddrNpi
+ {
+ get { return ReadByte(offsetSourceAddrNpi); }
+ }
+ public string SourceAddr
+ {
+ get { return ReadCString(offsetSourceAddr); }
+ }
+ public byte EsmeAddrTon
+ {
+ get { return ReadByte(offsetEsmeAddrTon); }
+ }
+ public byte EsmeAddrNpi
+ {
+ get { return ReadByte(offsetEsmeAddrNpi); }
+ }
+ public string EsmeAddr
+ {
+ get { return ReadCString(offsetEsmeAddr); }
+ }
+ public SmppOptionalParameter[] OptionalParameters
+ {
+ get { return ReadOptionalParameters(offsetOptionalParameters); }
+ }
+
+ public SmppPduAlertNotification(byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr, byte esmeAddrTon, byte esmeAddrNpi, string esmeAddr, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.alert_notification)
+ {
+ offsetSourceAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetSourceAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (sourceAddr.Length > 64) throw new ArgumentOutOfRangeException("sourceAddr");
+ offsetSourceAddr = CurrentOffset;
+ WriteCString(sourceAddr);
+
+ offsetEsmeAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetEsmeAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (esmeAddr.Length > 64) throw new ArgumentOutOfRangeException("esmeAddr");
+ offsetEsmeAddr = CurrentOffset;
+ WriteCString(esmeAddr);
+
+ offsetOptionalParameters = CurrentOffset;
+ if (optionalParameters != null)
+ WriteOptionalParameters(optionalParameters);
+ }
+
+ public SmppPduAlertNotification(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduAlertNotification(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.alert_notification) throw new Exception("Invaid command ID");
+ offsetSourceAddrTon = 12;
+ offsetSourceAddrNpi = offsetSourceAddrTon + 1;
+ offsetSourceAddr = offsetSourceAddrNpi + 1;
+ offsetEsmeAddrTon = FindCStringEnd(offsetSourceAddr);
+ offsetEsmeAddrNpi = offsetEsmeAddrTon + 1;
+ offsetEsmeAddr = offsetEsmeAddrNpi + 1;
+ offsetOptionalParameters = FindCStringEnd(offsetEsmeAddr);
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduBindReceiver.cs b/SmppServerLib/SmppPduBindReceiver.cs
new file mode 100644
index 0000000..22430d0
--- /dev/null
+++ b/SmppServerLib/SmppPduBindReceiver.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduBindReceiver : SmppPduBindBase
+ {
+ protected override SmppPdu.SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.bind_receiver;
+ }
+
+ public SmppPduBindReceiver(string systemId, string password, string systemType, byte interfaceVersion, byte addrTon, byte addrNpi, string addrRange)
+ : base(SmppCommandType.bind_receiver, systemId, password, systemType, interfaceVersion, addrTon, addrNpi, addrRange)
+ {
+ }
+
+ public SmppPduBindReceiver(byte[] bytes)
+ : this(bytes, (uint)bytes.Length)
+ {
+ }
+ public SmppPduBindReceiver(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduBindReceiverResp.cs b/SmppServerLib/SmppPduBindReceiverResp.cs
new file mode 100644
index 0000000..e51504f
--- /dev/null
+++ b/SmppServerLib/SmppPduBindReceiverResp.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduBindReceiverResp : SmppPduBindRespBase
+ {
+ protected override SmppPdu.SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.bind_receiver_resp;
+ }
+
+ public SmppPduBindReceiverResp(uint sequenceId, SmppCommandStatus status, string systemId, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.bind_receiver_resp, sequenceId, status, systemId, optionalParameters)
+ {
+ }
+
+ public SmppPduBindReceiverResp(byte[] bytes) : this(bytes, (uint)bytes.Length) {}
+ public SmppPduBindReceiverResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduBindTransceiver.cs b/SmppServerLib/SmppPduBindTransceiver.cs
new file mode 100644
index 0000000..324f0b3
--- /dev/null
+++ b/SmppServerLib/SmppPduBindTransceiver.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduBindTransceiver : SmppPduBindBase
+ {
+ protected override SmppPdu.SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.bind_transceiver;
+ }
+
+ public SmppPduBindTransceiver(string systemId, string password, string systemType, byte interfaceVersion, byte addrTon, byte addrNpi, string addrRange)
+ : base(SmppCommandType.bind_transceiver, systemId, password, systemType, interfaceVersion, addrTon, addrNpi, addrRange)
+ {
+ }
+
+ public SmppPduBindTransceiver(byte[] bytes)
+ : this(bytes, (uint)bytes.Length)
+ {
+ }
+ public SmppPduBindTransceiver(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduBindTransceiverResp.cs b/SmppServerLib/SmppPduBindTransceiverResp.cs
new file mode 100644
index 0000000..ca03bc2
--- /dev/null
+++ b/SmppServerLib/SmppPduBindTransceiverResp.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduBindTransceiverResp : SmppPduBindRespBase
+ {
+ protected override SmppPdu.SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.bind_transceiver_resp;
+ }
+
+ public SmppPduBindTransceiverResp(uint sequenceId, SmppCommandStatus status, string systemId, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.bind_transceiver_resp, sequenceId, status, systemId, optionalParameters)
+ {
+ }
+
+ public SmppPduBindTransceiverResp(byte[] bytes) : this(bytes, (uint)bytes.Length) {}
+ public SmppPduBindTransceiverResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduBindTransmitter.cs b/SmppServerLib/SmppPduBindTransmitter.cs
new file mode 100644
index 0000000..c10a4b2
--- /dev/null
+++ b/SmppServerLib/SmppPduBindTransmitter.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduBindTransmitter : SmppPduBindBase
+ {
+ protected override SmppPdu.SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.bind_transmitter;
+ }
+
+ public SmppPduBindTransmitter(string systemId, string password, string systemType, byte interfaceVersion, byte addrTon, byte addrNpi, string addrRange)
+ : base(SmppCommandType.bind_transmitter, systemId, password, systemType, interfaceVersion, addrTon, addrNpi, addrRange)
+ {
+ }
+
+ public SmppPduBindTransmitter(byte[] bytes)
+ : this(bytes, (uint)bytes.Length)
+ {
+ }
+ public SmppPduBindTransmitter(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduBindTransmitterResp.cs b/SmppServerLib/SmppPduBindTransmitterResp.cs
new file mode 100644
index 0000000..934222d
--- /dev/null
+++ b/SmppServerLib/SmppPduBindTransmitterResp.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduBindTransmitterResp : SmppPduBindRespBase
+ {
+ protected override SmppPdu.SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.bind_transmitter_resp;
+ }
+
+ public SmppPduBindTransmitterResp(uint sequenceId, SmppCommandStatus status, string systemId, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.bind_transmitter_resp, sequenceId, status, systemId, optionalParameters)
+ {
+ }
+
+ public SmppPduBindTransmitterResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduBindTransmitterResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduCancelSm.cs b/SmppServerLib/SmppPduCancelSm.cs
new file mode 100644
index 0000000..a43ba72
--- /dev/null
+++ b/SmppServerLib/SmppPduCancelSm.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduCancelSm : SmppPdu
+ {
+ uint offsetServiceType, offsetMessageId, offsetSourceAddrTon, offsetSourceAddrNpi, offsetSourceAddr,
+ offsetDestAddrTon, offsetDestAddrNpi, offsetDestAddr;
+
+ public string ServiceType
+ {
+ get { return ReadCString(offsetServiceType); }
+ }
+ public string MessageId
+ {
+ get { return ReadCString(offsetMessageId); }
+ }
+ public byte SourceAddrTon
+ {
+ get { return ReadByte(offsetSourceAddrTon); }
+ }
+ public byte SourceAddrNpi
+ {
+ get { return ReadByte(offsetSourceAddrNpi); }
+ }
+ public string SourceAddr
+ {
+ get { return ReadCString(offsetSourceAddr); }
+ }
+ public byte DestAddrTon
+ {
+ get { return ReadByte(offsetDestAddrTon); }
+ }
+ public byte DestAddrNpi
+ {
+ get { return ReadByte(offsetDestAddrNpi); }
+ }
+ public string DestAddr
+ {
+ get { return ReadCString(offsetDestAddr); }
+ }
+
+ public SmppPduCancelSm(string serviceType, string messageId, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr,
+ byte destAddrTon, byte destAddrNpi, string destAddr)
+ : base(SmppCommandType.cancel_sm)
+ {
+ if (serviceType.Length > 5) throw new ArgumentOutOfRangeException("serviceType");
+ offsetServiceType = CurrentOffset;
+ WriteCString(serviceType);
+
+ if (messageId.Length > 64) throw new ArgumentOutOfRangeException("messageId");
+ offsetMessageId = CurrentOffset;
+ WriteCString(messageId);
+
+ offsetSourceAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetSourceAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (sourceAddr.Length > 20) throw new ArgumentOutOfRangeException("sourceAddr");
+ offsetSourceAddr = CurrentOffset;
+ WriteCString(sourceAddr);
+
+ offsetDestAddrTon = CurrentOffset;
+ WriteByte(destAddrTon);
+
+ offsetDestAddrNpi = CurrentOffset;
+ WriteByte(destAddrTon);
+
+ if (destAddr.Length > 20) throw new ArgumentOutOfRangeException("destAddr");
+ offsetDestAddr = CurrentOffset;
+ WriteCString(destAddr);
+ }
+
+ public SmppPduCancelSm(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduCancelSm(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.cancel_sm) throw new Exception("Invaid command ID");
+ offsetServiceType = 12;
+ offsetMessageId = FindCStringEnd(offsetServiceType);
+ offsetSourceAddrTon = FindCStringEnd(offsetMessageId);
+ offsetSourceAddrNpi = offsetSourceAddrTon + 1;
+ offsetSourceAddr = offsetSourceAddrNpi + 1;
+ offsetDestAddrTon = FindCStringEnd(offsetSourceAddr);
+ offsetDestAddrNpi = offsetDestAddrTon + 1;
+ offsetDestAddr = offsetDestAddrNpi + 1;
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduCancelSmResp.cs b/SmppServerLib/SmppPduCancelSmResp.cs
new file mode 100644
index 0000000..9f77dd8
--- /dev/null
+++ b/SmppServerLib/SmppPduCancelSmResp.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduCancelSmResp : SmppPdu
+ {
+ public SmppPduCancelSmResp(uint sequenceId, SmppCommandStatus status)
+ : base(SmppCommandType.cancel_sm_resp, status, sequenceId)
+ {
+ }
+
+ public SmppPduCancelSmResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduCancelSmResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.cancel_sm_resp) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduDataSm.cs b/SmppServerLib/SmppPduDataSm.cs
new file mode 100644
index 0000000..33c91ff
--- /dev/null
+++ b/SmppServerLib/SmppPduDataSm.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduDataSm : SmppPdu
+ {
+ uint offsetServiceType, offsetSourceAddrTon, offsetSourceAddrNpi, offsetSourceAddr, offsetDestAddrTon, offsetDestAddrNpi, offsetDestAddr,
+ offsetEsmClass, offsetRegisteredDelivery, offsetDataCoding, offsetOptionalParameters;
+
+ public string ServiceType
+ {
+ get { return ReadCString(offsetServiceType); }
+ }
+ public byte SourceAddrTon
+ {
+ get { return ReadByte(offsetSourceAddrTon); }
+ }
+ public byte SourceAddrNpi
+ {
+ get { return ReadByte(offsetSourceAddrNpi); }
+ }
+ public string SourceAddr
+ {
+ get { return ReadCString(offsetSourceAddr); }
+ }
+ public byte DestAddrTon
+ {
+ get { return ReadByte(offsetDestAddrTon); }
+ }
+ public byte DestAddrNpi
+ {
+ get { return ReadByte(offsetDestAddrNpi); }
+ }
+ public string DestAddr
+ {
+ get { return ReadCString(offsetDestAddr); }
+ }
+ public byte EsmClass
+ {
+ get { return ReadByte(offsetEsmClass); }
+ }
+ public byte RegisteredDelivery
+ {
+ get { return ReadByte(offsetRegisteredDelivery); }
+ }
+ public byte DataCoding
+ {
+ get { return ReadByte(offsetDataCoding); }
+ }
+ public SmppOptionalParameter[] OptionalParameters
+ {
+ get { return ReadOptionalParameters(offsetOptionalParameters); }
+ }
+
+ public SmppPduDataSm(string serviceType, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr, byte destAddrTon, byte destAddrNpi, string destAddr,
+ byte esmClass, byte registeredDelivery, byte dataCoding, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.data_sm)
+ {
+ if (serviceType.Length > 5) throw new ArgumentOutOfRangeException("systemType");
+ offsetServiceType = CurrentOffset;
+ WriteCString(serviceType);
+
+ offsetSourceAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetSourceAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (sourceAddr.Length > 20) throw new ArgumentOutOfRangeException("sourceAddr");
+ offsetSourceAddr = CurrentOffset;
+ WriteCString(sourceAddr);
+
+ offsetDestAddrTon = CurrentOffset;
+ WriteByte(destAddrTon);
+
+ offsetDestAddrNpi = CurrentOffset;
+ WriteByte(destAddrNpi);
+
+ if (destAddr.Length > 20) throw new ArgumentOutOfRangeException("destAddr");
+ offsetDestAddr = CurrentOffset;
+ WriteCString(destAddr);
+
+ offsetEsmClass = CurrentOffset;
+ WriteByte(esmClass);
+
+ offsetRegisteredDelivery = CurrentOffset;
+ WriteByte(registeredDelivery);
+
+ offsetDataCoding = CurrentOffset;
+ WriteByte(dataCoding);
+
+ offsetOptionalParameters = CurrentOffset;
+ if (optionalParameters != null)
+ WriteOptionalParameters(optionalParameters);
+ }
+
+ public SmppPduDataSm(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduDataSm(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.data_sm) throw new Exception("Invaid command ID");
+ offsetServiceType = 12;
+ offsetSourceAddrTon = FindCStringEnd(offsetServiceType);
+ offsetSourceAddrNpi = offsetSourceAddrTon + 1;
+ offsetSourceAddr = offsetSourceAddrNpi + 1;
+ offsetDestAddrTon = FindCStringEnd(offsetSourceAddr);
+ offsetDestAddrNpi = offsetDestAddrTon + 1;
+ offsetDestAddr = offsetDestAddrNpi + 1;
+ offsetEsmClass = FindCStringEnd(offsetDestAddr);
+ offsetRegisteredDelivery = offsetEsmClass + 1;
+ offsetDataCoding = offsetRegisteredDelivery + 1;
+ offsetOptionalParameters = offsetDataCoding + 1;
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduDataSmResp.cs b/SmppServerLib/SmppPduDataSmResp.cs
new file mode 100644
index 0000000..9c5c505
--- /dev/null
+++ b/SmppServerLib/SmppPduDataSmResp.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduDataSmResp : SmppPduSmRespBase
+ {
+ uint offsetOptionalParameters;
+
+ override protected SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.data_sm_resp;
+ }
+ public SmppOptionalParameter[] OptionalParameters
+ {
+ get { return ReadOptionalParameters(offsetOptionalParameters); }
+ }
+
+ public SmppPduDataSmResp(uint sequenceId, SmppCommandStatus status, string messageId, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.data_sm_resp, sequenceId, status, messageId)
+ {
+ offsetOptionalParameters = CurrentOffset;
+ if (optionalParameters != null)
+ WriteOptionalParameters(optionalParameters);
+ }
+
+ public SmppPduDataSmResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduDataSmResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ offsetOptionalParameters = FindCStringEnd(offsetMessageId);
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduDeliverSm.cs b/SmppServerLib/SmppPduDeliverSm.cs
new file mode 100644
index 0000000..2592cbc
--- /dev/null
+++ b/SmppServerLib/SmppPduDeliverSm.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduDeliverSm : SmppPduSmBase
+ {
+ override protected SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.deliver_sm;
+ }
+
+ public SmppPduDeliverSm(string serviceType, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr, byte destAddrTon, byte destAddrNpi, string destAddr,
+ byte esmClass, byte protocolId, byte priorityFlag, byte registeredDelivery, byte dataCoding, /*byte smLength,*/ string shortMessage, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.deliver_sm, serviceType, sourceAddrTon, sourceAddrNpi, sourceAddr, destAddrTon, destAddrNpi, destAddr, esmClass, protocolId,
+ priorityFlag, "", "", registeredDelivery, 0, dataCoding, 0, /*smLength,*/ shortMessage, optionalParameters)
+ {
+ }
+
+ public SmppPduDeliverSm(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduDeliverSm(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduDeliverSmResp.cs b/SmppServerLib/SmppPduDeliverSmResp.cs
new file mode 100644
index 0000000..e541711
--- /dev/null
+++ b/SmppServerLib/SmppPduDeliverSmResp.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduDeliverSmResp : SmppPduSmRespBase
+ {
+ override protected SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.deliver_sm_resp;
+ }
+
+ public SmppPduDeliverSmResp(uint sequenceId, SmppCommandStatus status = SmppCommandStatus.ESME_ROK)
+ : base(SmppCommandType.deliver_sm_resp, sequenceId, status, "")
+ {
+ }
+
+ public SmppPduDeliverSmResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduDeliverSmResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduEnquireLink.cs b/SmppServerLib/SmppPduEnquireLink.cs
new file mode 100644
index 0000000..2be1d70
--- /dev/null
+++ b/SmppServerLib/SmppPduEnquireLink.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduEnquireLink : SmppPdu
+ {
+ public SmppPduEnquireLink()
+ : base(SmppCommandType.enquire_link)
+ {
+ }
+
+ public SmppPduEnquireLink(byte[] bytes) : this(bytes, (uint)bytes.Length) {}
+ public SmppPduEnquireLink(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.enquire_link) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduEnquireLinkResp.cs b/SmppServerLib/SmppPduEnquireLinkResp.cs
new file mode 100644
index 0000000..9c5c596
--- /dev/null
+++ b/SmppServerLib/SmppPduEnquireLinkResp.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduEnquireLinkResp : SmppPdu
+ {
+ public SmppPduEnquireLinkResp(uint sequenceId, SmppCommandStatus status = SmppCommandStatus.ESME_ROK)
+ : base(SmppCommandType.enquire_link_resp, status, sequenceId)
+ {
+ }
+
+ public SmppPduEnquireLinkResp(byte[] bytes) : this(bytes, (uint)bytes.Length) {}
+ public SmppPduEnquireLinkResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.enquire_link_resp) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduGenericNack.cs b/SmppServerLib/SmppPduGenericNack.cs
new file mode 100644
index 0000000..7b277a7
--- /dev/null
+++ b/SmppServerLib/SmppPduGenericNack.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduGenerickNack : SmppPdu
+ {
+ public SmppPduGenerickNack(uint sequenceId, SmppCommandStatus status)
+ : base(SmppCommandType.generic_nack, status, sequenceId) { }
+ public SmppPduGenerickNack(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduGenerickNack(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.generic_nack) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduOutbind.cs b/SmppServerLib/SmppPduOutbind.cs
new file mode 100644
index 0000000..f9961b3
--- /dev/null
+++ b/SmppServerLib/SmppPduOutbind.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduOutbind : SmppPdu
+ {
+ uint offsetSystemId, offsetPassword;
+
+ public string SystemId
+ {
+ get { return ReadCString(offsetSystemId); }
+ }
+ public string Password
+ {
+ get { return ReadCString(offsetPassword); }
+ }
+
+ public SmppPduOutbind(string systemId, string password)
+ : base(SmppCommandType.outbind)
+ {
+ if (systemId.Length > 15) throw new ArgumentOutOfRangeException("systemId");
+ offsetSystemId = CurrentOffset;
+ WriteCString(systemId);
+
+ if (password.Length > 8) throw new ArgumentOutOfRangeException("password");
+ offsetPassword = CurrentOffset;
+ WriteCString(password);
+ }
+
+ public SmppPduOutbind(byte[] bytes) : this(bytes, (uint)bytes.Length)
+ {
+ }
+ public SmppPduOutbind(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.outbind) throw new Exception("Invaid command ID");
+ offsetSystemId = 12;
+ offsetPassword = FindCStringEnd(offsetSystemId);
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduQuerySm.cs b/SmppServerLib/SmppPduQuerySm.cs
new file mode 100644
index 0000000..aee5b73
--- /dev/null
+++ b/SmppServerLib/SmppPduQuerySm.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduQuerySm : SmppPdu
+ {
+ uint offsetMessageId, offsetSourceAddrTon, offsetSourceAddrNpi, offsetSourceAddr;
+
+ public string MessageId
+ {
+ get { return ReadCString(offsetMessageId); }
+ }
+ public byte SourceAddrTon
+ {
+ get { return ReadByte(offsetSourceAddrTon); }
+ }
+ public byte SourceAddrNpi
+ {
+ get { return ReadByte(offsetSourceAddrNpi); }
+ }
+ public string SourceAddr
+ {
+ get { return ReadCString(offsetSourceAddr); }
+ }
+
+ public SmppPduQuerySm(string messageId, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr)
+ : base(SmppCommandType.query_sm)
+ {
+ if (messageId.Length > 64) throw new ArgumentOutOfRangeException("messageId");
+ offsetMessageId = CurrentOffset;
+ WriteCString(messageId);
+
+ offsetSourceAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetSourceAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (sourceAddr.Length > 20) throw new ArgumentOutOfRangeException("sourceAddr");
+ offsetSourceAddr = CurrentOffset;
+ WriteCString(sourceAddr);
+ }
+
+ public SmppPduQuerySm(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduQuerySm(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.query_sm) throw new Exception("Invaid command ID");
+ offsetMessageId = 12;
+ offsetSourceAddrTon = FindCStringEnd(offsetMessageId);
+ offsetSourceAddrNpi = offsetSourceAddrTon + 1;
+ offsetSourceAddr = offsetSourceAddrNpi + 1;
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduQuerySmResp.cs b/SmppServerLib/SmppPduQuerySmResp.cs
new file mode 100644
index 0000000..416131e
--- /dev/null
+++ b/SmppServerLib/SmppPduQuerySmResp.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduQuerySmResp : SmppPdu
+ {
+ uint offsetMessageId, offsetFinalDate, offsetMessageState, offsetErrorCode;
+
+ public string MessageId
+ {
+ get { return ReadCString(offsetMessageId); }
+ }
+ public string FinalDate
+ {
+ get { return ReadCString(offsetFinalDate); }
+ }
+ public byte MessageState
+ {
+ get { return ReadByte(offsetMessageState); }
+ }
+ public byte ErrorCode
+ {
+ get { return ReadByte(offsetErrorCode); }
+ }
+
+ public SmppPduQuerySmResp(uint sequenceId, SmppCommandStatus status, string messageId, string finalDate, byte messageState, byte errorCode)
+ : base(SmppCommandType.query_sm_resp, status, sequenceId)
+ {
+ if (messageId.Length > 64) throw new ArgumentOutOfRangeException("messageId");
+ offsetMessageId = CurrentOffset;
+ WriteCString(messageId);
+
+ if (finalDate.Length != 0 && finalDate.Length != 16) throw new ArgumentOutOfRangeException("finalDate");
+ offsetFinalDate = CurrentOffset;
+ WriteCString(finalDate);
+
+ offsetMessageState = CurrentOffset;
+ WriteByte(messageState);
+
+ offsetErrorCode = CurrentOffset;
+ WriteByte(errorCode);
+ }
+
+ public SmppPduQuerySmResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduQuerySmResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.query_sm_resp) throw new Exception("Invaid command ID");
+ offsetMessageId = 12;
+ offsetFinalDate = FindCStringEnd(offsetMessageId);
+ offsetMessageState = FindCStringEnd(offsetFinalDate);
+ offsetErrorCode = offsetMessageState+1;
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduReplaceSm.cs b/SmppServerLib/SmppPduReplaceSm.cs
new file mode 100644
index 0000000..48d4361
--- /dev/null
+++ b/SmppServerLib/SmppPduReplaceSm.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduReplaceSm : SmppPdu
+ {
+ uint offsetMessageId, offsetSourceAddrTon, offsetSourceAddrNpi, offsetSourceAddr, offsetScheduleDeliveryTime,
+ offsetRegisteredDelivery, offsetValidityPeriod, offsetSmDefaultMsgId, offsetSmLength, offsetShortMessage;
+
+ public string MessageId
+ {
+ get { return ReadCString(offsetMessageId); }
+ }
+ public byte SourceAddrTon
+ {
+ get { return ReadByte(offsetSourceAddrTon); }
+ }
+ public byte SourceAddrNpi
+ {
+ get { return ReadByte(offsetSourceAddrNpi); }
+ }
+ public string SourceAddr
+ {
+ get { return ReadCString(offsetSourceAddr); }
+ }
+ public string ScheduleDeliveryTime
+ {
+ get { return ReadCString(offsetScheduleDeliveryTime); }
+ }
+ public string ValidityPeriod
+ {
+ get { return ReadCString(offsetValidityPeriod); }
+ }
+ public byte RegisteredDelivery
+ {
+ get { return ReadByte(offsetRegisteredDelivery); }
+ }
+ public byte SmDefaultMsgId
+ {
+ get { return ReadByte(offsetSmDefaultMsgId); }
+ }
+ public byte SmLength
+ {
+ get { return ReadByte(offsetSmLength); }
+ }
+ public string ShortMessage
+ {
+ get { return ReadString(offsetShortMessage, SmLength ); }
+ }
+
+ public SmppPduReplaceSm(string messageId, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr, string scheduleDeliveryTime, string validityPeriod, byte registeredDelivery, byte smDefaultMsgId, byte smLength, string shortMessage)
+ : base(SmppCommandType.replace_sm)
+ {
+ if (messageId.Length > 64) throw new ArgumentOutOfRangeException("messageId");
+ offsetMessageId = CurrentOffset;
+ WriteCString(messageId);
+
+ offsetSourceAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetSourceAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (sourceAddr.Length > 20) throw new ArgumentOutOfRangeException("sourceAddr");
+ offsetSourceAddr = CurrentOffset;
+ WriteCString(sourceAddr);
+
+ if (scheduleDeliveryTime.Length != 0 && scheduleDeliveryTime.Length != 16) throw new ArgumentOutOfRangeException("scheduleDeliveryTime");
+ offsetScheduleDeliveryTime = CurrentOffset;
+ WriteCString(scheduleDeliveryTime);
+
+ if (validityPeriod.Length != 0 && validityPeriod.Length != 16) throw new ArgumentOutOfRangeException("validityPeriod");
+ offsetValidityPeriod = CurrentOffset;
+ WriteCString(validityPeriod);
+
+ offsetRegisteredDelivery = CurrentOffset;
+ WriteByte(registeredDelivery);
+
+ offsetSmDefaultMsgId = CurrentOffset;
+ WriteByte(smDefaultMsgId);
+
+ // TODO: Codepage?
+ offsetSmLength = CurrentOffset;
+ WriteByte(smLength);
+
+ offsetShortMessage = CurrentOffset;
+ WriteString(shortMessage, smLength);
+ }
+
+ public SmppPduReplaceSm(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduReplaceSm(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.replace_sm) throw new Exception("Invaid command ID");
+ offsetMessageId = 12;
+ offsetSourceAddrTon = FindCStringEnd(offsetMessageId);
+ offsetSourceAddrNpi = offsetSourceAddrTon + 1;
+ offsetSourceAddr = offsetSourceAddrNpi + 1;
+ offsetScheduleDeliveryTime = FindCStringEnd(offsetSourceAddr);
+ offsetValidityPeriod = FindCStringEnd(offsetScheduleDeliveryTime);
+ offsetRegisteredDelivery = FindCStringEnd(offsetValidityPeriod);
+ offsetSmDefaultMsgId = offsetRegisteredDelivery + 1;
+ offsetSmLength = offsetSmDefaultMsgId + 1;
+ offsetShortMessage = offsetSmLength + 1;
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduReplaceSmResp.cs b/SmppServerLib/SmppPduReplaceSmResp.cs
new file mode 100644
index 0000000..8d93c91
--- /dev/null
+++ b/SmppServerLib/SmppPduReplaceSmResp.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduReplaceSmResp : SmppPdu
+ {
+ public SmppPduReplaceSmResp(uint sequenceId, SmppCommandStatus status)
+ : base(SmppCommandType.replace_sm_resp, status, sequenceId)
+ {
+ }
+
+ public SmppPduReplaceSmResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduReplaceSmResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.replace_sm_resp) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduSubmitSm.cs b/SmppServerLib/SmppPduSubmitSm.cs
new file mode 100644
index 0000000..533bbba
--- /dev/null
+++ b/SmppServerLib/SmppPduSubmitSm.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduSubmitSm : SmppPduSmBase
+ {
+ override protected SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.submit_sm;
+ }
+
+ public SmppPduSubmitSm(string serviceType, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr, byte destAddrTon, byte destAddrNpi, string destAddr,
+ byte esmClass, byte protocolId, byte priorityFlag, string scheduleDeliveryTime, string validityPeriod, byte registeredDelivery, byte replaceIfPresentFlag,
+ byte dataCoding, byte smDefaultMsgId, /*byte smLength,*/ string shortMessage, SmppOptionalParameter[] optionalParameters = null)
+ : base(SmppCommandType.submit_sm, serviceType, sourceAddrTon, sourceAddrNpi, sourceAddr, destAddrTon, destAddrNpi, destAddr, esmClass, protocolId,
+ priorityFlag, scheduleDeliveryTime, validityPeriod, registeredDelivery, replaceIfPresentFlag, dataCoding, smDefaultMsgId, /*smLength,*/ shortMessage,
+ optionalParameters)
+ {
+ }
+
+ public SmppPduSubmitSm(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduSubmitSm(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduSubmitSmResp.cs b/SmppServerLib/SmppPduSubmitSmResp.cs
new file mode 100644
index 0000000..ea26a64
--- /dev/null
+++ b/SmppServerLib/SmppPduSubmitSmResp.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduSubmitSmResp : SmppPduSmRespBase
+ {
+ override protected SmppCommandType GetCommandType()
+ {
+ return SmppCommandType.submit_sm_resp;
+ }
+
+ public SmppPduSubmitSmResp(uint sequenceId, SmppCommandStatus status, string messageId)
+ : base(SmppCommandType.submit_sm_resp, sequenceId, status, messageId)
+ {
+ }
+
+ public SmppPduSubmitSmResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduSubmitSmResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduUnbind.cs b/SmppServerLib/SmppPduUnbind.cs
new file mode 100644
index 0000000..98f61c6
--- /dev/null
+++ b/SmppServerLib/SmppPduUnbind.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduUnbind : SmppPdu
+ {
+ public SmppPduUnbind() : base(SmppCommandType.unbind) { }
+ public SmppPduUnbind(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduUnbind(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.unbind) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppPduUnbindResp.cs b/SmppServerLib/SmppPduUnbindResp.cs
new file mode 100644
index 0000000..db2c157
--- /dev/null
+++ b/SmppServerLib/SmppPduUnbindResp.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPduUnbindResp : SmppPdu
+ {
+ public SmppPduUnbindResp(uint sequenceId, SmppCommandStatus status)
+ : base(SmppCommandType.unbind_resp, status, sequenceId) { }
+ public SmppPduUnbindResp(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduUnbindResp(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != SmppCommandType.unbind_resp) throw new Exception("Invaid command ID");
+ }
+ }
+}
diff --git a/SmppServerLib/SmppUdhiParameter.cs b/SmppServerLib/SmppUdhiParameter.cs
new file mode 100644
index 0000000..83a9122
--- /dev/null
+++ b/SmppServerLib/SmppUdhiParameter.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppUdhiParameter
+ {
+ public readonly byte Tag;
+ public readonly byte Length;
+ public readonly byte[] Value;
+
+ public SmppUdhiParameter(byte tag, byte length, byte[] value)
+ {
+ Tag = tag;
+ Length = length;
+ Value = value;
+ }
+
+ public override string ToString()
+ {
+ var data = new StringBuilder();
+ foreach(var b in Value)
+ data.AppendFormat("{0:X2} ",b);
+ return string.Format("UDHI: {0} = {1}", Tag, data.ToString());
+ }
+ }
+}
diff --git a/SmppServerLib/_SmppPdu.cs b/SmppServerLib/_SmppPdu.cs
new file mode 100644
index 0000000..11519a0
--- /dev/null
+++ b/SmppServerLib/_SmppPdu.cs
@@ -0,0 +1,338 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public class SmppPdu
+ {
+ static uint currentSeqNumber = 1;
+ const uint offsetCommandId = 0;
+ const uint offsetStatus = 4;
+ const uint offsetSequenceNumber = 8;
+
+ public uint Length
+ {
+ get { return (uint)(data.Length + 4); }
+ }
+ protected uint CurrentOffset
+ {
+ get { return (uint)(data.Length); }
+ }
+ public SmppCommandType CommandId
+ {
+ get { return (SmppCommandType)ReadInteger(offsetCommandId); }
+ }
+ public SmppCommandStatus Status
+ {
+ get { return (SmppCommandStatus)ReadInteger(offsetStatus); }
+ }
+ public uint SequenceNumber
+ {
+ get { return ReadInteger(offsetSequenceNumber); }
+ }
+ MemoryStream data;
+
+ public enum SmppCommandType : uint
+ {
+ generic_nack = 0x80000000,
+ bind_receiver = 0x00000001,
+ bind_receiver_resp = 0x80000001,
+ bind_transmitter = 0x00000002,
+ bind_transmitter_resp = 0x80000002,
+ query_sm = 0x00000003,
+ query_sm_resp = 0x80000003,
+ submit_sm = 0x00000004,
+ submit_sm_resp = 0x80000004,
+ deliver_sm = 0x00000005,
+ deliver_sm_resp = 0x80000005,
+ unbind = 0x00000006,
+ unbind_resp = 0x80000006,
+ replace_sm = 0x00000007,
+ replace_sm_resp = 0x80000007,
+ cancel_sm = 0x00000008,
+ cancel_sm_resp = 0x80000008,
+ bind_transceiver = 0x00000009,
+ bind_transceiver_resp = 0x80000009,
+ outbind = 0x0000000B,
+ enquire_link = 0x00000015,
+ enquire_link_resp = 0x80000015,
+ submit_multi = 0x00000021,
+ submit_multi_resp = 0x80000021,
+ alert_notification = 0x00000102,
+ data_sm = 0x00000103,
+ data_sm_resp = 0x80000103
+ };
+ public enum SmppCommandStatus : uint
+ {
+ ESME_ROK = 0x00000000, // No Error
+ ESME_RINVMSGLEN = 0x00000001, // Message Length is invalid
+ ESME_RINVCMDLEN = 0x00000002, // Command Length is invalid
+ ESME_RINVCMDID = 0x00000003, // Invalid Command ID
+ ESME_RINVBNDSTS = 0x00000004, // Incorrect BIND Status for given command
+ ESME_RALYBND = 0x00000005, // ESME Already in Bound State
+ ESME_RINVPRTFLG = 0x00000006, // Invalid Priority Flag
+ ESME_RINVREGDLVFLG = 0x00000007, // Invalid Registered Delivery Flag
+ ESME_RSYSERR = 0x00000008, // System Error
+ ESME_RINVSRCADR = 0x0000000A, // Invalid Source Address
+ ESME_RINVDSTADR = 0x0000000B, // Invalid Dest Addr
+ ESME_RINVMSGID = 0x0000000C, // Message ID is invalid
+ ESME_RBINDFAIL = 0x0000000D, // Bind Failed
+ ESME_RINVPASWD = 0x0000000E, // Invalid Password
+ ESME_RINVSYSID = 0x0000000F, // Invalid System ID
+ ESME_RCANCELFAIL = 0x00000011, // 0x00000011 Cancel SM Failed
+ ESME_RREPLACEFAIL = 0x00000013, // Replace SM Failed
+ ESME_RMSGQFUL = 0x00000014, // Message Queue Full
+ ESME_RINVSERTYP = 0x00000015, // Invalid Service Type
+ ESME_RINVNUMDESTS = 0x00000033, // Invalid number of destinations
+ ESME_RINVDLNAME = 0x00000034, // Invalid Distribution List name
+ ESME_RINVDESTFLAG = 0x00000040, // Destination flag is invalid
+ ESME_RINVSUBREP = 0x00000042, // Invalid ‘submit with replace’ request
+ ESME_RINVESMCLASS = 0x00000043, // Invalid esm_classfield data
+ ESME_RCNTSUBDL = 0x00000044, // Cannot Submit to Distribution List
+ ESME_RSUBMITFAIL = 0x00000045, // submit_smor submit_multi failed
+ ESME_RINVSRCTON = 0x00000048, // Invalid Source address TON
+ ESME_RINVSRCNPI = 0x00000049, // Invalid Source address NPI
+ ESME_RINVDSTTON = 0x00000050, // Invalid Destination address TON
+ ESME_RINVDSTNPI = 0x00000051, // Invalid Destination address NPI
+ ESME_RINVSYSTYP = 0x00000053, // Invalid system_typefield
+ ESME_RINVREPFLAG = 0x00000054, // Invalid replace_if_present flag
+ ESME_RINVNUMMSGS = 0x00000055, // Invalid number of messages
+ ESME_RTHROTTLED = 0x00000058, // Throttling error (ESME has exceeded allowed message limits)
+ ESME_RINVSCHED = 0x00000061, // Invalid Scheduled Delivery Time
+ ESME_RINVEXPIRY = 0x00000062, // Invalid message validity period (Expiry time)
+ ESME_RINVDFTMSGID = 0x00000063, // Predefined Message Invalid or Not Found
+ ESME_RX_T_APPN = 0x00000064, // ESME Receiver Temporary App Error Code
+ ESME_RX_P_APPN = 0x00000065, // ESME Receiver Permanent App Error Code
+ ESME_RX_R_APPN = 0x00000066, // ESME Receiver Reject Message Error Code
+ ESME_RQUERYFAIL = 0x00000067, // query_smrequest failed
+ ESME_RINVOPTPARSTREAM = 0x000000C0, // Error in the optional part of the PDU Body.
+ ESME_ROPTPARNOTALLWD = 0x000000C1, // Optional Parameter not allowed
+ ESME_RINVPARLEN = 0x000000C2, // Invalid Parameter Length.
+ ESME_RMISSINGOPTPARAM = 0x000000C3, // Expected Optional Parameter missing
+ ESME_RINVOPTPARAMVAL = 0x000000C4, // Invalid Optional Parameter Value
+ ESME_RDELIVERYFAILURE = 0x000000FE, // Delivery Failure (used for data_sm_resp)
+ ESME_RUNKNOWNERR = 0x000000FF // Unknown Error
+ }
+
+ public byte[] GetData()
+ {
+ var result = new byte[Length];
+ result[0] = (byte)((Length >> 24) & 0xFF);
+ result[1] = (byte)((Length >> 16) & 0xFF);
+ result[2] = (byte)((Length >> 8) & 0xFF);
+ result[3] = (byte)(Length & 0xFF);
+ var buffer = data.GetBuffer();
+ Array.Copy(buffer, 0, result, 4, Length - 4);
+ return result;
+ }
+
+ protected void WriteInteger(uint v)
+ {
+ data.Seek(0, SeekOrigin.End);
+ data.WriteByte((byte)((v >> 24) & 0xFF));
+ data.WriteByte((byte)((v >> 16) & 0xFF));
+ data.WriteByte((byte)((v >> 8) & 0xFF));
+ data.WriteByte((byte)(v & 0xFF));
+ }
+ protected uint ReadInteger(uint offset)
+ {
+ uint result = 0;
+ var buffer = data.GetBuffer();
+ for (int c = 0; c < 4; c++)
+ {
+ var b = buffer[offset + c];
+ result <<= 8;
+ result |= (byte)b;
+ }
+ return result;
+ }
+ protected void WriteShort(ushort v)
+ {
+ data.Seek(0, SeekOrigin.End);
+ data.WriteByte((byte)((v >> 8) & 0xFF));
+ data.WriteByte((byte)(v & 0xFF));
+ }
+ protected ushort ReadShort(uint offset)
+ {
+ ushort result = 0;
+ var buffer = data.GetBuffer();
+ for (int c = 0; c < 2; c++)
+ {
+ var b = buffer[offset + c];
+ result <<= 8;
+ result |= (byte)b;
+ }
+ return result;
+ }
+ protected void WriteByte(byte v)
+ {
+ data.Seek(0, SeekOrigin.End);
+ data.WriteByte(v);
+ }
+ protected byte ReadByte(uint offset)
+ {
+ var buffer = data.GetBuffer();
+ return buffer[offset];
+ }
+ protected byte[] ReadBytes(uint offset, int len)
+ {
+ var buffer = data.GetBuffer();
+ var result = new byte[len];
+ Array.Copy(buffer, offset, result, 0, len);
+ return result;
+ }
+ protected void WriteCString(string v, Encoding encoding = null)
+ {
+ encoding = encoding ?? Encoding.ASCII;
+ var bytes = encoding.GetBytes(v);
+ data.Seek(0, SeekOrigin.End);
+ data.Write(bytes, 0, bytes.Length);
+ data.WriteByte(0);
+ }
+ protected string ReadCString(uint offset, Encoding encoding = null)
+ {
+ encoding = encoding ?? Encoding.ASCII;
+ var buffer = data.GetBuffer();
+ int len = 0;
+ while (buffer[offset + len] != 0) len++;
+ return encoding.GetString(buffer, (int)offset, len);
+ }
+ protected uint FindCStringEnd(uint offset)
+ {
+ var buffer = data.GetBuffer();
+ uint result = offset;
+ while (buffer[result] != 0) result++;
+ return result + 1;
+ }
+ protected void WriteString(string v, uint length, Encoding encoding = null)
+ {
+ encoding = encoding ?? Encoding.ASCII;
+ var bytes = encoding.GetBytes(v);
+ data.Seek(0, SeekOrigin.End);
+ data.Write(bytes, 0, (int)length);
+ }
+ protected string ReadString(uint offset, uint length, Encoding encoding = null)
+ {
+ encoding = encoding ?? Encoding.ASCII;
+ var buffer = data.GetBuffer();
+ return encoding.GetString(buffer, (int)offset, (int)length);
+ }
+ protected void WriteOptionalParameters(SmppOptionalParameter[] parameters)
+ {
+ foreach (var parameter in parameters)
+ {
+ WriteShort((ushort)parameter.Tag);
+ WriteShort((ushort)parameter.Length);
+ data.Write(parameter.Value, 0, parameter.Length);
+ }
+ }
+ protected SmppOptionalParameter[] ReadOptionalParameters(uint offset)
+ {
+ var parameters = new List<SmppOptionalParameter>();
+ uint pos = offset;
+ var buffer = data.GetBuffer();
+ while (pos + 3 < data.Length)
+ {
+ ushort tag = ReadShort(pos);
+ pos += 2;
+ ushort valueLength = ReadShort(pos);
+ pos += 2;
+ var value = new byte[valueLength];
+ Array.Copy(buffer, pos, value, 0, valueLength);
+ pos += valueLength;
+ parameters.Add(new SmppOptionalParameter((SmppOptionalParameter.ParameterTag)tag, valueLength, value));
+ }
+ return parameters.ToArray();
+ }
+
+ protected SmppPdu(SmppCommandType commandType, SmppCommandStatus commandStatus = 0, uint seqNumber = 0)
+ {
+ data = new MemoryStream();
+ WriteInteger((uint)commandType);
+ WriteInteger((uint)commandStatus);
+ WriteInteger(seqNumber == 0 ? currentSeqNumber++ : seqNumber);
+ if (currentSeqNumber > int.MaxValue) currentSeqNumber = 1;
+ }
+ public SmppPdu(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPdu(byte[] bytes, uint length)
+ {
+ data = new MemoryStream();
+ data.Write(bytes, 4, (int)length - 4);
+ }
+
+ public static SmppPdu CreateFromBytes(byte[] bytes)
+ {
+ return CreateFromBytes(bytes, (uint)bytes.Length);
+ }
+ public static SmppPdu CreateFromBytes(byte[] bytes, uint length)
+ {
+ var pdu = new SmppPdu(bytes, length);
+ switch (pdu.CommandId)
+ {
+ case SmppCommandType.bind_receiver:
+ return new SmppPduBindReceiver(bytes, length);
+ case SmppCommandType.bind_receiver_resp:
+ return new SmppPduBindReceiverResp(bytes, length);
+ case SmppCommandType.bind_transceiver:
+ return new SmppPduBindTransceiver(bytes, length);
+ case SmppCommandType.bind_transceiver_resp:
+ return new SmppPduBindTransceiverResp(bytes, length);
+ case SmppCommandType.bind_transmitter:
+ return new SmppPduBindTransmitter(bytes, length);
+ case SmppCommandType.bind_transmitter_resp:
+ return new SmppPduBindTransmitterResp(bytes, length);
+ case SmppCommandType.outbind:
+ return new SmppPduOutbind(bytes, length);
+ case SmppCommandType.unbind:
+ return new SmppPduUnbind(bytes, length);
+ case SmppCommandType.unbind_resp:
+ return new SmppPduUnbindResp(bytes, length);
+ case SmppCommandType.enquire_link:
+ return new SmppPduEnquireLink(bytes, length);
+ case SmppCommandType.enquire_link_resp:
+ return new SmppPduEnquireLinkResp(bytes, length);
+ case SmppCommandType.generic_nack:
+ return new SmppPduGenerickNack(bytes, length);
+ case SmppCommandType.deliver_sm:
+ return new SmppPduDeliverSm(bytes, length);
+ case SmppCommandType.submit_sm:
+ return new SmppPduSubmitSm(bytes, length);
+ case SmppCommandType.deliver_sm_resp:
+ return new SmppPduDeliverSmResp(bytes, length);
+ case SmppCommandType.submit_sm_resp:
+ return new SmppPduSubmitSmResp(bytes, length);
+ case SmppCommandType.data_sm:
+ return new SmppPduDataSm(bytes, length);
+ case SmppCommandType.data_sm_resp:
+ return new SmppPduDataSmResp(bytes, length);
+ case SmppCommandType.query_sm:
+ return new SmppPduQuerySm(bytes, length);
+ case SmppCommandType.query_sm_resp:
+ return new SmppPduQuerySmResp(bytes, length);
+ case SmppCommandType.cancel_sm:
+ return new SmppPduCancelSm(bytes, length);
+ case SmppCommandType.cancel_sm_resp:
+ return new SmppPduCancelSmResp(bytes, length);
+ case SmppCommandType.replace_sm:
+ return new SmppPduReplaceSm(bytes, length);
+ case SmppCommandType.replace_sm_resp:
+ return new SmppPduReplaceSmResp(bytes, length);
+ case SmppCommandType.alert_notification:
+ return new SmppPduAlertNotification(bytes, length);
+ }
+ throw new NotSupportedException(string.Format("Command {0} is not supported", pdu.CommandId));
+ }
+
+ public override string ToString()
+ {
+ var d = GetData();
+ var dStr = new StringBuilder();
+ foreach (var b in d)
+ dStr.AppendFormat("{0:X2} ", b);
+ return string.Format("Command: {0}, status: {1}, seq: {2}, length: {3}, data: {4}", CommandId, Status, SequenceNumber, Length, dStr.ToString());
+ }
+ }
+}
diff --git a/SmppServerLib/_SmppPduBindBase.cs b/SmppServerLib/_SmppPduBindBase.cs
new file mode 100644
index 0000000..9d64c79
--- /dev/null
+++ b/SmppServerLib/_SmppPduBindBase.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public abstract class SmppPduBindBase : SmppPdu
+ {
+ abstract protected SmppCommandType GetCommandType();
+
+ uint offsetSystemId, offsetPassword, offsetSystemType, offsetInterfaceVersion, offsetAddrTon, offsetAddrNpi, offsetAddrRange;
+
+ public string SystemId
+ {
+ get { return ReadCString(offsetSystemId); }
+ }
+ public string Password
+ {
+ get { return ReadCString(offsetPassword); }
+ }
+ public string SystemType
+ {
+ get { return ReadCString(offsetSystemType); }
+ }
+ public byte InterfaceVersion
+ {
+ get { return ReadByte(offsetInterfaceVersion);}
+ }
+ public byte AddrTon
+ {
+ get { return ReadByte(offsetAddrTon); }
+ }
+ public byte AddrNpi
+ {
+ get { return ReadByte(offsetAddrNpi); }
+ }
+ public string AddrRange
+ {
+ get { return ReadCString(offsetAddrRange); }
+ }
+
+ public SmppPduBindBase(SmppCommandType commandType, string systemId, string password, string systemType, byte interfaceVersion, byte addrTon, byte addrNpi, string addrRange)
+ : base(commandType)
+ {
+ if (commandType != GetCommandType()) throw new Exception("Invaid command ID");
+
+ if (systemId.Length > 15) throw new ArgumentOutOfRangeException("systemId");
+ offsetSystemId = CurrentOffset;
+ WriteCString(systemId);
+
+ if (password.Length > 8) throw new ArgumentOutOfRangeException("password");
+ offsetPassword = CurrentOffset;
+ WriteCString(password);
+
+ if (systemType.Length > 12) throw new ArgumentOutOfRangeException("systemType");
+ offsetSystemType = CurrentOffset;
+ WriteCString(systemType);
+
+ offsetInterfaceVersion = CurrentOffset;
+ WriteByte(interfaceVersion);
+
+ offsetAddrTon = CurrentOffset;
+ WriteByte(addrTon);
+
+ offsetAddrNpi = CurrentOffset;
+ WriteByte(addrNpi);
+
+ if (addrRange.Length > 40) throw new ArgumentOutOfRangeException("addressRange");
+ offsetAddrRange = CurrentOffset;
+ WriteCString(addrRange);
+ }
+
+ public SmppPduBindBase(byte[] bytes) : this(bytes, (uint)bytes.Length)
+ {
+ }
+ public SmppPduBindBase(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != GetCommandType()) throw new Exception("Invaid command ID");
+ offsetSystemId = 12;
+ offsetPassword = FindCStringEnd(offsetSystemId);
+ offsetSystemType = FindCStringEnd(offsetPassword);
+ offsetInterfaceVersion = FindCStringEnd(offsetSystemType);
+ offsetAddrTon = offsetInterfaceVersion + 1;
+ offsetAddrNpi = offsetAddrTon + 1;
+ offsetAddrRange = offsetAddrNpi + 1;
+ }
+ }
+}
diff --git a/SmppServerLib/_SmppPduBindRespBase.cs b/SmppServerLib/_SmppPduBindRespBase.cs
new file mode 100644
index 0000000..fd38139
--- /dev/null
+++ b/SmppServerLib/_SmppPduBindRespBase.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public abstract class SmppPduBindRespBase : SmppPdu
+ {
+ abstract protected SmppCommandType GetCommandType();
+
+ uint offsetSystemId, offsetOptionalParameters;
+
+ public string SystemId
+ {
+ get { return ReadCString(offsetSystemId); }
+ }
+ public SmppOptionalParameter[] OptionalParameters
+ {
+ get { return ReadOptionalParameters(offsetOptionalParameters); }
+ }
+
+ public SmppPduBindRespBase(SmppCommandType commandType, uint sequenceId, SmppCommandStatus status, string systemId, SmppOptionalParameter[] optionalParameters = null)
+ : base(commandType, status, sequenceId)
+ {
+ if (commandType != GetCommandType()) throw new Exception("Invaid command ID");
+
+ if (systemId.Length > 15) throw new ArgumentOutOfRangeException("systemId");
+ offsetSystemId = CurrentOffset;
+ WriteCString(systemId);
+
+ offsetOptionalParameters = CurrentOffset;
+ if (optionalParameters != null)
+ WriteOptionalParameters(optionalParameters);
+ }
+
+ public SmppPduBindRespBase(byte[] bytes) : this(bytes, (uint)bytes.Length) {}
+ public SmppPduBindRespBase(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != GetCommandType()) throw new Exception("Invaid command ID");
+ offsetSystemId = 12;
+ offsetOptionalParameters = FindCStringEnd(offsetSystemId);
+ }
+ }
+}
diff --git a/SmppServerLib/_SmppPduSmBase.cs b/SmppServerLib/_SmppPduSmBase.cs
new file mode 100644
index 0000000..279e106
--- /dev/null
+++ b/SmppServerLib/_SmppPduSmBase.cs
@@ -0,0 +1,243 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public abstract class SmppPduSmBase : SmppPdu
+ {
+ abstract protected SmppCommandType GetCommandType();
+
+ uint offsetServiceType, offsetSourceAddrTon, offsetSourceAddrNpi, offsetSourceAddr, offsetDestAddrTon, offsetDestAddrNpi, offsetDestAddr,
+ offsetEsmClass, offsetProtocolId, offsetPriorityFlag, offsetScheduleDeliveryTime, offsetRegisteredDelivery, offsetValidityPeriod, offsetReplaceIfPresentFlag, offsetDataCoding,
+ offsetSmDefaultMsgId, offsetSmLength, offsetShortMessage, offsetOptionalParameters;
+
+ public string ServiceType
+ {
+ get { return ReadCString(offsetServiceType); }
+ }
+ public byte SourceAddrTon
+ {
+ get { return ReadByte(offsetSourceAddrTon); }
+ }
+ public byte SourceAddrNpi
+ {
+ get { return ReadByte(offsetSourceAddrNpi); }
+ }
+ public string SourceAddr
+ {
+ get { return ReadCString(offsetSourceAddr); }
+ }
+ public byte DestAddrTon
+ {
+ get { return ReadByte(offsetDestAddrTon); }
+ }
+ public byte DestAddrNpi
+ {
+ get { return ReadByte(offsetDestAddrNpi); }
+ }
+ public string DestAddr
+ {
+ get { return ReadCString(offsetDestAddr); }
+ }
+ public byte EsmClass
+ {
+ get { return ReadByte(offsetEsmClass); }
+ }
+ public byte ProtocolId
+ {
+ get { return ReadByte(offsetProtocolId); }
+ }
+ public byte PriorityFlag
+ {
+ get { return ReadByte(offsetPriorityFlag); }
+ }
+ public string ScheduleDeliveryTime
+ {
+ get { return ReadCString(offsetScheduleDeliveryTime); }
+ }
+ public string ValidityPeriod
+ {
+ get { return ReadCString(offsetValidityPeriod); }
+ }
+ public byte RegisteredDelivery
+ {
+ get { return ReadByte(offsetRegisteredDelivery); }
+ }
+ public byte ReplaceIfPresentFlag
+ {
+ get { return ReadByte(offsetReplaceIfPresentFlag); }
+ }
+ public byte DataCoding
+ {
+ get { return ReadByte(offsetDataCoding); }
+ }
+ public Encoding DataEncoder
+ {
+ get
+ {
+ switch (DataCoding)
+ {
+ case 0:
+ return Encoding.ASCII;
+ case 8:
+ return Encoding.BigEndianUnicode;
+ default:
+ throw new NotSupportedException(string.Format("Codepage {0} is not supported yet", DataCoding));
+ }
+ }
+ }
+ public byte SmDefaultMsgId
+ {
+ get { return ReadByte(offsetSmDefaultMsgId); }
+ }
+ public byte SmLength
+ {
+ get { return ReadByte(offsetSmLength); }
+ }
+ public string ShortMessage
+ {
+ get
+ {
+ if ((EsmClass & 64) == 0)
+ return ReadString(offsetShortMessage, SmLength, DataEncoder);
+ byte udhiLength = ReadByte(offsetShortMessage);
+ return ReadString(offsetShortMessage + udhiLength + 1, (uint)(SmLength - udhiLength - 1), DataEncoder); // UDHI
+ }
+ }
+ public SmppOptionalParameter[] OptionalParameters
+ {
+ get { return ReadOptionalParameters(offsetOptionalParameters); }
+ }
+ public SmppUdhiParameter[] UdhiParameters
+ {
+ get
+ {
+ if ((EsmClass & 64) == 0) return new SmppUdhiParameter[0];
+ byte udhiLength = ReadByte(offsetShortMessage);
+ var result = new List<SmppUdhiParameter>();
+ byte pos = 0;
+ while (pos < udhiLength)
+ {
+ byte tag = ReadByte(offsetShortMessage + 1 + pos);
+ byte len = ReadByte(offsetShortMessage + 1 + pos + 1);
+ var data = ReadBytes(offsetShortMessage + 1 + pos + 2, len);
+ result.Add(new SmppUdhiParameter(tag, len, data));
+ pos += (byte)(len + 2);
+ }
+ return result.ToArray();
+ }
+ }
+
+ public SmppPduSmBase(SmppCommandType commandType, string serviceType, byte sourceAddrTon, byte sourceAddrNpi, string sourceAddr, byte destAddrTon, byte destAddrNpi, string destAddr,
+ byte esmClass, byte protocolId, byte priorityFlag, string scheduleDeliveryTime, string validityPeriod, byte registeredDelivery, byte replaceIfPresentFlag,
+ byte dataCoding, byte smDefaultMsgId, /*byte smLength,*/ string shortMessage, SmppOptionalParameter[] optionalParameters = null)
+ : base(commandType)
+ {
+ if (commandType != GetCommandType()) throw new Exception("Invaid command ID");
+
+ if (serviceType.Length > 5) throw new ArgumentOutOfRangeException("systemType");
+ offsetServiceType = CurrentOffset;
+ WriteCString(serviceType);
+
+ offsetSourceAddrTon = CurrentOffset;
+ WriteByte(sourceAddrTon);
+
+ offsetSourceAddrNpi = CurrentOffset;
+ WriteByte(sourceAddrNpi);
+
+ if (sourceAddr.Length > 20) throw new ArgumentOutOfRangeException("sourceAddr");
+ offsetSourceAddr = CurrentOffset;
+ WriteCString(sourceAddr);
+
+ offsetDestAddrTon = CurrentOffset;
+ WriteByte(destAddrTon);
+
+ offsetDestAddrNpi = CurrentOffset;
+ WriteByte(destAddrNpi);
+
+ if (destAddr.Length > 20) throw new ArgumentOutOfRangeException("destAddr");
+ offsetDestAddr = CurrentOffset;
+ WriteCString(destAddr);
+
+ offsetEsmClass = CurrentOffset;
+ WriteByte(esmClass);
+
+ offsetProtocolId = CurrentOffset;
+ WriteByte(protocolId);
+
+ offsetPriorityFlag = CurrentOffset;
+ WriteByte(priorityFlag);
+
+ if (scheduleDeliveryTime.Length != 0 && scheduleDeliveryTime.Length != 16) throw new ArgumentOutOfRangeException("scheduleDeliveryTime");
+ offsetScheduleDeliveryTime = CurrentOffset;
+ WriteCString(scheduleDeliveryTime);
+
+ if (validityPeriod.Length != 0 && validityPeriod.Length != 16) throw new ArgumentOutOfRangeException("validityPeriod");
+ offsetValidityPeriod = CurrentOffset;
+ WriteCString(validityPeriod);
+
+ offsetRegisteredDelivery = CurrentOffset;
+ WriteByte(registeredDelivery);
+
+ offsetReplaceIfPresentFlag = CurrentOffset;
+ WriteByte(replaceIfPresentFlag);
+
+ offsetDataCoding = CurrentOffset;
+ WriteByte(dataCoding);
+
+ offsetSmDefaultMsgId = CurrentOffset;
+ WriteByte(smDefaultMsgId);
+
+ if (DataEncoder.GetByteCount(shortMessage) > 254) throw new ArgumentOutOfRangeException("smLength");
+ offsetSmLength = CurrentOffset;
+ WriteByte((byte)DataEncoder.GetByteCount(shortMessage));
+
+ offsetShortMessage = CurrentOffset;
+ WriteString(shortMessage, (byte)DataEncoder.GetByteCount(shortMessage), DataEncoder);
+
+ offsetOptionalParameters = CurrentOffset;
+ if (optionalParameters != null)
+ WriteOptionalParameters(optionalParameters);
+ }
+
+ public SmppPduSmBase(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduSmBase(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != GetCommandType()) throw new Exception("Invaid command ID");
+ offsetServiceType = 12;
+ offsetSourceAddrTon = FindCStringEnd(offsetServiceType);
+ offsetSourceAddrNpi = offsetSourceAddrTon + 1;
+ offsetSourceAddr = offsetSourceAddrNpi + 1;
+ offsetDestAddrTon = FindCStringEnd(offsetSourceAddr);
+ offsetDestAddrNpi = offsetDestAddrTon + 1;
+ offsetDestAddr = offsetDestAddrNpi + 1;
+ offsetEsmClass = FindCStringEnd(offsetDestAddr);
+ offsetProtocolId = offsetEsmClass + 1;
+ offsetPriorityFlag = offsetProtocolId + 1;
+ offsetScheduleDeliveryTime = offsetPriorityFlag + 1;
+ offsetValidityPeriod = FindCStringEnd(offsetScheduleDeliveryTime);
+ offsetRegisteredDelivery = FindCStringEnd(offsetValidityPeriod);
+ offsetReplaceIfPresentFlag = offsetRegisteredDelivery + 1;
+ offsetDataCoding = offsetReplaceIfPresentFlag + 1;
+ offsetSmDefaultMsgId = offsetDataCoding + 1;
+ offsetSmLength = offsetSmDefaultMsgId + 1;
+ offsetShortMessage = offsetSmLength + 1;
+ offsetOptionalParameters = offsetShortMessage + SmLength;
+ }
+
+ public override string ToString()
+ {
+ var options = new StringBuilder();
+ foreach (var option in OptionalParameters)
+ options.AppendFormat("\r\n{0}", option.ToString());
+ foreach (var udhi in UdhiParameters)
+ options.AppendFormat("\r\n{0}", udhi.ToString());
+ return base.ToString() + string.Format("\r\nservice type: {0}, source_addr_ton: {1}, source_addr_npi: {2}, sounce_addr: {3}, dest_addr_ton: {4}, dest_addr_npi: {5}, destination_addr: {6}, length: {8}, message: {7}",
+ ServiceType, SourceAddrTon, SourceAddrNpi, SourceAddr, DestAddrTon, DestAddrNpi, DestAddr, ShortMessage, SmLength)
+ + options.ToString();
+ }
+ }
+}
diff --git a/SmppServerLib/_SmppPduSmRespBase.cs b/SmppServerLib/_SmppPduSmRespBase.cs
new file mode 100644
index 0000000..d1b3309
--- /dev/null
+++ b/SmppServerLib/_SmppPduSmRespBase.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Flex.Cluster.Smpp
+{
+ public abstract class SmppPduSmRespBase : SmppPdu
+ {
+ abstract protected SmppCommandType GetCommandType();
+
+ protected uint offsetMessageId;
+
+ public string MessageId
+ {
+ get { return ReadCString(offsetMessageId); }
+ }
+
+ public SmppPduSmRespBase(SmppCommandType commandType, uint sequenceId, SmppCommandStatus status, string messageId)
+ : base(commandType, status, sequenceId)
+ {
+ if (commandType != GetCommandType()) throw new Exception("Invaid command ID");
+
+ if (messageId.Length > 64) throw new ArgumentOutOfRangeException("messageId");
+ offsetMessageId = CurrentOffset;
+ WriteCString(messageId);
+ }
+
+ public SmppPduSmRespBase(byte[] bytes) : this(bytes, (uint)bytes.Length) { }
+ public SmppPduSmRespBase(byte[] bytes, uint length)
+ : base(bytes, length)
+ {
+ if (CommandId != GetCommandType()) throw new Exception("Invaid command ID");
+ offsetMessageId = 12;
+ }
+ }
+}
diff --git a/SmppServerLib/bin/Release/SmppLib.dll b/SmppServerLib/bin/Release/SmppLib.dll
new file mode 100644
index 0000000..9c49fe1
--- /dev/null
+++ b/SmppServerLib/bin/Release/SmppLib.dll
Binary files differ