diff --git a/ASyncSocketClient.cs b/ASyncSocketClient.cs
new file mode 100644
index 0000000..9a4962d
--- /dev/null
+++ b/ASyncSocketClient.cs
@@ -0,0 +1,382 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+using System.Net.Sockets;
+
+namespace RoaminSMPP
+{
+ ///
+ /// Socket class for asynchronous connection.
+ ///
+ internal class AsyncSocketClient : IDisposable
+ {
+ #region delegates
+
+ ///
+ /// Called when a message is received.
+ ///
+ ///
+ /// The AsyncSocketClient to receive messages from.
+ ///
+ public delegate void MessageHandler(AsyncSocketClient asyncSocketClient);
+
+ ///
+ /// Called when a connection is closed.
+ ///
+ ///
+ /// The AsyncSocketClient to receive messages from.
+ ///
+ public delegate void SocketClosingHandler(
+ AsyncSocketClient asyncSocketClient);
+
+ ///
+ /// Called when a socket error occurs.
+ ///
+ ///
+ /// The AsyncSocketClient to receive messages from.
+ ///
+ ///
+ /// The exception that generated the error.
+ ///
+ public delegate void ErrorHandler(
+ AsyncSocketClient asyncSocketClient, Exception exception);
+
+ #endregion delegates
+ //one MB
+ private const int BUFFER_SIZE = 1048576;
+
+ #region private fields
+
+ private NetworkStream _NetworkStream;
+ private TcpClient _TcpClient;
+ private AsyncCallback _CallbackReadMethod;
+ private AsyncCallback _CallbackWriteMethod;
+ private MessageHandler _MessageHandler;
+ private SocketClosingHandler _SocketCloseHandler;
+ private ErrorHandler _ErrorHandler;
+ private bool _IsDisposed;
+ private string _ServerIPAddress;
+ private Int16 _ServerPort;
+ private object _StateObject;
+ private byte[] _Buffer;
+ //private int clientBufferSize;
+
+ #endregion private fields
+
+ #region properties
+
+ ///
+ /// The server IP address to connect to.
+ ///
+ public string ServerIPAddress
+ {
+ get
+ {
+ return _ServerIPAddress;
+ }
+ }
+
+ ///
+ /// The server port to connect to.
+ ///
+ public Int16 ServerPort
+ {
+ get
+ {
+ return _ServerPort;
+ }
+ }
+
+ ///
+ /// A user set state object to associate some state with a connection.
+ ///
+ public object StateObject
+ {
+ get
+ {
+ return _StateObject;
+ }
+ set
+ {
+ _StateObject = value;
+ }
+ }
+
+ ///
+ /// Buffer to hold data coming in from the socket.
+ ///
+ public byte[] Buffer
+ {
+ get
+ {
+ return _Buffer;
+ }
+ }
+
+ #endregion properties
+
+ ///
+ /// Constructs an AsyncSocketClient.
+ ///
+ /// The size of the receive buffer.
+ /// The object to use for sending state
+ /// information.
+ /// The user-defined message handling method.
+ ///
+ /// The user-defined socket closing
+ /// handling method.
+ /// The user defined error handling method.
+ ///
+ public AsyncSocketClient(Int32 bufferSize, object stateObject,
+ MessageHandler msgHandler, SocketClosingHandler closingHandler,
+ ErrorHandler errHandler)
+ {
+ //allocate buffer
+// clientBufferSize = bufferSize;
+// _Buffer = new byte[clientBufferSize];
+
+ _Buffer = new byte[BUFFER_SIZE];
+ _StateObject = stateObject;
+
+ //set handlers
+ _MessageHandler = msgHandler;
+ _SocketCloseHandler = closingHandler;
+ _ErrorHandler = errHandler;
+
+ //set the asynchronous method handlers
+ _CallbackReadMethod = new AsyncCallback(ReceiveComplete);
+ _CallbackWriteMethod = new AsyncCallback(SendComplete);
+
+ //haven't been disposed yet
+ _IsDisposed = false;
+ }
+
+ ///
+ /// Finalizer method. If Dispose() is called correctly, there is nothing
+ /// for this to do.
+ ///
+ ~AsyncSocketClient()
+ {
+ if (!_IsDisposed)
+ {
+ Dispose();
+ }
+ }
+
+ #region public methods
+
+ ///
+ /// Sets the disposed flag to true and disconnects the socket.
+ ///
+ public void Dispose()
+ {
+ try
+ {
+ _IsDisposed = true;
+ Disconnect();
+ }
+ catch
+ {}
+ }
+
+ ///
+ /// Connects the socket to the given IP address and port.
+ /// This also calls Receive().
+ ///
+ /// The IP address of the server.
+ /// The port to connect to.
+ public void Connect(String IPAddress, Int16 port)
+ {
+ try
+ {
+ //do we already have an open connection?
+ if (_NetworkStream == null)
+ {
+ _ServerIPAddress = IPAddress;
+ _ServerPort = port;
+
+ //attempt to establish the connection
+ _TcpClient = new TcpClient(_ServerIPAddress, _ServerPort);
+ _NetworkStream = _TcpClient.GetStream();
+
+ //set some socket options
+ _TcpClient.ReceiveBufferSize = BUFFER_SIZE;
+ _TcpClient.SendBufferSize = BUFFER_SIZE;
+ _TcpClient.NoDelay = true;
+ //if the connection is dropped, drop all associated data
+ _TcpClient.LingerState = new LingerOption(false, 0);
+
+ //start receiving messages
+ Receive();
+ }
+ }
+ catch (SocketException exc)
+ {
+ //the connect failed..pass the word on
+ throw new Exception(exc.Message, exc.InnerException);
+ }
+ }
+
+ ///
+ /// Disconnects from the server.
+ ///
+ public void Disconnect()
+ {
+ //close down the connection, making sure it exists first
+ if (_NetworkStream != null)
+ {
+ _NetworkStream.Close();
+ }
+ if (_TcpClient != null)
+ {
+ _TcpClient.Close();
+ }
+
+ //prep for garbage collection-we may want to use this instance again
+ _NetworkStream = null;
+ _TcpClient = null;
+
+ }
+
+ ///
+ /// Asynchronously sends data across the socket.
+ ///
+ ///
+ /// The buffer of data to send.
+ ///
+ public void Send(byte[] buffer)
+ {
+ //send the data; don't worry about receiving any state information
+ //back;
+ try
+ {
+ if (_NetworkStream != null && _NetworkStream.CanWrite)
+ {
+ _NetworkStream.BeginWrite(
+ buffer, 0, buffer.Length, _CallbackWriteMethod, null);
+ }
+ else
+ {
+ throw new Exception("Socket is closed, cannot Send().");
+ }
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ ///
+ /// Asynchronously receives data from the socket.
+ ///
+ public void Receive()
+ {
+ try
+ {
+ if (_NetworkStream != null && _NetworkStream.CanRead)
+ {
+ //_Buffer = new byte[clientBufferSize];
+ _Buffer = new byte[BUFFER_SIZE];
+
+ _NetworkStream.BeginRead(
+ _Buffer, 0, _Buffer.Length, _CallbackReadMethod, null);
+ }
+ else
+ {
+ throw new Exception("Socket is closed, cannot Receive().");
+ }
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ #endregion public methods
+
+ #region private methods
+
+ ///
+ /// Callback method called by the NetworkStream's thread when a message
+ /// is sent.
+ ///
+ /// The state object holding information about
+ /// the connection.
+ private void SendComplete(IAsyncResult state)
+ {
+ try
+ {
+ //check to be sure the network stream is valid before writing
+ if (_NetworkStream.CanWrite)
+ {
+ _NetworkStream.EndWrite(state);
+ }
+ }
+ catch
+ {}
+ }
+
+ ///
+ /// Callback method called by the NetworkStream's thread when a message
+ /// arrives.
+ ///
+ /// The state object holding information about
+ /// the connection.
+ private void ReceiveComplete(IAsyncResult state)
+ {
+ try
+ {
+ //check the stream to be sure it is valid
+ if (_NetworkStream.CanRead)
+ {
+ int bytesReceived = _NetworkStream.EndRead(state);
+
+ //if there are bytes to process, do so. Otherwise, the
+ //connection has been lost, so clean it up
+ if (bytesReceived > 0)
+ {
+ try
+ {
+ //send the incoming message to the message handler
+ _MessageHandler(this);
+ }
+ finally
+ {
+ //start listening again
+ Receive();
+ }
+ }
+ }
+ }
+ catch
+ {
+ //the connection has been dropped so call the CloseHandler
+ try
+ {
+ _SocketCloseHandler(this);
+ }
+ finally
+ {
+ Dispose();
+ }
+ }
+ }
+ #endregion private methods
+ }
+}
diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs
new file mode 100644
index 0000000..0fc3ec0
--- /dev/null
+++ b/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.4")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*)If no key is specified, the assembly is not signed.
+// (*)KeyName refers to a key that has been installed in the Crypto Service
+// Provider(CSP)on your machine. KeyFile refers to a file which contains
+// a key.
+// (*)If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1)If the KeyName can be found in the CSP, that key is used.
+// (2)If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*)In order to create a KeyFile, you can use the sn.exe(Strong Name)utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*)Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000..08e8652
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,22 @@
+10/11/2008 : License changed to GNU Lesser General Public License, V3. This should make combination with other (older) open source licenses such as the original BSD license possible.
+
+11/13/2006 : Added the remainder of the code to the project; I will no longer be working on this app.
+
+08/13/2005 : I've replaced much of the older code with new (hopefully more useful) code. This
+new set of namespaces includes both incoming and outgoing functionality for all the PDUs. Note also
+that this release is GPL only-I have dropped the QPL portion of the license from here on out. I
+also fixed the dates on this changelog-for some reason I had them a year off.
+
+08/20/2004 : Host of changes. The PDUFactory and several incoming PDUs were changed
+for compatibility after some testing. Added some documentation tags. Fixed TLVTable
+so that null tags are simply dropped (i.e. trying to set an optional param to null
+does nothing). Also added the debug file and xml file to the binary release. Also
+changed the zip files so that they store relative path info rather than full path info
+(to those of you who downloaded the early release-sorry about that).
+
+08/15/2004 : Changed the PDUFactory so that it allows multiple responses to come in on
+a PDU. Also fixed the TrimResponsePDU() so that it didn't break if the command length
+was too large (the null SMSC I was testing with today sent some out like that. Also
+included a build script.
+
+08/14/2004 : Initial release.
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..10926e8
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,675 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
+
diff --git a/COPYING.LESSER b/COPYING.LESSER
new file mode 100644
index 0000000..3f7b8b1
--- /dev/null
+++ b/COPYING.LESSER
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
diff --git a/EventObject/AlertEventArgs.cs b/EventObject/AlertEventArgs.cs
new file mode 100644
index 0000000..5c24768
--- /dev/null
+++ b/EventObject/AlertEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Class that defines the bind event. Includes all the available
+ /// mandatory and optional parameters in a bind_response.
+ ///
+ public class AlertEventArgs : SmppEventArgs
+ {
+ private SmppAlertNotification _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppAlertNotification AlertPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the AlertEventArgs.
+ ///
+ /// The SmppAlertNotification.
+ internal AlertEventArgs(SmppAlertNotification response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/BindEventArgs.cs b/EventObject/BindEventArgs.cs
new file mode 100644
index 0000000..1035bfc
--- /dev/null
+++ b/EventObject/BindEventArgs.cs
@@ -0,0 +1,52 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+using RoaminSMPP.Packet.Request;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines the bind_sm event.
+ ///
+ public class BindEventArgs : SmppEventArgs
+ {
+ private SmppBind _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppBind BindPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the BindEventArgs.
+ ///
+ /// The SmppBindResp.
+ internal BindEventArgs(SmppBind response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/BindRespEventArgs.cs b/EventObject/BindRespEventArgs.cs
new file mode 100644
index 0000000..c721360
--- /dev/null
+++ b/EventObject/BindRespEventArgs.cs
@@ -0,0 +1,52 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Class that defines the bind_sm_resp event.
+ ///
+ public class BindRespEventArgs : SmppEventArgs
+ {
+ private SmppBindResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppBindResp BindRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the BindEventArgs.
+ ///
+ /// The SmppBindResp.
+ internal BindRespEventArgs(SmppBindResp response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/CancelEventArgs.cs b/EventObject/CancelEventArgs.cs
new file mode 100644
index 0000000..ab76f93
--- /dev/null
+++ b/EventObject/CancelEventArgs.cs
@@ -0,0 +1,53 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Class that defines a cancel_sm_resp event.
+ ///
+ public class CancelEventArgs : SmppEventArgs
+ {
+ private SmppCancelSmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppCancelSmResp CancelPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the CancelEventArgs.
+ ///
+ /// The SmppCancelSmResp.
+ internal CancelEventArgs(SmppCancelSmResp response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/CancelSmEventArgs.cs b/EventObject/CancelSmEventArgs.cs
new file mode 100644
index 0000000..ee7de73
--- /dev/null
+++ b/EventObject/CancelSmEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a cancel_sm event.
+ ///
+ public class CancelSmEventArgs : SmppEventArgs
+ {
+ private SmppCancelSm _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppCancelSm CancelSmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a CancelSmEventArgs.
+ ///
+ /// The PDU that was received.
+ internal CancelSmEventArgs(SmppCancelSm packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/CancelSmRespEventArgs.cs b/EventObject/CancelSmRespEventArgs.cs
new file mode 100644
index 0000000..0b0fb98
--- /dev/null
+++ b/EventObject/CancelSmRespEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+using RoaminSMPP.Packet.Response;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a cancel_sm_resp event.
+ ///
+ public class CancelSmRespEventArgs : SmppEventArgs
+ {
+ private SmppCancelSmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppCancelSmResp CancelSmRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a CancelSmRespEventArgs.
+ ///
+ /// The PDU that was received.
+ internal CancelSmRespEventArgs(SmppCancelSmResp packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/CommonErrorEventArgs.cs b/EventObject/CommonErrorEventArgs.cs
new file mode 100644
index 0000000..c72be81
--- /dev/null
+++ b/EventObject/CommonErrorEventArgs.cs
@@ -0,0 +1,51 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Event args class. Holds the internal exception generated.
+ ///
+ public class CommonErrorEventArgs : System.EventArgs
+ {
+ private Exception _exc;
+
+ ///
+ /// The thrown exception.
+ ///
+ public Exception ThrownException
+ {
+ get
+ {
+ return _exc;
+ }
+ }
+
+ ///
+ /// Creates an CommErrorEventArgs.
+ ///
+ /// The exception that was generated.
+ public CommonErrorEventArgs(Exception exc)
+ {
+ _exc = exc;
+ }
+ }
+}
diff --git a/EventObject/DataSmEventArgs.cs b/EventObject/DataSmEventArgs.cs
new file mode 100644
index 0000000..54ea598
--- /dev/null
+++ b/EventObject/DataSmEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a data_sm event.
+ ///
+ public class DataSmEventArgs : SmppEventArgs
+ {
+ private SmppDataSm _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppDataSm DataSmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a DataSmEventArgs.
+ ///
+ /// The PDU that was received.
+ internal DataSmEventArgs(SmppDataSm packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/DataSmRespEventArgs.cs b/EventObject/DataSmRespEventArgs.cs
new file mode 100644
index 0000000..cbaa9d2
--- /dev/null
+++ b/EventObject/DataSmRespEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a data_sm_resp event.
+ ///
+ public class DataSmRespEventArgs : SmppEventArgs
+ {
+ private SmppDataSmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppDataSmResp DataSmRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a DataSmRespEventArgs.
+ ///
+ /// The PDU that was received.
+ internal DataSmRespEventArgs(SmppDataSmResp packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/DeliverSmEventArgs.cs b/EventObject/DeliverSmEventArgs.cs
new file mode 100644
index 0000000..e5ba47d
--- /dev/null
+++ b/EventObject/DeliverSmEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a deliver_sm event.
+ ///
+ public class DeliverSmEventArgs : SmppEventArgs
+ {
+ private SmppDeliverSm _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppDeliverSm DeliverSmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a DeliverSmEventArgs.
+ ///
+ /// The PDU that was received.
+ internal DeliverSmEventArgs(SmppDeliverSm packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/DeliverSmRespEventArgs.cs b/EventObject/DeliverSmRespEventArgs.cs
new file mode 100644
index 0000000..f06a4ac
--- /dev/null
+++ b/EventObject/DeliverSmRespEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a deliver_sm_resp event.
+ ///
+ public class DeliverSmRespEventArgs : SmppEventArgs
+ {
+ private SmppDeliverSmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppDeliverSmResp DeliverSmRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a DeliverSmRespEventArgs.
+ ///
+ /// The PDU that was received.
+ internal DeliverSmRespEventArgs(SmppDeliverSmResp packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/EnquireLinkEventArgs.cs b/EventObject/EnquireLinkEventArgs.cs
new file mode 100644
index 0000000..dc26012
--- /dev/null
+++ b/EventObject/EnquireLinkEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines the enquire_link event.
+ ///
+ public class EnquireLinkEventArgs : SmppEventArgs
+ {
+ private SmppEnquireLink _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppEnquireLink EnquireLinkPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the EnquireLinkEventArgs.
+ ///
+ /// The PDU from the ESME.
+ internal EnquireLinkEventArgs(SmppEnquireLink response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/EnquireLinkRespEventArgs.cs b/EventObject/EnquireLinkRespEventArgs.cs
new file mode 100644
index 0000000..f3932e0
--- /dev/null
+++ b/EventObject/EnquireLinkRespEventArgs.cs
@@ -0,0 +1,52 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines the enquire_link_resp event.
+ ///
+ public class EnquireLinkRespEventArgs : SmppEventArgs
+ {
+ private SmppEnquireLinkResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppEnquireLinkResp EnquireLinkRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the EnquireLinkEventArgs.
+ ///
+ /// The SmppEnquireLinkResp.
+ internal EnquireLinkRespEventArgs(SmppEnquireLinkResp response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/GenericNackEventArgs.cs b/EventObject/GenericNackEventArgs.cs
new file mode 100644
index 0000000..10bd05a
--- /dev/null
+++ b/EventObject/GenericNackEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a generic_nack event.
+ ///
+ public class GenericNackEventArgs : SmppEventArgs
+ {
+ private SmppGenericNack _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppGenericNack GenericNackPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a GenericNackEventArgs.
+ ///
+ /// The PDU that was received.
+ internal GenericNackEventArgs(SmppGenericNack packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/QuerySmEventArgs.cs b/EventObject/QuerySmEventArgs.cs
new file mode 100644
index 0000000..5d82202
--- /dev/null
+++ b/EventObject/QuerySmEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a query_sm event.
+ ///
+ public class QuerySmEventArgs : SmppEventArgs
+ {
+ private SmppQuerySm _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppQuerySm QuerySmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a QuerySmEventArgs.
+ ///
+ /// The PDU that was received.
+ internal QuerySmEventArgs(SmppQuerySm packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/QuerySmRespEventArgs.cs b/EventObject/QuerySmRespEventArgs.cs
new file mode 100644
index 0000000..fe211a5
--- /dev/null
+++ b/EventObject/QuerySmRespEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a query_sm_resp event.
+ ///
+ public class QuerySmRespEventArgs : SmppEventArgs
+ {
+ private SmppQuerySmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppQuerySmResp QuerySmRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a QuerySmRespEventArgs.
+ ///
+ /// The PDU that was received.
+ internal QuerySmRespEventArgs(SmppQuerySmResp packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/ReplaceSmEventArgs.cs b/EventObject/ReplaceSmEventArgs.cs
new file mode 100644
index 0000000..70214ef
--- /dev/null
+++ b/EventObject/ReplaceSmEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a replace_sm event.
+ ///
+ public class ReplaceSmEventArgs : SmppEventArgs
+ {
+ private SmppReplaceSm _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppReplaceSm ReplaceSmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a ReplaceSmEventArgs.
+ ///
+ /// The PDU that was received.
+ internal ReplaceSmEventArgs(SmppReplaceSm packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/ReplaceSmRespEventArgs.cs b/EventObject/ReplaceSmRespEventArgs.cs
new file mode 100644
index 0000000..8d6ae42
--- /dev/null
+++ b/EventObject/ReplaceSmRespEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a replace_sm_resp event.
+ ///
+ public class ReplaceSmRespEventArgs : SmppEventArgs
+ {
+ private SmppReplaceSmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppReplaceSmResp ReplaceSmRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a ReplaceSmRespEventArgs.
+ ///
+ /// The PDU that was received.
+ internal ReplaceSmRespEventArgs(SmppReplaceSmResp packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/SmppEventArgs.cs b/EventObject/SmppEventArgs.cs
new file mode 100644
index 0000000..2faffef
--- /dev/null
+++ b/EventObject/SmppEventArgs.cs
@@ -0,0 +1,53 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Base class to provide some functionality for all events.
+ ///
+ public abstract class SmppEventArgs : System.EventArgs
+ {
+ private Pdu _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public Pdu ResponsePdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the SmppEventArgs.
+ ///
+ /// The SMPPResponse.
+ public SmppEventArgs(Pdu response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/SubmitMultiEventArgs.cs b/EventObject/SubmitMultiEventArgs.cs
new file mode 100644
index 0000000..c03698d
--- /dev/null
+++ b/EventObject/SubmitMultiEventArgs.cs
@@ -0,0 +1,54 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a submit_multi event.
+ ///
+ public class SubmitMultiEventArgs : SmppEventArgs
+ {
+ private SmppSubmitMulti _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppSubmitMulti SubmitMultiPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a SubmitMultiEventArgs.
+ ///
+ /// The PDU that was received.
+ internal SubmitMultiEventArgs(SmppSubmitMulti packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/SubmitMultiRespEventArgs.cs b/EventObject/SubmitMultiRespEventArgs.cs
new file mode 100644
index 0000000..846f397
--- /dev/null
+++ b/EventObject/SubmitMultiRespEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a submit_multi_resp event.
+ ///
+ public class SubmitMultiRespEventArgs : SmppEventArgs
+ {
+ private SmppSubmitMultiResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppSubmitMultiResp SubmitMultiRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a SubmitMultiRespEventArgs.
+ ///
+ /// The PDU that was received.
+ internal SubmitMultiRespEventArgs(SmppSubmitMultiResp packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/SubmitSmEventArgs.cs b/EventObject/SubmitSmEventArgs.cs
new file mode 100644
index 0000000..72a856c
--- /dev/null
+++ b/EventObject/SubmitSmEventArgs.cs
@@ -0,0 +1,53 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+
+namespace RoaminSMPP.EventObjects
+{
+ ///
+ /// Class that defines a submit_sm event.
+ ///
+ public class SubmitSmEventArgs : SmppEventArgs
+ {
+ private SmppSubmitSm _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppSubmitSm SubmitSmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Creates a SubmitSmEventArgs.
+ ///
+ /// The PDU that was received.
+ internal SubmitSmEventArgs(SmppSubmitSm packet): base(packet)
+ {
+ _response = packet;
+ }
+ }
+}
diff --git a/EventObject/SubmitSmRespEventArgs.cs b/EventObject/SubmitSmRespEventArgs.cs
new file mode 100644
index 0000000..f1c65fb
--- /dev/null
+++ b/EventObject/SubmitSmRespEventArgs.cs
@@ -0,0 +1,53 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Class that defines the submit_sm_resp event.
+ ///
+ public class SubmitSmRespEventArgs : SmppEventArgs
+ {
+ private SmppSubmitSmResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppSubmitSmResp SubmitSmPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the SubmitSmRespEventArgs.
+ ///
+ /// The SmppSubmitSmResp.
+ internal SubmitSmRespEventArgs(SmppSubmitSmResp response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
diff --git a/EventObject/UnbindEventArgs.cs b/EventObject/UnbindEventArgs.cs
new file mode 100644
index 0000000..d50ac73
--- /dev/null
+++ b/EventObject/UnbindEventArgs.cs
@@ -0,0 +1,55 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+
+using System;
+using RoaminSMPP.Packet.Response;
+using RoaminSMPP.Packet.Request;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Class that defines the unbind event.
+ ///
+ public class UnbindEventArgs : SmppEventArgs
+ {
+ SmppUnbind _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppUnbind UnbindPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the UnbindEventArgs.
+ ///
+ /// The SmppUnbind.
+ internal UnbindEventArgs(SmppUnbind response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
+
diff --git a/EventObject/UnbindRespEventArgs.cs b/EventObject/UnbindRespEventArgs.cs
new file mode 100644
index 0000000..b0b4672
--- /dev/null
+++ b/EventObject/UnbindRespEventArgs.cs
@@ -0,0 +1,53 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.EventObjects
+{
+
+ ///
+ /// Class that defines the unbind_resp event.
+ ///
+ public class UnbindRespEventArgs : SmppEventArgs
+ {
+ SmppUnbindResp _response;
+
+ ///
+ /// Allows access to the underlying Pdu.
+ ///
+ public SmppUnbindResp UnbindRespPdu
+ {
+ get
+ {
+ return _response;
+ }
+ }
+
+ ///
+ /// Sets up the UnbindEventArgs.
+ ///
+ /// The SmppUnbindResp.
+ internal UnbindRespEventArgs(SmppUnbindResp response): base(response)
+ {
+ _response = response;
+ }
+ }
+}
+
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..b860267
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Packet/Pdu.cs b/Packet/Pdu.cs
new file mode 100644
index 0000000..8f1934e
--- /dev/null
+++ b/Packet/Pdu.cs
@@ -0,0 +1,1399 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Diagnostics;
+using RoaminSMPP.Utility;
+using System.Text;
+
+namespace RoaminSMPP.Packet
+{
+ ///
+ /// Represents a protocol data unit. This class holds type enumerations and common
+ /// functionality for request and response Pdus.
+ ///
+ public abstract class Pdu : IDisposable
+ {
+ #region constants
+
+ ///
+ /// Standard length of Pdu header.
+ ///
+ protected const int HEADER_LENGTH = 16;
+ ///
+ /// Delivery time length
+ ///
+ protected const int DATE_TIME_LENGTH = 16;
+
+ #endregion constants
+
+ #region private fields
+
+ private static uint _StaticSequenceNumber = 0;
+ private uint _CommandStatus;
+ private CommandIdType _CommandID;
+ private TlvTable _tlvTable = new TlvTable();
+ private uint _CustomSequenceNumber = 0;
+ private uint _SequenceNumber = 0;
+
+ private byte[] _PacketBytes = new byte[0];
+ private uint _CommandLength;
+
+ #endregion private fields
+
+ #region properties
+
+ ///
+ /// Gets or sets the byte response from the SMSC. This will return a clone of the
+ /// byte array upon a "get" request.
+ ///
+ public byte[] PacketBytes
+ {
+ get
+ {
+ return(byte[])_PacketBytes.Clone();
+ }
+
+ set
+ {
+ _PacketBytes = value;
+ }
+ }
+
+ ///
+ /// Defines the overall length of the Pdu in octets(i.e. bytes).
+ ///
+ public uint CommandLength
+ {
+ get
+ {
+ return _CommandLength;
+ }
+ }
+
+ ///
+ /// The sequence number of the message. Only call this after you call
+ /// GetMSBHexEncoding; it will be incorrect otherwise. If you are setting the
+ /// sequence number(such as for a deliver_sm_resp), set this before you call
+ /// GetMSBHexEncoding. Note that setting the custom sequence number will
+ /// disable the automatic updating of the sequence number for this instance.
+ /// You can restore the automatic updating by setting this property to 0.
+ ///
+ public uint SequenceNumber
+ {
+ get
+ {
+ return _SequenceNumber;
+ }
+ set
+ {
+ _CustomSequenceNumber = value;
+ }
+ }
+
+ ///
+ /// Indicates outcome of request.
+ ///
+ public uint CommandStatus
+ {
+ get
+ {
+ return _CommandStatus;
+ }
+ set
+ {
+ _CommandStatus = value;
+ }
+ }
+
+ ///
+ /// The command ID of this Pdu.
+ ///
+ protected CommandIdType CommandID
+ {
+ get
+ {
+ return _CommandID;
+ }
+ set
+ {
+ _CommandID = value;
+ }
+ }
+
+ #endregion properties
+
+ #region constructors
+
+ ///
+ /// Constructor for sent Pdus.
+ ///
+ protected Pdu()
+ {
+ InitPdu();
+ }
+
+ ///
+ /// Constructor for received Pdus.
+ ///
+ /// The incoming bytes to translate to a Pdu.
+ protected Pdu(byte[] incomingBytes)
+ {
+ #if DEBUG
+ Console.WriteLine("In Pdu byte[] constructor");
+ #endif
+ _PacketBytes = incomingBytes;
+ _CommandLength = DecodeCommandLength(_PacketBytes);
+ _CommandID = DecodeCommandId(_PacketBytes);
+ _CommandStatus = UnsignedNumConverter.SwapByteOrdering(BitConverter.ToUInt32(_PacketBytes, 8));
+ _SequenceNumber = UnsignedNumConverter.SwapByteOrdering(BitConverter.ToUInt32(_PacketBytes, 12));
+ _PacketBytes = TrimResponsePdu(_PacketBytes);
+
+ //set the other Pdu-specific fields
+ DecodeSmscResponse();
+ }
+
+ #endregion constructors
+
+ #region overridable methods
+
+ ///
+ /// Initializes this Pdu. Override to add more functionality, but don't forget to
+ /// call this one.
+ ///
+ protected virtual void InitPdu()
+ {
+ CommandStatus = 0;
+ CommandID = Pdu.CommandIdType.generic_nack;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public virtual void ToMsbHexEncoding()
+ {
+ throw new NotImplementedException("GetMSBHexEncoding is not implemented in Pdu.");
+ }
+
+ ///
+ /// Decodes the bind response from the SMSC. This version throws a NotImplementedException.
+ ///
+ protected virtual void DecodeSmscResponse()
+ {
+ throw new NotImplementedException("DecodeSmscResponse is not implemented in Pdu.");
+ }
+
+ #endregion overridable methods
+
+ ///
+ /// Calculates the length of the given ArrayList representation of the Pdu and
+ /// inserts this length into the appropriate spot in the Pdu. This will call
+ /// TrimToSize()on the ArrayList-the caller need not do it.
+ ///
+ /// The protocol data unit to calculate the
+ /// length for.
+ /// The Pdu with the length inserted, trimmed to size.
+ protected static ArrayList InsertLengthIntoPdu(ArrayList pdu)
+ {
+ pdu.TrimToSize();
+ uint commandLength =(uint)(4 + pdu.Count);
+ uint reqLenH2N = UnsignedNumConverter.SwapByteOrdering(commandLength);
+ byte[] reqLenArray = BitConverter.GetBytes(reqLenH2N);
+ //insert into the Pdu
+ pdu.InsertRange(0, reqLenArray);
+ pdu.TrimToSize();
+
+ return pdu;
+ }
+
+ ///
+ /// Takes the given Pdu, calculates its length(trimming it beforehand), inserting
+ /// its length, and copying it to a byte array.
+ ///
+ /// The Pdu to encode.
+ /// The byte array representation of the Pdu.
+ protected byte[] EncodePduForTransmission(ArrayList pdu)
+ {
+ AddTlvBytes(ref pdu);
+ pdu = InsertLengthIntoPdu(pdu);
+ byte[] result = new byte[pdu.Count];
+ pdu.CopyTo(result);
+
+ return result;
+ }
+
+ ///
+ /// Retrieves the given bytes from the TLV table and converts them into a
+ /// host order UInt16.
+ ///
+ /// The TLV tag to use for retrieval
+ /// The host order result.
+ protected UInt16 GetHostOrderUInt16FromTlv(ushort tag)
+ {
+ return UnsignedNumConverter.SwapByteOrdering(
+ BitConverter.ToUInt16(GetOptionalParamBytes(tag), 0));
+ }
+
+ ///
+ /// Retrieves the given bytes from the TLV table and converts them into a
+ /// host order UInt32.
+ ///
+ /// The TLV tag to use for retrieval
+ /// The host order result.
+ protected UInt32 GetHostOrderUInt32FromTlv(ushort tag)
+ {
+ return UnsignedNumConverter.SwapByteOrdering(
+ BitConverter.ToUInt32(GetOptionalParamBytes(tag), 0));
+ }
+
+ ///
+ /// Takes the given value and puts it into the TLV table, accounting for
+ /// network byte ordering.
+ ///
+ /// The TLV tag to use for retrieval
+ /// The value to put into the table
+ protected void SetHostOrderValueIntoTlv(UInt16 tag, UInt16 val)
+ {
+ SetOptionalParamBytes(
+ tag,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering(val)));
+ }
+
+ ///
+ /// Takes the given value and puts it into the TLV table, accounting for
+ /// network byte ordering.
+ ///
+ /// The TLV tag to use for retrieval
+ /// The value to put into the table
+ protected void SetHostOrderValueIntoTlv(UInt16 tag, UInt32 val)
+ {
+ SetOptionalParamBytes(
+ tag,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering(val)));
+ }
+
+ ///
+ /// What remains after the header is stripped off the Pdu. Subclasses
+ /// don't need the header as its information is stored here. In
+ /// addition, this allows them to manipulate the response data
+ /// all they want without destroying the original. The copying is
+ /// done every time this property is accessed, so use caution in a
+ /// high-performance setting.
+ ///
+ protected byte[] BytesAfterHeader
+ {
+ get
+ {
+ long length = _PacketBytes.Length - HEADER_LENGTH;
+ byte[] remainder = new byte[length];
+ Array.Copy(_PacketBytes, HEADER_LENGTH, remainder, 0, length);
+ return remainder;
+ }
+ }
+
+ ///
+ /// Creates an ArrayList consisting of the Pdu header. Command ID and status
+ /// need to be set before calling this.
+ ///
+ /// The Pdu as a trimmed ArrayList.
+ protected ArrayList GetPduHeader()
+ {
+ ArrayList pdu = new ArrayList();
+ pdu.AddRange(BitConverter.GetBytes(UnsignedNumConverter.SwapByteOrdering((uint)_CommandID)));
+ pdu.AddRange(BitConverter.GetBytes(UnsignedNumConverter.SwapByteOrdering(_CommandStatus)));
+
+ //increase the sequence number
+ GenerateSequenceNumber();
+ pdu.AddRange(BitConverter.GetBytes(UnsignedNumConverter.SwapByteOrdering(_SequenceNumber)));
+ pdu.TrimToSize();
+ return pdu;
+ }
+
+ ///
+ /// Generates a monotonically increasing sequence number for each Pdu. When it
+ /// hits the the 32 bit unsigned int maximum, it starts over.
+ ///
+ private void GenerateSequenceNumber()
+ {
+ if(_CustomSequenceNumber == 0)
+ {
+ _StaticSequenceNumber++;
+ if(_StaticSequenceNumber >= UInt32.MaxValue)
+ {
+ _StaticSequenceNumber = 1;
+ }
+ _SequenceNumber = _StaticSequenceNumber;
+ }
+ else
+ {
+ _SequenceNumber = _CustomSequenceNumber;
+ }
+ }
+
+ #region TLV table methods
+
+ ///
+ /// Gets the optional parameter string associated with
+ /// the given tag.
+ ///
+ /// The tag in TLV.
+ /// The optional parameter string, the empty
+ /// string if not found.
+ public string GetOptionalParamString(UInt16 tag)
+ {
+ return _tlvTable.GetOptionalParamString(UnsignedNumConverter.SwapByteOrdering(tag));
+ }
+
+ ///
+ /// Gets the optional parameter bytes associated with
+ /// the given tag.
+ ///
+ /// The tag in TLV.
+ /// The optional parameter bytes, null if
+ /// not found.
+ public byte[] GetOptionalParamBytes(UInt16 tag)
+ {
+ return _tlvTable.GetOptionalParamBytes(UnsignedNumConverter.SwapByteOrdering(tag));
+ }
+
+ ///
+ /// Sets the given TLV(as a string)into the table. This ignores
+ /// null values. This will reverse the byte order in the tag for you
+ ///(necessary for encoding).
+ ///
+ /// The tag for this TLV.
+ /// The value of this TLV.
+ public void SetOptionalParamString(UInt16 tag, string val)
+ {
+ _tlvTable.SetOptionalParamString(UnsignedNumConverter.SwapByteOrdering(tag), val);
+ }
+
+ ///
+ /// Sets the given TLV(as a byte array)into the table. This will not take
+ /// care of big-endian/little-endian issues, although it will reverse the byte order
+ /// in the tag for you(necessary for encoding). This ignores null values.
+ ///
+ /// The tag for this TLV.
+ /// The value of this TLV.
+ public void SetOptionalParamBytes(UInt16 tag, byte[] val)
+ {
+ _tlvTable.SetOptionalParamBytes(UnsignedNumConverter.SwapByteOrdering(tag), val);
+ }
+
+ ///
+ /// Allows the updating of TLV values. This will not take care of
+ /// big-endian/little-endian issues, although it will reverse the byte order
+ /// in the tag for you(necessary for encoding).
+ ///
+ /// The tag for this TLV.
+ /// The value of this TLV.
+ public void UpdateOptionalParamBytes(UInt16 tag, byte[] val)
+ {
+ _tlvTable.UpdateOptionalParamBytes(UnsignedNumConverter.SwapByteOrdering(tag), val);
+ }
+
+ ///
+ /// Allows the updating of TLV values. This will reverse the byte order in the tag for you
+ ///(necessary for encoding).
+ ///
+ /// The tag for this TLV.
+ /// The value of this TLV.
+ public void UpdateOptionalParamString(UInt16 tag, string val)
+ {
+ _tlvTable.UpdateOptionalParamString(UnsignedNumConverter.SwapByteOrdering(tag), val);
+ }
+
+ ///
+ /// Takes the given bytes and attempts to insert them into the TLV table.
+ ///
+ /// The bytes to convert for the TLVs.
+ protected void TranslateTlvDataIntoTable(byte[] tlvBytes)
+ {
+ _tlvTable.TranslateTlvDataIntoTable(tlvBytes);
+ }
+
+ ///
+ /// Takes the given bytes and attempts to insert them into the TLV table.
+ ///
+ /// The bytes to convert for the TLVs.
+ /// The index of the byte array to start at. This is here
+ /// because in some instances you may not want to start at the
+ /// beginning.
+ protected void TranslateTlvDataIntoTable(byte[] tlvBytes, Int32 index)
+ {
+ #if DEBUG
+ Console.WriteLine("Calling TranslateTlvDataIntoTable(byte[], Int32)");
+ #endif
+ _tlvTable.TranslateTlvDataIntoTable(tlvBytes, index);
+ }
+
+ ///
+ /// Adds the TLV bytes to the given Pdu.
+ ///
+ /// The Pdu to add to.
+ protected void AddTlvBytes(ref ArrayList pdu)
+ {
+ ArrayList tlvs = _tlvTable.GenerateByteEncodedTlv();
+ foreach(byte[] tlv in tlvs)
+ {
+ #if DEBUG
+ StringBuilder sb = new StringBuilder("\nAdding TLV bytes\n");
+ for(int i = 0; i < tlv.Length; i++)
+ {
+ sb.Append(tlv[i].ToString("X").PadLeft(2, '0'));
+ sb.Append(" ");
+ }
+ sb.Append("\n");
+ Console.WriteLine(sb);
+
+ #endif
+
+ pdu.AddRange(tlv);
+ }
+ }
+
+ #endregion TLV table methods
+
+ #region enumerations
+
+ ///
+ /// Enumerates the bearer types for source and destination.
+ ///
+ public enum BearerType : byte
+ {
+ ///
+ /// Unknown
+ ///
+ Unknown = 0x00,
+ ///
+ /// SMS
+ ///
+ SMS = 0x01,
+ ///
+ /// CircuitSwitchedData
+ ///
+ CircuitSwitchedData = 0x02,
+ ///
+ /// PacketData
+ ///
+ PacketData = 0x03,
+ ///
+ /// USSD
+ ///
+ USSD = 0x04,
+ ///
+ /// CDPD
+ ///
+ CDPD = 0x05,
+ ///
+ /// DataTAC
+ ///
+ DataTAC = 0x06,
+ ///
+ /// FLEX_ReFLEX
+ ///
+ FLEX_ReFLEX = 0x07,
+ ///
+ /// CellBroadcast
+ ///
+ CellBroadcast = 0x08
+ }
+
+ ///
+ /// Enumerates the network types for the source and destination.
+ ///
+ public enum NetworkType : byte
+ {
+ ///
+ /// Unknown
+ ///
+ Unknown = 0x00,
+ ///
+ /// GSM
+ ///
+ GSM = 0x01,
+ ///
+ /// ANSI_136_TDMA
+ ///
+ ANSI_136_TDMA = 0x02,
+ ///
+ /// IS_95_CDMA
+ ///
+ IS_95_CDMA = 0x03,
+ ///
+ /// PDC
+ ///
+ PDC = 0x04,
+ ///
+ /// PHS
+ ///
+ PHS = 0x05,
+ ///
+ /// iDEN
+ ///
+ iDEN = 0x06,
+ ///
+ /// AMPS
+ ///
+ AMPS = 0x07,
+ ///
+ /// PagingNetwork
+ ///
+ PagingNetwork = 0x08
+ }
+
+ ///
+ /// Enumerates the different states a message can be in.
+ ///
+ public enum MessageStateType : byte
+ {
+ ///
+ /// Enroute
+ ///
+ Enroute = 1,
+ ///
+ /// Delivered
+ ///
+ Delivered = 2,
+ ///
+ /// Expired
+ ///
+ Expired = 3,
+ ///
+ /// Deleted
+ ///
+ Deleted = 4,
+ ///
+ /// Undeliverable
+ ///
+ Undeliverable = 5,
+ ///
+ /// Accepted
+ ///
+ Accepted = 6,
+ ///
+ /// Unknown
+ ///
+ Unknown = 7,
+ ///
+ /// Rejected
+ ///
+ Rejected = 8
+ }
+
+ ///
+ /// SMPP version type.
+ ///
+ public enum SmppVersionType : byte
+ {
+ ///
+ /// Version 3.3 of the SMPP spec.
+ ///
+ Version3_3 = 0x33,
+ ///
+ /// Version 3.4 of the SMPP spec.
+ ///
+ Version3_4 = 0x34
+ }
+
+ ///
+ /// Enumerates the source address subunit types.
+ ///
+ public enum AddressSubunitType : byte
+ {
+ ///
+ /// Unknown
+ ///
+ Unknown = 0x00,
+ ///
+ /// MSDisplay
+ ///
+ MSDisplay = 0x01,
+ ///
+ /// MobileEquipment
+ ///
+ MobileEquipment = 0x02,
+ ///
+ /// SmartCard1
+ ///
+ SmartCard1 = 0x03,
+ ///
+ /// ExternalUnit1
+ ///
+ ExternalUnit1 = 0x04
+ }
+
+ ///
+ /// Enumerates the display time type.
+ ///
+ public enum DisplayTimeType : byte
+ {
+ ///
+ /// Temporary
+ ///
+ Temporary = 0x00,
+ ///
+ /// Default
+ ///
+ Default = 0x01,
+ ///
+ /// Invoke
+ ///
+ Invoke = 0x02
+ }
+
+ ///
+ /// Enumerates the type of the ITS Reply Type
+ ///
+ public enum ItsReplyTypeType : byte
+ {
+ ///
+ /// Digit
+ ///
+ Digit = 0,
+ ///
+ /// Number
+ ///
+ Number = 1,
+ ///
+ /// TelephoneNum
+ ///
+ TelephoneNum = 2,
+ ///
+ /// Password
+ ///
+ Password = 3,
+ ///
+ /// CharacterLine
+ ///
+ CharacterLine = 4,
+ ///
+ /// Menu
+ ///
+ Menu = 5,
+ ///
+ /// Date
+ ///
+ Date = 6,
+ ///
+ /// Time
+ ///
+ Time = 7,
+ ///
+ /// Continue
+ ///
+ Continue = 8
+ }
+
+ ///
+ /// Enumerates the MS Display type.
+ ///
+ public enum MsValidityType : byte
+ {
+ ///
+ /// StoreIndefinitely
+ ///
+ StoreIndefinitely = 0x00,
+ ///
+ /// PowerDown
+ ///
+ PowerDown = 0x01,
+ ///
+ /// SIDBased
+ ///
+ SIDBased = 0x02,
+ ///
+ /// DisplayOnly
+ ///
+ DisplayOnly = 0x03
+ }
+
+ ///
+ /// Enumerates all of the "standard" optional codes. This is more for
+ /// convenience when writing/updating this library than for end programmers,
+ /// as the the TLV table methods take a ushort/UInt16 rather than an
+ /// OptionalParamCodes enumeration.
+ ///
+ public enum OptionalParamCodes : ushort
+ {
+ ///
+ /// Destination address subunit
+ ///
+ dest_addr_subunit = 0x0005,
+ ///
+ /// Destination address network type
+ ///
+ dest_network_type = 0x0006,
+ ///
+ /// Destination address bearer type
+ ///
+ dest_bearer_type = 0x0007,
+ ///
+ /// Destination address telematics ID
+ ///
+ dest_telematics_id = 0x0008,
+ ///
+ /// Source address subunit
+ ///
+ source_addr_subunit = 0x000D,
+ ///
+ /// Source address network type
+ ///
+ source_network_type = 0x000E,
+ ///
+ /// Source address bearer type
+ ///
+ source_bearer_type = 0x000F,
+ ///
+ /// Source address telematics ID
+ ///
+ source_telematics_id = 0x0010,
+ ///
+ /// Quality of service time to live
+ ///
+ qos_time_to_live = 0x0017,
+ ///
+ /// Payload type
+ ///
+ payload_type = 0x0019,
+ ///
+ /// Additional status info
+ ///
+ additional_status_info_text = 0x001D,
+ ///
+ /// Receipted message ID
+ ///
+ receipted_message_id = 0x001E,
+ ///
+ /// Message wait facilities
+ ///
+ ms_msg_wait_facilities = 0x0030,
+ ///
+ /// Privacy indicator
+ ///
+ privacy_indicator = 0x0201,
+ ///
+ /// Source subaddress
+ ///
+ source_subaddress = 0x0202,
+ ///
+ /// Destination subaddress
+ ///
+ dest_subaddress = 0x0203,
+ ///
+ /// User message reference
+ ///
+ user_message_reference = 0x0204,
+ ///
+ /// User response code
+ ///
+ user_response_code = 0x0205,
+ ///
+ /// Source port
+ ///
+ source_port = 0x020A,
+ ///
+ /// Destination port
+ ///
+ destination_port = 0x020B,
+ ///
+ /// Message reference number
+ ///
+ sar_msg_ref_num = 0x020C,
+ ///
+ /// Language indicator
+ ///
+ language_indicator = 0x020D,
+ ///
+ /// Total segments
+ ///
+ sar_total_segments = 0x020E,
+ ///
+ /// Segment sequence number
+ ///
+ sar_segment_seqnum = 0x020F,
+ ///
+ /// Interface version
+ ///
+ SC_interface_version = 0x0210,
+ ///
+ /// Callback number indicator
+ ///
+ callback_num_pres_ind = 0x0302,
+ ///
+ /// Callback number tag
+ ///
+ callback_num_atag = 0x0303,
+ ///
+ /// Total number of messages
+ ///
+ number_of_messages = 0x0304,
+ ///
+ /// Callback number
+ ///
+ callback_num = 0x0381,
+ ///
+ /// DPF result
+ ///
+ dpf_result = 0x0420,
+ ///
+ /// Set DPF
+ ///
+ set_dpf = 0x0421,
+ ///
+ /// Availability status
+ ///
+ ms_availability_status = 0x0422,
+ ///
+ /// Network error code
+ ///
+ network_error_code = 0x0423,
+ ///
+ /// Message payload
+ ///
+ message_payload = 0x0424,
+ ///
+ /// Reason for delivery failure
+ ///
+ delivery_failure_reason = 0x0425,
+ ///
+ /// More messages to send flag
+ ///
+ more_messages_to_send = 0x0426,
+ ///
+ /// Message state
+ ///
+ message_state = 0x0427,
+ ///
+ /// USSD service opcode
+ ///
+ ussd_service_op = 0x0501,
+ ///
+ /// Display time
+ ///
+ display_time = 0x1201,
+ ///
+ /// SMS signal
+ ///
+ sms_signal = 0x1203,
+ ///
+ /// Message validity
+ ///
+ ms_validity = 0x1204,
+ ///
+ /// Alert on message delivery
+ ///
+ alert_on_message_delivery = 0x130C,
+ ///
+ /// ITS reply type
+ ///
+ its_reply_type = 0x1380,
+ ///
+ /// ITS session info
+ ///
+ its_session_info = 0x1383
+ }
+
+ ///
+ /// Enumerates the type of number types that can be used for the SMSC
+ /// message
+ /// sending.
+ ///
+ public enum TonType : byte
+ {
+ ///
+ /// Unknown
+ ///
+ Unknown = 0x00,
+ ///
+ /// International
+ ///
+ International = 0x01,
+ ///
+ /// National
+ ///
+ National = 0x02,
+ ///
+ /// Network specific
+ ///
+ NetworkSpecific = 0x03,
+ ///
+ /// Subscriber number
+ ///
+ SubscriberNumber = 0x04,
+ ///
+ /// Alphanumeric
+ ///
+ Alphanumeric = 0x05,
+ ///
+ /// Abbreviated
+ ///
+ Abbreviated = 0x06
+ }
+
+ ///
+ /// Enumerates the number plan indicator types that can be used for the
+ /// SMSC
+ /// message sending.
+ ///
+ public enum NpiType : byte
+ {
+ ///
+ /// Unknown
+ ///
+ Unknown = 0x00,
+ ///
+ /// ISDN
+ ///
+ ISDN = 0x01,
+ ///
+ /// Data
+ ///
+ Data = 0x03,
+ ///
+ /// Telex
+ ///
+ Telex = 0x04,
+ ///
+ /// Land mobile
+ ///
+ LandMobile = 0x06,
+ ///
+ /// National
+ ///
+ National = 0x08,
+ ///
+ /// Private
+ ///
+ Private = 0x09,
+ ///
+ /// ERMES
+ ///
+ ERMES = 0x0A,
+ ///
+ /// Internet
+ ///
+ Internet = 0x0E
+ }
+
+ ///
+ /// Enumerates the priority level of the message.
+ ///
+ public enum PriorityType : byte
+ {
+ ///
+ /// Lowest
+ ///
+ Lowest = 0x00,
+ ///
+ /// Level1
+ ///
+ Level1 = 0x01,
+ ///
+ /// Level2
+ ///
+ Level2 = 0x02,
+ ///
+ /// Highest
+ ///
+ Highest = 0x03
+ }
+
+ ///
+ /// Enumerates the types of registered delivery. Not all possible options
+ /// are present, just the common ones.
+ ///
+ public enum RegisteredDeliveryType : byte
+ {
+ ///
+ /// No registered delivery
+ ///
+ None = 0x00,
+ ///
+ /// Notification on success or failure
+ ///
+ OnSuccessOrFailure = 0x01,
+ ///
+ /// Notification on failure only
+ ///
+ OnFailure = 0x02
+ }
+
+ ///
+ /// Enumerates the data coding types.
+ ///
+ public enum DataCodingType : byte
+ {
+ ///
+ /// SMSCDefault
+ ///
+ SMSCDefault = 0x00,
+ ///
+ /// IA5_ASCII
+ ///
+ IA5_ASCII = 0x01,
+ ///
+ /// OctetUnspecifiedB
+ ///
+ OctetUnspecifiedB = 0x02,
+ ///
+ /// Latin1
+ ///
+ Latin1 = 0x03,
+ ///
+ /// OctetUnspecifiedA
+ ///
+ OctetUnspecifiedA = 0x04,
+ ///
+ /// JIS
+ ///
+ JIS = 0x05,
+ ///
+ /// Cyrillic
+ ///
+ Cyrillic = 0x06,
+ ///
+ /// Latin_Hebrew
+ ///
+ Latin_Hebrew = 0x07,
+ ///
+ /// Pictogram
+ ///
+ Pictogram = 0x09,
+ ///
+ /// MusicCodes
+ ///
+ MusicCodes = 0x0A,
+ ///
+ /// ExtendedKanjiJIS
+ ///
+ ExtendedKanjiJIS = 0x0D,
+ ///
+ /// KS_C
+ ///
+ KS_C = 0x0E
+ }
+
+ ///
+ /// Enumerates the privacy indicator types.
+ ///
+ public enum PrivacyType : byte
+ {
+ ///
+ /// Nonrestricted
+ ///
+ Nonrestricted = 0x00,
+ ///
+ /// Restricted
+ ///
+ Restricted = 0x01,
+ ///
+ /// Confidential
+ ///
+ Confidential = 0x03,
+ ///
+ /// Secret
+ ///
+ Secret = 0x03
+ }
+
+ ///
+ /// Enumerates the types of payload type.
+ ///
+ public enum PayloadTypeType : byte
+ {
+ ///
+ /// WDPMessage
+ ///
+ WDPMessage = 0x00,
+ ///
+ /// WCMPMessage
+ ///
+ WCMPMessage = 0x01
+ }
+
+ ///
+ /// Enumerates the language types.
+ ///
+ public enum LanguageType : byte
+ {
+ ///
+ /// Unspecified
+ ///
+ Unspecified = 0x00,
+ ///
+ /// English
+ ///
+ English = 0x01,
+ ///
+ /// French
+ ///
+ French = 0x02,
+ ///
+ /// Spanish
+ ///
+ Spanish = 0x03,
+ ///
+ /// German
+ ///
+ German = 0x04,
+ ///
+ /// Portuguese
+ ///
+ Portuguese = 0x05
+ }
+
+ ///
+ /// Enumerates the DPF result types.
+ ///
+ public enum DpfResultType : byte
+ {
+ ///
+ /// DPFNotSet
+ ///
+ DPFNotSet = 0,
+ ///
+ /// DPFSet
+ ///
+ DPFSet = 1
+ }
+
+ ///
+ /// Enumeration of all the Pdu command types.
+ ///
+ public enum CommandIdType : uint
+ {
+ ///
+ /// generic_nack
+ ///
+ generic_nack = 0x80000000,
+ ///
+ /// bind_receiver
+ ///
+ bind_receiver = 0x00000001,
+ ///
+ /// bind_receiver_resp
+ ///
+ bind_receiver_resp = 0x80000001,
+ ///
+ /// bind_transmitter
+ ///
+ bind_transmitter = 0x00000002,
+ ///
+ /// bind_transmitter_resp
+ ///
+ bind_transmitter_resp = 0x80000002,
+ ///
+ /// query_sm
+ ///
+ query_sm = 0x00000003,
+ ///
+ /// query_sm_resp
+ ///
+ query_sm_resp = 0x80000003,
+ ///
+ /// submit_sm
+ ///
+ submit_sm = 0x00000004,
+ ///
+ /// submit_sm_resp
+ ///
+ submit_sm_resp = 0x80000004,
+ ///
+ /// deliver_sm
+ ///
+ deliver_sm = 0x00000005,
+ ///
+ /// deliver_sm_resp
+ ///
+ deliver_sm_resp = 0x80000005,
+ ///
+ /// unbind
+ ///
+ unbind = 0x00000006,
+ ///
+ /// unbind_resp
+ ///
+ unbind_resp = 0x80000006,
+ ///
+ /// replace_sm
+ ///
+ replace_sm = 0x00000007,
+ ///
+ /// replace_sm_resp
+ ///
+ replace_sm_resp = 0x80000007,
+ ///
+ /// cancel_sm
+ ///
+ cancel_sm = 0x00000008,
+ ///
+ /// cancel_sm_resp
+ ///
+ cancel_sm_resp = 0x80000008,
+ ///
+ /// bind_transceiver
+ ///
+ bind_transceiver = 0x00000009,
+ ///
+ /// bind_transceiver_resp
+ ///
+ bind_transceiver_resp = 0x80000009,
+ ///
+ /// outbind
+ ///
+ outbind = 0x0000000B,
+ ///
+ /// enquire_link
+ ///
+ enquire_link = 0x00000015,
+ ///
+ /// enquire_link_resp
+ ///
+ enquire_link_resp = 0x80000015,
+ ///
+ /// submit_multi
+ ///
+ submit_multi = 0x00000021,
+ ///
+ /// submit_multi_resp
+ ///
+ submit_multi_resp = 0x80000021,
+ ///
+ /// alert_notification
+ ///
+ alert_notification = 0x00000102,
+ ///
+ /// data_sm
+ ///
+ data_sm = 0x00000103,
+ ///
+ /// data_sm_resp
+ ///
+ data_sm_resp = 0x80000103
+ }
+
+ #endregion enumerations
+
+ #region utility methods
+
+ ///
+ /// Trims the trailing zeroes off of the response Pdu. Useful for
+ /// tracing and other purposes. This uses the command length to
+ /// actually trim it down, so TLVs and strings are not lost. If the
+ /// response actually is the same length as the command length, this
+ /// method performs a pass-through.
+ ///
+ /// The trimmed Pdu(byte array).
+ public static byte[] TrimResponsePdu(byte[] response)
+ {
+ uint commLength = DecodeCommandLength(response);
+ if(commLength == response.Length)
+ {
+ return response;
+ }
+ //trap any weird data coming in
+ if(commLength >= Int32.MaxValue || commLength > response.Length)
+ {
+ return new Byte[0];
+ }
+
+ byte[] trimmed = new Byte[commLength];
+ for(int i = 0; i < trimmed.Length; i++)
+ {
+ trimmed[i] = response[i];
+ }
+
+ return trimmed;
+ }
+
+ ///
+ /// Utility method to allow the Pdu factory to decode the command
+ /// ID without knowing about packet structure. Some SMSCs combine
+ /// response packets(even though they shouldn't).
+ ///
+ /// The Pdu response packet.
+ /// The ID of the Pdu command(e.g. cancel_sm_resp).
+ public static CommandIdType DecodeCommandId(byte[] response)
+ {
+ uint id = 0;
+ try
+ {
+ id = UnsignedNumConverter.SwapByteOrdering(BitConverter.ToUInt32(response, 4));
+ return(CommandIdType)id;
+ }
+ catch //possible that we are reading a bad command
+ {
+ return CommandIdType.generic_nack;
+ }
+ }
+
+ ///
+ /// Utility method to allow the Pdu factory to decode the command
+ /// length without knowing about packet structure. Some SMSCs combine
+ /// response packets(even though they shouldn't).
+ ///
+ /// The Pdu response packet.
+ /// The length of the Pdu command.
+ public static UInt32 DecodeCommandLength(byte[] response)
+ {
+ return UnsignedNumConverter.SwapByteOrdering(BitConverter.ToUInt32(response, 0));
+ }
+
+ #endregion utility methods
+
+ #region IDisposable methods
+
+ ///
+ /// Implementation of IDisposable
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Method for derived classes to implement.
+ ///
+ /// Set to false if called from a finalizer.
+ protected virtual void Dispose(bool disposing)
+ {
+ if(disposing)
+ {
+ // Free other state(managed objects).
+ }
+ // Free your own state(unmanaged objects).
+ // Set large fields to null.
+ }
+
+ ///
+ /// Finalizer. Base classes will inherit this-used when Dispose()is not automatically called.
+ ///
+ ~Pdu()
+ {
+ // Simply call Dispose(false).
+ Dispose(false);
+ }
+
+ #endregion IDisposable methods
+ }
+}
diff --git a/Packet/Request/MessageLcd2.cs b/Packet/Request/MessageLcd2.cs
new file mode 100644
index 0000000..6054d1b
--- /dev/null
+++ b/Packet/Request/MessageLcd2.cs
@@ -0,0 +1,267 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// This class encapsulates common attributes for submit_sm and submit_multi Pdus.
+ ///
+ public abstract class MessageLcd2 : MessageLcd3
+ {
+ ///
+ /// Limit of short message.
+ ///
+ public const int SHORT_MESSAGE_LIMIT = 160;
+
+ #region private fields
+
+ private SmppVersionType _ProtocolId = Pdu.SmppVersionType.Version3_4;
+ private PriorityType _PriorityFlag = Pdu.PriorityType.Level1;
+ private string _ScheduleDeliveryTime = string.Empty;
+ private string _ValidityPeriod = string.Empty;
+ private bool _ReplaceIfPresentFlag = false;
+ private byte _SmDefaultMessageId = 0;
+ private object _ShortMessage = null;
+
+ #endregion private fields
+
+ #region protected fields
+
+ ///
+ /// The length of the short message.
+ ///
+ protected byte _SmLength = 0;
+
+ #endregion protected fields
+
+ #region properties
+
+ ///
+ /// Protocol Identifier; network specific field.
+ ///
+ public SmppVersionType ProtocolId
+ {
+ get
+ {
+ return _ProtocolId;
+ }
+ set
+ {
+ _ProtocolId = value;
+ }
+ }
+
+ ///
+ /// The priority level of the message.
+ ///
+ public PriorityType PriorityFlag
+ {
+ get
+ {
+ return _PriorityFlag;
+ }
+ set
+ {
+ _PriorityFlag = value;
+ }
+ }
+
+ ///
+ /// Scheduled delivery time for the message delivery. Set to null for immediate
+ /// delivery. Otherwise, use YYMMDDhhmmsstnn as the format. See section 7.1.1 of
+ /// the SMPP spec for more details.
+ ///
+ public string ScheduleDeliveryTime
+ {
+ get
+ {
+ return _ScheduleDeliveryTime;
+ }
+ set
+ {
+ if(value != null && value != string.Empty)
+ {
+ if(value.Length == DATE_TIME_LENGTH)
+ {
+ _ScheduleDeliveryTime = value;
+ }
+ else
+ {
+ throw new ArgumentException("Scheduled delivery time not in correct format.");
+ }
+ }
+ else
+ {
+ _ScheduleDeliveryTime = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// The validity period of this message. Set to null to request the SMSC default
+ /// validity period. Otherwise, use YYMMDDhhmmsstnn as the format. See section 7.1.1 of
+ /// the SMPP spec for more details.
+ ///
+ public string ValidityPeriod
+ {
+ get
+ {
+ return _ValidityPeriod;
+ }
+ set
+ {
+ if(value != null && value != string.Empty)
+ {
+ if(value.Length == DATE_TIME_LENGTH)
+ {
+ _ValidityPeriod = value;
+ }
+ else
+ {
+ throw new ArgumentException("Validity period not in correct format.");
+ }
+ }
+ else
+ {
+ _ValidityPeriod = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// Flag indicating if submitted message should replace an existing message.
+ ///
+ public bool ReplaceIfPresentFlag
+ {
+ get
+ {
+ return _ReplaceIfPresentFlag;
+ }
+ set
+ {
+ _ReplaceIfPresentFlag = value;
+ }
+ }
+
+ ///
+ /// Allows use of a canned message from the SMSC. If not using an SMSC canned message,
+ /// set to 0.
+ ///
+ public byte SmDefaultMessageId
+ {
+ get
+ {
+ return _SmDefaultMessageId;
+ }
+ set
+ {
+ _SmDefaultMessageId = value;
+ }
+ }
+
+ ///
+ /// The short message to send, up to 160 octets. If you need more length, use the
+ /// MessagePayload property. Do not use both at the same time! Setting this to null
+ /// will result in an empty string. This can be either a string or a byte array; anything
+ /// else will result in an exception.
+ ///
+ public object ShortMessage
+ {
+ get
+ {
+ return _ShortMessage;
+ }
+ set
+ {
+ _ShortMessage = value;
+ }
+ }
+
+ ///
+ /// The length of the short message.
+ ///
+ public byte SmLength
+ {
+ get
+ {
+ return _SmLength;
+ }
+ }
+
+ #endregion properties
+
+ #region constructors
+
+ ///
+ /// Groups construction tasks for subclasses. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// ESM class to 0, data coding to SMSC default, protocol ID to v3.4, priority to level 1,
+ /// validity period to default, replace if present to false, default message ID to 0,
+ /// and the short message to an empty string.
+ ///
+ protected MessageLcd2(): base()
+ {}
+
+ ///
+ /// Creates a new MessageLcd2 for incoming PDUs.
+ ///
+ /// The incoming bytes to decode.
+ protected MessageLcd2(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Creates the bytes after the destination address bytes. This also inserts the TLV
+ /// table data. Common to both submit and submit multiple.
+ ///
+ /// The bytes in the Pdu before the destination address(es).
+ protected ArrayList GetBytesAfterDestination()
+ {
+ ArrayList pdu = new ArrayList();
+ pdu.Add(EsmClass);
+ pdu.Add((byte)ProtocolId);
+ pdu.Add((byte)PriorityFlag);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ScheduleDeliveryTime)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ValidityPeriod)));
+ pdu.Add((byte)RegisteredDelivery);
+
+ if(ReplaceIfPresentFlag == true)
+ {
+ pdu.Add((byte)0x01);
+ }
+ else
+ {
+ pdu.Add((byte)0x00);
+ }
+
+ pdu.Add((byte)DataCoding);
+ pdu.Add(SmDefaultMessageId);
+ _SmLength = PduUtil.InsertShortMessage(pdu, ShortMessage);
+
+ pdu.TrimToSize();
+
+ return pdu;
+ }
+ }
+}
diff --git a/Packet/Request/MessageLcd3.cs b/Packet/Request/MessageLcd3.cs
new file mode 100644
index 0000000..31b15ca
--- /dev/null
+++ b/Packet/Request/MessageLcd3.cs
@@ -0,0 +1,601 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Provides some common attributes for data_sm, submit_sm, and submit_multi.
+ ///
+ public abstract class MessageLcd3 : MessageLcd4
+ {
+ #region private fields
+
+ private string _ServiceType = string.Empty;
+ private byte _EsmClass = 0;
+ private DataCodingType _DataCoding = Pdu.DataCodingType.SMSCDefault;
+
+ #endregion private fields
+
+ #region constants
+
+ private const int SAR_MIN = 1;
+ private const int SAR_MAX = 255;
+
+ #endregion constants
+
+ #region mandatory parameters
+
+ ///
+ /// The service type of the message. Null values are treated as empty strings.
+ ///
+ public string ServiceType
+ {
+ get
+ {
+ return _ServiceType;
+ }
+
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= SERVICE_TYPE_LENGTH)
+ {
+ _ServiceType = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("Service Type must be " +
+ SERVICE_TYPE_LENGTH + " 5 characters or less.");
+ }
+ }
+ else
+ {
+ _ServiceType = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// Indicates Message Mode and Message Type. See the SMSC version 3.4 specification
+ /// for details on setting this.
+ ///
+ public byte EsmClass
+ {
+ get
+ {
+ return _EsmClass;
+ }
+ set
+ {
+ _EsmClass = value;
+ }
+ }
+
+ ///
+ /// Defines the encoding scheme of the short message user data.
+ ///
+ public DataCodingType DataCoding
+ {
+ get
+ {
+ return _DataCoding;
+ }
+ set
+ {
+ _DataCoding = value;
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region optional params
+
+ ///
+ /// The application port number associated with the source address of the message.
+ /// This parameter should be present for WAP applications.
+ ///
+ public UInt16 SourcePort
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.source_port);
+ }
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.source_port, value);
+ }
+ else
+ {
+ throw new ArgumentException("source_port value too large.");
+ }
+ }
+ }
+
+ ///
+ /// The subcomponent in the destination device which created the user data.
+ ///
+ public AddressSubunitType SourceAddressSubunit
+ {
+ get
+ {
+ return (AddressSubunitType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.source_addr_subunit)[0];
+ }
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.source_addr_subunit, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// The application port number associated with the destination address of the
+ /// message. This parameter should be present for WAP applications.
+ ///
+ public UInt16 DestinationPort
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.destination_port);
+ }
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.destination_port, value);
+ }
+ else
+ {
+ throw new ArgumentException("destination_port value too large.");
+ }
+ }
+ }
+
+ ///
+ /// The reference number for a particular concatenated short message. Both
+ /// SarTotalSegments and SarSegmentSeqnum need to be set in conjunction with this
+ /// property. In addition, this must be the same for each segment.
+ ///
+ public UInt16 SarMsgRefNumber
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.sar_msg_ref_num);
+ }
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.sar_msg_ref_num, value);
+ }
+ else
+ {
+ throw new ArgumentException("sar_msg_ref_number value too large.");
+ }
+ }
+ }
+
+ ///
+ /// Indicates the total number of short messages within the concatenated short
+ /// message. Both SarMsgRefNumber and SarSegmentSeqNum need to be set in
+ /// conjunction with this property. In addition, this must be the same for each
+ /// segment.
+ ///
+ public byte SarTotalSegments
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.sar_total_segments)[0];
+ }
+
+ set
+ {
+ if(value >= SAR_MIN && value <= SAR_MAX)
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.sar_total_segments, new Byte[] {(byte)value});
+ }
+ else
+ {
+ throw new ArgumentException(
+ "sar_total_segments must be >= " + SAR_MIN + " and <= " + SAR_MAX);
+ }
+ }
+ }
+
+ ///
+ /// The sequence number of a particular short message within the concatenated
+ /// short message. Both SarMsgRefNumber and SarTotalSegments need to be set in
+ /// conjunction with this property.
+ ///
+ public byte SarSegmentSeqnum
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.sar_segment_seqnum)[0];
+ }
+
+ set
+ {
+ if(value >= SAR_MIN && value <= SAR_MAX)
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.sar_segment_seqnum, new Byte[] {(byte)value});
+ }
+ else
+ {
+ throw new ArgumentException(
+ "sar_segment_seqnum must be >= " + SAR_MIN + " and <= " + SAR_MAX);
+ }
+ }
+ }
+
+ ///
+ /// Defines the type of payload.
+ ///
+ public PayloadTypeType PayloadType
+ {
+ get
+ {
+ return (PayloadTypeType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.payload_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.payload_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Contains the extended short message user data. Up to 64K octets can be
+ /// transmitted. The limit for this is network/SMSC dependent.
+ ///
+ public object MessagePayload
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.message_payload);
+ }
+
+ set
+ {
+ PduUtil.SetMessagePayload(this, value);
+ }
+ }
+
+ ///
+ /// The privacy level of the message.
+ ///
+ public PrivacyType PrivacyIndicator
+ {
+ get
+ {
+ return (PrivacyType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.privacy_indicator)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.privacy_indicator, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// ESME assigned message reference number.
+ ///
+ public UInt16 UserMessageReference
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.user_message_reference);
+ }
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.user_message_reference, value);
+ }
+ else
+ {
+ throw new ArgumentException("user_message_reference too large.");
+ }
+ }
+ }
+
+ ///
+ /// Allows an indication to be provided to an MS that there are
+ /// messages waiting for the subscriber on systems on the PLMN. The indication
+ /// can be an icon on the MS screen or other MMI indication.
+ /// See section 5.3.2.13 for details on how to set this.
+ ///
+ public byte MsMsgWaitFacilities
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.ms_msg_wait_facilities)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.ms_msg_wait_facilities, new Byte[] {value});
+ }
+ }
+
+ ///
+ /// Provides a MS with validity information associated with the received
+ /// short message.
+ ///
+ public MsValidityType MsValidity
+ {
+ get
+ {
+ return (MsValidityType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.ms_validity)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.ms_validity, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Provides a TDMA MS station with alert tone information associated with the
+ /// received short message.
+ ///
+ public UInt16 SmsSignal
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.sms_signal);
+ }
+
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.sms_signal, value);
+ }
+ else
+ {
+ throw new ArgumentException("sms_signal value too large.");
+ }
+ }
+ }
+
+ ///
+ /// The subcomponent in the destination device for which the user data is intended.
+ ///
+ public AddressSubunitType DestinationAddrSubunit
+ {
+ get
+ {
+ return (AddressSubunitType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.dest_addr_subunit)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.dest_addr_subunit, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Tells a mobile station to alert the user when the short message arrives at the MS.
+ ///
+ /// Note: there is no value part associated with this parameter.
+ /// Any value you pass in will be discarded.
+ ///
+ public byte AlertOnMsgDelivery
+ {
+ get
+ {
+ try
+ {
+ byte[] bytes = GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.alert_on_message_delivery);
+ return 1;
+ }
+ catch(ApplicationException)
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.alert_on_message_delivery, new Byte[0]);
+ }
+ }
+
+ ///
+ /// The language of the short message.
+ ///
+ public LanguageType LanguageIndicator
+ {
+ get
+ {
+ return (LanguageType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.language_indicator)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.language_indicator, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Associates a display time with the short message on the MS.
+ ///
+ public DisplayTimeType DisplayTime
+ {
+ get
+ {
+ return (DisplayTimeType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.display_time)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.display_time, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Associates a call back number with the message. See section 5.3.2.36 of the
+ /// SMPP spec for details. This must be between 4 and 19 characters in length.
+ ///
+ public string CallbackNum
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.callback_num);
+ }
+
+ set
+ {
+ PduUtil.SetCallbackNum(this, value);
+ }
+ }
+
+ ///
+ /// Controls the presentation indication and screening of the CallBackNumber at the
+ /// mobile station. You must also use the callback_num parameter with this.
+ /// See section 5.3.2.37 of the SMPP spec for details in how to set this.
+ ///
+ public byte CallbackNumPresInd
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.callback_num_pres_ind)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.callback_num_pres_ind, new Byte[] {value});
+ }
+ }
+
+ ///
+ /// Alphanumeric display tag for call back number. This must be less than or
+ /// equal to 65 characters in length.
+ ///
+ public string CallbackNumAtag
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.callback_num_atag);
+ }
+
+ set
+ {
+ const int CALLBACK_ATAG_MAX = 65;
+
+ if(value.Length <= CALLBACK_ATAG_MAX)
+ {
+ SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.callback_num_atag, value);
+ }
+ else
+ {
+ throw new ArgumentException("Callback number atag must be <= " + CALLBACK_ATAG_MAX + ".");
+ }
+ }
+ }
+
+ ///
+ /// Specifies a subaddress associated with the originator of the message.
+ /// See section 5.3.2.15 of the SMPP spec for details on
+ /// setting this parameter.
+ ///
+ public string SourceSubaddress
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.source_subaddress);
+ }
+
+ set
+ {
+ PduUtil.SetSourceSubaddress(this, value);
+ }
+ }
+
+ ///
+ /// Specifies a subaddress associated with the receiver of the message.
+ /// See section 5.3.2.15 of the SMPP spec for details on
+ /// setting this parameter.
+ ///
+ public string DestinationSubaddress
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.dest_subaddress);
+ }
+
+ set
+ {
+ PduUtil.SetDestSubaddress(this, value);
+ }
+ }
+
+ #endregion optional params
+
+ #region constructors
+
+ ///
+ /// Groups construction tasks for subclasses. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// ESM class to 0, and data coding to SMSC default.
+ ///
+ protected MessageLcd3(): base()
+ {}
+
+ ///
+ /// Creates a new MessageLcd3 for incoming PDUs.
+ ///
+ /// The incoming bytes to decode.
+ protected MessageLcd3(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+ }
+}
diff --git a/Packet/Request/MessageLcd4.cs b/Packet/Request/MessageLcd4.cs
new file mode 100644
index 0000000..c3b28ab
--- /dev/null
+++ b/Packet/Request/MessageLcd4.cs
@@ -0,0 +1,72 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Provides some common attributes for data_sm, submit_sm, submit_multi,
+ /// and replace_sm.
+ ///
+ public abstract class MessageLcd4 : MessageLcd6
+ {
+ ///
+ /// The registered delivery type of the message.
+ ///
+ protected RegisteredDeliveryType _RegisteredDelivery = Pdu.RegisteredDeliveryType.None;
+
+ #region properties
+
+ ///
+ /// The registered delivery type of the message.
+ ///
+ public RegisteredDeliveryType RegisteredDelivery
+ {
+ get
+ {
+ return _RegisteredDelivery;
+ }
+ set
+ {
+ _RegisteredDelivery = value;
+ }
+ }
+
+ #endregion properties
+
+ #region constructors
+
+ ///
+ /// Groups construction tasks for subclasses. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", and registered delivery type to
+ /// none.
+ ///
+ protected MessageLcd4(): base()
+ {}
+
+ ///
+ /// Creates a new MessageLcd4 for incoming PDUs.
+ ///
+ /// The incoming bytes to decode.
+ protected MessageLcd4(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+ }
+}
diff --git a/Packet/Request/MessageLcd6.cs b/Packet/Request/MessageLcd6.cs
new file mode 100644
index 0000000..c1f9eea
--- /dev/null
+++ b/Packet/Request/MessageLcd6.cs
@@ -0,0 +1,135 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Provides some common attributes for data_sm, query_sm, submit_sm, submit_multi,
+ /// cancel_sm, and replace_sm.
+ ///
+ public abstract class MessageLcd6 : Pdu
+ {
+ #region private fields
+
+ private TonType _SourceAddressTon = Pdu.TonType.International;
+ private NpiType _SourceAddressNpi = Pdu.NpiType.ISDN;
+ private string _SourceAddress = string.Empty;
+
+ #endregion private fields
+
+ #region constants
+ ///
+ /// Address length for source and destination addresses
+ ///
+ protected const int ADDRESS_LENGTH = 20;
+ ///
+ /// Message length
+ ///
+ protected const int MSG_LENGTH = 64;
+ ///
+ /// Length of service type string
+ ///
+ protected const int SERVICE_TYPE_LENGTH = 50;
+
+ #endregion constants
+
+ #region properties
+
+ ///
+ /// The type of number of the source address.
+ ///
+ public TonType SourceAddressTon
+ {
+ get
+ {
+ return _SourceAddressTon;
+ }
+ set
+ {
+ _SourceAddressTon = value;
+ }
+ }
+
+ ///
+ /// The number plan indicator of the source address.
+ ///
+ public NpiType SourceAddressNpi
+ {
+ get
+ {
+ return _SourceAddressNpi;
+ }
+ set
+ {
+ _SourceAddressNpi = value;
+ }
+ }
+
+ ///
+ /// The source address. Null values are treated as empty strings.
+ ///
+ public string SourceAddress
+ {
+ get
+ {
+ return _SourceAddress;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= ADDRESS_LENGTH)
+ {
+ _SourceAddress = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Source Address must be <= " + ADDRESS_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _SourceAddress = string.Empty;
+ }
+ }
+ }
+
+ #endregion properties
+
+ #region constructors
+
+ ///
+ /// Groups construction tasks for subclasses. Sets source address TON to
+ /// international, source address NPI to ISDN, and source address to "".
+ ///
+ protected MessageLcd6(): base()
+ {}
+
+ ///
+ /// Creates a new MessageLcd6 for incoming PDUs.
+ ///
+ /// The incoming bytes to decode.
+ protected MessageLcd6(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+ }
+}
diff --git a/Packet/Request/SmppAlertNotification.cs b/Packet/Request/SmppAlertNotification.cs
new file mode 100644
index 0000000..9de4ccb
--- /dev/null
+++ b/Packet/Request/SmppAlertNotification.cs
@@ -0,0 +1,248 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Sent from the SMSC to the mobile device when the device is available and a
+ /// delivery pending flag has been set from a previous data_sm operation.
+ ///
+ public class SmppAlertNotification : Pdu
+ {
+ #region private fields
+
+ private TonType _SourceAddressTon = TonType.International;
+ private NpiType _SourceAddressNpi = NpiType.ISDN;
+ private string _SourceAddress = string.Empty;
+ private TonType _EsmeAddressTon = TonType.International;
+ private NpiType _EsmeAddressNpi = NpiType.ISDN;
+ private string _EsmeAddress = string.Empty;
+
+ #endregion private fields
+
+ #region enumerations
+
+ ///
+ /// Enumerates the availability states of the message.
+ ///
+ public enum AvailabilityStatusType : byte
+ {
+ ///
+ /// Available
+ ///
+ Available = 0x00,
+ ///
+ /// Denied
+ ///
+ Denied = 0x01,
+ ///
+ /// Unavailable
+ ///
+ Unavailable = 0x02
+ }
+
+ #endregion enumerations
+
+ #region mandatory parameters
+
+ ///
+ /// Enumerates the type of number.
+ ///
+ public TonType SourceAddressTon
+ {
+ get
+ {
+ return _SourceAddressTon;
+ }
+
+ set
+ {
+ _SourceAddressTon = value;
+ }
+ }
+
+ ///
+ /// Enumerates the numbering plan indicator.
+ ///
+ public NpiType SourceAddressNpi
+ {
+ get
+ {
+ return _SourceAddressNpi;
+ }
+
+ set
+ {
+ _SourceAddressNpi = value;
+ }
+ }
+
+ ///
+ /// Address of sending entity.
+ ///
+ public string SourceAddress
+ {
+ get
+ {
+ return _SourceAddress;
+ }
+
+ set
+ {
+ _SourceAddress = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// The type of number for the destination address that requested an alert.
+ ///
+ public TonType EsmeAddressTon
+ {
+ get
+ {
+ return _EsmeAddressTon;
+ }
+
+ set
+ {
+ _EsmeAddressTon = value;
+ }
+ }
+
+ ///
+ /// The numbering plan indicator for the destination address that requested an alert.
+ ///
+ public NpiType EsmeAddressNpi
+ {
+ get
+ {
+ return _EsmeAddressNpi;
+ }
+
+ set
+ {
+ _EsmeAddressNpi = value;
+ }
+ }
+
+ ///
+ /// The source address of the device that requested an alert.
+ ///
+ public string EsmeAddress
+ {
+ get
+ {
+ return _EsmeAddress;
+ }
+
+ set
+ {
+ _EsmeAddress = (value == null) ? string.Empty : value;
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region optional parameters
+
+ ///
+ /// The status of the mobile station.
+ ///
+ public AvailabilityStatusType MSAvailabilityStatus
+ {
+ get
+ {
+ return(AvailabilityStatusType)GetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.ms_availability_status)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.ms_availability_status, new Byte[] {(byte)value});
+ }
+ }
+
+ #endregion optional parameters
+
+ #region constructors
+
+ ///
+ /// Creates an SMPP Alert Notification Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppAlertNotification(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates an SMPP Alert Notification Pdu.
+ ///
+ public SmppAlertNotification(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the alert_notification from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ SourceAddressTon =(TonType)remainder[0];
+ SourceAddressNpi =(NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ EsmeAddressTon =(TonType)remainder[0];
+ EsmeAddressNpi =(NpiType)remainder[1];
+ EsmeAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder);
+ }
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.alert_notification;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ pdu.Add((byte)EsmeAddressTon);
+ pdu.Add((byte)EsmeAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(EsmeAddress)));
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Request/SmppBind.cs b/Packet/Request/SmppBind.cs
new file mode 100644
index 0000000..c4889aa
--- /dev/null
+++ b/Packet/Request/SmppBind.cs
@@ -0,0 +1,343 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Class for a bind request Pdu.
+ ///
+ public class SmppBind : Pdu
+ {
+ #region private fields
+
+ private string _SystemId = string.Empty;
+ private string _Password = string.Empty;
+ private string _SystemType = string.Empty;
+ private string _AddressRange = string.Empty;
+ private SmppVersionType _InterfaceVersion = Pdu.SmppVersionType.Version3_4;
+ private TonType _AddressTon = Pdu.TonType.International;
+ private NpiType _AddressNpi = Pdu.NpiType.ISDN;
+ private BindingType _BindType = BindingType.BindAsTransceiver;
+
+ #endregion private fields
+
+ #region constants
+
+ private const int ID_LENGTH = 15;
+ private const int PASS_LENGTH = 8;
+ private const int TYPE_LENGTH = 12;
+ private const int RANGE_LENGTH = 40;
+
+ #endregion constants
+
+ #region mandatory parameters
+
+ ///
+ /// The binding type: transmitter, receiver, or transceiver.
+ ///
+ public BindingType BindType
+ {
+ get
+ {
+ return _BindType;
+ }
+ set
+ {
+ switch(value)
+ {
+ case BindingType.BindAsReceiver:
+ {
+ CommandID = CommandIdType.bind_receiver;
+ break;
+ }
+ case BindingType.BindAsTransceiver:
+ {
+ CommandID = CommandIdType.bind_transceiver;
+ break;
+ }
+ case BindingType.BindAsTransmitter:
+ {
+ CommandID = CommandIdType.bind_transmitter;
+ break;
+ }
+ default:
+ {
+ CommandID = CommandIdType.bind_transmitter;
+ break;
+ }
+ }
+
+ _BindType = value;
+ }
+ }
+
+ ///
+ /// The ESME system requesting to bind with the SMSC. Set to null for default value.
+ ///
+ public string SystemId
+ {
+ get
+ {
+ return _SystemId;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= ID_LENGTH)
+ _SystemId = value;
+ else
+ throw new ArgumentOutOfRangeException("System ID must be <= "+
+ ID_LENGTH + " characters).");
+ }
+ else
+ _SystemId = "";
+ }
+ }
+
+ ///
+ /// Used by the SMSC to authenticate the ESME requesting to bind.
+ /// Set to null for default value.
+ ///
+ public string Password
+ {
+ get
+ {
+ return _Password;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= PASS_LENGTH)
+ {
+ _Password = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("Password must be <= "+ PASS_LENGTH + " characters).");
+ }
+ }
+ else
+ {
+ _Password = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// The type of ESME system requesting to bind with the SMSC.
+ /// Set to null for default value.
+ ///
+ public string SystemType
+ {
+ get
+ {
+ return _SystemType;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= TYPE_LENGTH)
+ {
+ _SystemType = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("System type must be <= "+ TYPE_LENGTH + " characters).");
+ }
+ }
+ else
+ {
+ _SystemType = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// The ESME address range. If not known, set to null.
+ ///
+ public string AddressRange
+ {
+ get
+ {
+ return _AddressRange;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= RANGE_LENGTH)
+ {
+ _AddressRange = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("Address range must be <= "+ RANGE_LENGTH + " characters).");
+ }
+ }
+ else
+ {
+ _AddressRange = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// The version of the SMPP protocol supported by the ESME.
+ ///
+ public SmppVersionType InterfaceVersion
+ {
+ get
+ {
+ return _InterfaceVersion;
+ }
+ set
+ {
+ _InterfaceVersion = value;
+ }
+ }
+
+ ///
+ /// Indicates type of number of ESME address.
+ ///
+ public TonType AddressTon
+ {
+ get
+ {
+ return _AddressTon;
+ }
+ set
+ {
+ _AddressTon = value;
+ }
+ }
+
+ ///
+ /// Numbering plan indicator for ESME address.
+ ///
+ public NpiType AddressNpi
+ {
+ get
+ {
+ return _AddressNpi;
+ }
+ set
+ {
+ _AddressNpi = value;
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region enumerations
+
+ ///
+ /// Binding types for the SMPP bind request.
+ ///
+ public enum BindingType : uint
+ {
+ ///
+ /// BindAsReceiver
+ ///
+ BindAsReceiver = 1,
+ ///
+ /// BindAsTransmitter
+ ///
+ BindAsTransmitter = 2,
+ ///
+ /// BindAsTransceiver
+ ///
+ BindAsTransceiver = 9
+ }
+
+ #endregion enumerations
+
+ #region constructors
+
+ ///
+ /// Constructs a bind request. Sets system ID, password, system type, and address
+ /// range to empty strings. Sets interface version to v3.4, address TON to
+ /// international, address NPI to ISDN, and sets to bind as a transceiver.
+ ///
+ public SmppBind(): base()
+ {}
+
+ ///
+ /// Constructs a bind request. Sets system ID, password, system type, and address
+ /// range to empty strings. Sets interface version to v3.4, address TON to
+ /// international, address NPI to ISDN, and sets to bind as a transceiver.
+ ///
+ /// The incoming bytes from an ESME.
+ public SmppBind(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ BindType = BindingType.BindAsTransceiver;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SystemId)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(Password)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SystemType)));
+ pdu.Add((byte)InterfaceVersion);
+ pdu.Add((byte)AddressTon);
+ pdu.Add((byte)AddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(AddressRange)));
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the submit_sm Pdu. The Pdu has basically the same format as
+ /// the submit_sm Pdu, but in this case it is a response.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ BindType = (SmppBind.BindingType)CommandID;
+ SystemId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ Password = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SystemType = SmppStringUtil.GetCStringFromBody(ref remainder);
+ InterfaceVersion =(SmppVersionType)remainder[0];
+ AddressTon =(TonType)remainder[1];
+ AddressNpi =(NpiType)remainder[2];
+ AddressRange = SmppStringUtil.GetCStringFromBody(ref remainder, 3);
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppCancelSm.cs b/Packet/Request/SmppCancelSm.cs
new file mode 100644
index 0000000..28f6a62
--- /dev/null
+++ b/Packet/Request/SmppCancelSm.cs
@@ -0,0 +1,253 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Cancels one or more previous short messages. A particular message or all messages
+ /// for a particular source, destination and service_type can be cancelled.
+ ///
+ /// From the SMPP spec:
+ /// If the message_id is set to the ID of a previously submitted message, then
+ /// provided the source address supplied by the ESME matches that of the stored
+ /// message, that message will be cancelled.
+ /// If the message_id is null, all outstanding undelivered messages with matching
+ /// source and destination addresses given in the Pdu are cancelled. If provided,
+ /// service_type is included in this matching.
+ /// Where the original submit_sm, data_sm or submit_multi source address was
+ /// defaulted to null, then the source address in the cancel_sm command should also
+ /// be null.
+ ///
+ public class SmppCancelSm : MessageLcd6
+ {
+ #region private fields
+
+ private string _MessageId = string.Empty;
+ private string _ServiceType = string.Empty;
+ private TonType _DestinationAddressTon = Pdu.TonType.International;
+ private NpiType _DestinationAddressNpi = Pdu.NpiType.ISDN;
+ private string _DestinationAddress = string.Empty;
+
+ #endregion private fields
+
+ #region properties
+
+ ///
+ /// Message ID of the message to be cancelled. This must be the SMSC assigned Message
+ /// ID of the original message. Set to null if cancelling a group of messages.
+ ///
+ public string MessageId
+ {
+ get
+ {
+ return _MessageId;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= MSG_LENGTH)
+ {
+ _MessageId = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Message ID must be <= " + MSG_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _MessageId = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// Set to indicate SMS Application service, if cancellation of a group of application
+ /// service messages is desired. Otherwise set to null.
+ ///
+ public string ServiceType
+ {
+ get
+ {
+ return _ServiceType;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= SERVICE_TYPE_LENGTH)
+ {
+ _ServiceType = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Service Type must be <= " + SERVICE_TYPE_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _ServiceType = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// Type of number of destination SME address of the message(s)to be cancelled.
+ /// This must match that supplied in the original message submission request.
+ /// This can be set to null if the message ID is provided.
+ ///
+ public TonType DestinationAddressTon
+ {
+ get
+ {
+ return _DestinationAddressTon;
+ }
+ set
+ {
+ _DestinationAddressTon = value;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator of destination SME address of the message(s))to be
+ /// cancelled. This must match that supplied in the original message submission request.
+ /// This can be set to null when the message ID is provided.
+ ///
+ public NpiType DestinationAddressNpi
+ {
+ get
+ {
+ return _DestinationAddressNpi;
+ }
+ set
+ {
+ _DestinationAddressNpi = value;
+ }
+ }
+
+ ///
+ /// Destination address of message(s)to be cancelled. This must match that supplied in
+ /// the original message submission request. This can be set to null when the message ID
+ /// is provided.
+ ///
+ public string DestinationAddress
+ {
+ get
+ {
+ return _DestinationAddress;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= ADDRESS_LENGTH)
+ {
+ _DestinationAddress = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Destination Address must be <= " + ADDRESS_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _DestinationAddress = string.Empty;
+ }
+ }
+ }
+
+ #endregion properties
+
+ #region constructors
+
+ ///
+ /// Creates an SMPP Cancel SM Pdu. Sets message ID and service type to empty strings
+ ///(null), sets the destination TON to international and the destination NPI to ISDN,
+ /// and sets the command status to 0.
+ ///
+ public SmppCancelSm(): base()
+ {}
+
+ ///
+ /// Creates an SMPP Cancel SM Pdu. Sets message ID and service type to empty strings
+ ///(null), sets the destination TON to international and the destination NPI to ISDN,
+ /// and sets the command status to 0.
+ ///
+ /// The bytes received from an ESME.
+ public SmppCancelSm(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.cancel_sm;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ServiceType)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ pdu.Add((byte)DestinationAddressTon);
+ pdu.Add((byte)DestinationAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(DestinationAddress)));
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the cancel_sm Pdu.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ ServiceType = SmppStringUtil.GetCStringFromBody(ref remainder);
+ MessageId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon =(TonType)remainder[0];
+ SourceAddressNpi =(NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ DestinationAddressTon =(TonType)remainder[0];
+ DestinationAddressNpi =(NpiType)remainder[1];
+ DestinationAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppDataSm.cs b/Packet/Request/SmppDataSm.cs
new file mode 100644
index 0000000..579bfb3
--- /dev/null
+++ b/Packet/Request/SmppDataSm.cs
@@ -0,0 +1,516 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using RoaminSMPP.Utility;
+using System.Collections;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// This command is used to transfer data between the SMSC and the ESME(and can be
+ /// used by both). This is an alternative to the submit_sm and deliver_sm commands.
+ ///
+ public class SmppDataSm : MessageLcd3
+ {
+ private TonType _DestinationAddressTon = Pdu.TonType.International;
+ private NpiType _DestinationAddressNpi = Pdu.NpiType.ISDN;
+ private string _DestinationAddress = string.Empty;
+
+ #region mandatory parameters
+
+ ///
+ /// Type of number of destination SME address of the message(s)to be cancelled.
+ /// This must match that supplied in the original message submission request.
+ /// This can be set to null if the message ID is provided.
+ ///
+ public TonType DestinationAddressTon
+ {
+ get
+ {
+ return _DestinationAddressTon;
+ }
+ set
+ {
+ _DestinationAddressTon = value;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator of destination SME address of the message(s))to be
+ /// cancelled. This must match that supplied in the original message submission request.
+ /// This can be set to null when the message ID is provided.
+ ///
+ public NpiType DestinationAddressNpi
+ {
+ get
+ {
+ return _DestinationAddressNpi;
+ }
+ set
+ {
+ _DestinationAddressNpi = value;
+ }
+ }
+
+ ///
+ /// Destination address of message(s)to be cancelled. This must match that supplied in
+ /// the original message submission request. This can be set to null when the message ID
+ /// is provided.
+ ///
+ public string DestinationAddress
+ {
+ get
+ {
+ return _DestinationAddress;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= ADDRESS_LENGTH)
+ {
+ _DestinationAddress = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Destination Address must be <= " + ADDRESS_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _DestinationAddress = string.Empty;
+ }
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region optional params
+
+ ///
+ /// The correct network associated with the originating device.
+ ///
+ public NetworkType SourceNetworkType
+ {
+ get
+ {
+ return(NetworkType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.source_network_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.source_network_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// The correct bearer type for the delivering the user data to the destination.
+ ///
+ public BearerType SourceBearerType
+ {
+ get
+ {
+ return(BearerType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.source_bearer_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.source_bearer_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// The telematics identifier associated with the source. The value part
+ /// has yet to be defined in the specs as of 07/20/2004.
+ ///
+ public UInt16 SourceTelematicsId
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.source_telematics_id);
+ }
+
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetOptionalParamBytes(
+ (UInt16)Pdu.OptionalParamCodes.source_telematics_id,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering(value)));
+ }
+ else
+ {
+ throw new ArgumentException("source_telematics_id value too large.");
+ }
+ }
+ }
+
+ ///
+ /// The correct network for the destination device.
+ ///
+ public NetworkType DestNetworkType
+ {
+ get
+ {
+ return(NetworkType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.dest_network_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.dest_network_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// The correct bearer type for the delivering the user data to the destination.
+ ///
+ public BearerType DestBearerType
+ {
+ get
+ {
+ return(BearerType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.dest_bearer_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.dest_bearer_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// The telematics identifier associated with the destination. The value part
+ /// has yet to be defined in the specs as of 07/20/2004.
+ ///
+ public UInt16 DestTelematicsId
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)Pdu.OptionalParamCodes.dest_telematics_id);
+ }
+
+ set
+ {
+ if(value < UInt16.MaxValue)
+ {
+ SetOptionalParamBytes(
+ (UInt16)Pdu.OptionalParamCodes.dest_telematics_id,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering(value)));
+ }
+ else
+ {
+ throw new ArgumentException("dest_telematics_id value too large.");
+ }
+ }
+ }
+
+ ///
+ /// If true, this indicates that there are more messages to follow for the
+ /// destination SME.
+ ///
+ public bool MoreMessagesToSend
+ {
+ get
+ {
+ byte sendMore = GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.more_messages_to_send)[0];
+
+ return (sendMore == 0) ? false : true;
+ }
+
+ set
+ {
+ byte sendMore;
+ if(value == false)
+ {
+ sendMore =(byte)0x00;
+ }
+ else
+ {
+ sendMore =(byte)0x01;
+ }
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.more_messages_to_send, new Byte[] {sendMore});
+ }
+ }
+
+ ///
+ /// Time to live as a relative time in seconds from submission.
+ ///
+ public UInt32 QosTimeToLive
+ {
+ get
+ {
+ return GetHostOrderUInt32FromTlv((ushort)Pdu.OptionalParamCodes.qos_time_to_live);
+ }
+
+ set
+ {
+ if(value < UInt32.MaxValue)
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.qos_time_to_live,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering(value)));
+ }
+ else
+ {
+ throw new ArgumentException("qos_time_to_live value too large.");
+ }
+ }
+ }
+
+ ///
+ /// Sets the Delivery Pending Flag on delivery failure.
+ ///
+ public DpfResultType SetDpf
+ {
+ get
+ {
+ return(DpfResultType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.set_dpf)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.set_dpf, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// SMSC message ID of message being receipted. Should be present for SMSC
+ /// Delivery Receipts and Intermediate Notifications.
+ ///
+ public string ReceiptedMessageId
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)Pdu.OptionalParamCodes.receipted_message_id);
+ }
+
+ set
+ {
+ PduUtil.SetReceiptedMessageId(this, value);
+ }
+ }
+
+ ///
+ /// Message State. Should be present for SMSC Delivery Receipts and Intermediate
+ /// Notifications.
+ ///
+ public MessageStateType MessageState
+ {
+ get
+ {
+ return (MessageStateType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.message_state)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.message_state, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Network error code. May be present for SMSC Delivery Receipts and
+ /// Intermediate Notifications. See section 5.3.2.31 for more information.
+ ///
+ public string NetworkErrorCode
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)Pdu.OptionalParamCodes.network_error_code);
+ }
+
+ set
+ {
+ PduUtil.SetNetworkErrorCode(this, value);
+ }
+ }
+
+ ///
+ /// A user response code. The actual response codes are implementation specific.
+ ///
+ public byte UserResponseCode
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.user_response_code)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.user_response_code,new Byte[] {value});
+ }
+ }
+
+ ///
+ /// Indicates the number of messages stored in a mail box.
+ ///
+ public byte NumberOfMessages
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.number_of_messages)[0];
+ }
+
+ set
+ {
+ if(value <= 99)
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.number_of_messages, new Byte[] {value});
+ }
+ else
+ {
+ throw new ArgumentException("number_of_messages must be between 0 and 99.");
+ }
+ }
+ }
+
+ ///
+ /// Indicates and controls the MS users reply method to an SMS delivery message
+ /// received from the network.
+ ///
+ public ItsReplyTypeType ItsReplyType
+ {
+ get
+ {
+ return (ItsReplyTypeType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.its_reply_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.its_reply_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Session control information for Interactive Teleservice.
+ ///
+ /// See section 5.3.2.43 of the SMPP spec for how to set this.
+ ///
+ public string ItsSessionInfo
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)Pdu.OptionalParamCodes.its_session_info);
+ }
+
+ set
+ {
+ PduUtil.SetItsSessionInfo(this, value);
+ }
+ }
+
+ #endregion optional params
+
+ #region constructors
+
+ ///
+ /// Creates a data_sm Pdu. Sets the destination TON to international, the destination
+ /// NPI to ISDN, and the command status to 0.
+ ///
+ public SmppDataSm(): base()
+ {}
+
+ ///
+ /// Creates a data_sm Pdu. Sets the destination TON to international, the destination
+ /// NPI to ISDN, and the command status to 0.
+ ///
+ /// The bytes received from an ESME.
+ public SmppDataSm(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.data_sm;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ServiceType)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ pdu.Add((byte)DestinationAddressTon);
+ pdu.Add((byte)DestinationAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(DestinationAddress)));
+ pdu.Add(EsmClass);
+ pdu.Add((byte)RegisteredDelivery);
+ pdu.Add((byte)DataCoding);
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the cancel_sm Pdu.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ #if DEBUG
+ Console.WriteLine("In DecodeSmscResponse of EsmppDataSm");
+ #endif
+ byte[] remainder = BytesAfterHeader;
+ ServiceType = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon = (TonType)remainder[0];
+ SourceAddressNpi = (NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ DestinationAddressTon = (TonType)remainder[0];
+ DestinationAddressNpi = (NpiType)remainder[1];
+ DestinationAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ EsmClass = remainder[0];
+ RegisteredDelivery = (RegisteredDeliveryType)remainder[1];
+ DataCoding = (DataCodingType)remainder[2];
+
+ TranslateTlvDataIntoTable(remainder, 3);
+ }
+ }
+}
diff --git a/Packet/Request/SmppDeliverSm.cs b/Packet/Request/SmppDeliverSm.cs
new file mode 100644
index 0000000..83c1f79
--- /dev/null
+++ b/Packet/Request/SmppDeliverSm.cs
@@ -0,0 +1,678 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using RoaminSMPP.Utility;
+using RoaminSMPP.Packet;
+using System.Collections;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// This class defines a deliver_sm that is SMSC generated. This does
+ /// NOT handle anything other than strings in the short message.
+ ///
+ public class SmppDeliverSm : Pdu
+ {
+ #region private fields
+
+ private string _ServiceType = string.Empty;
+ private TonType _SourceAddressTon = TonType.International;
+ private NpiType _SourceAddressNpi = NpiType.ISDN;
+ private string _SourceAddress = string.Empty;
+ private TonType _DestinationAddressTon = TonType.International;
+ private NpiType _DestinationAddressNpi = NpiType.ISDN;
+ private string _DestinationAddress = string.Empty;
+ private byte _EsmClass = 0;
+ private SmppVersionType _ProtocolId = SmppVersionType.Version3_4;
+ private PriorityType _PriorityFlag = PriorityType.Lowest;
+ private RegisteredDeliveryType _RegisteredDelivery = RegisteredDeliveryType.None;
+ private DataCodingType _DataCoding = DataCodingType.SMSCDefault;
+ private byte _SmLength = 0;
+ private string _ShortMessage = null;
+
+ #endregion private fields
+
+ ///
+ /// Used to indicate the SMS Application service associated with the message.
+ /// If this is unknown, null is returned.
+ ///
+ public string ServiceType
+ {
+ get
+ {
+ return _ServiceType;
+ }
+
+ set
+ {
+ _ServiceType = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// Type of Number for source address.
+ ///
+ public TonType SourceAddressTon
+ {
+ get
+ {
+ return _SourceAddressTon;
+ }
+
+ set
+ {
+ _SourceAddressTon = value;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator for source address.
+ ///
+ public NpiType SourceAddressNpi
+ {
+ get
+ {
+ return _SourceAddressNpi;
+ }
+
+ set
+ {
+ _SourceAddressNpi = value;
+ }
+ }
+
+ ///
+ /// Address of origination entity.
+ ///
+ public string SourceAddress
+ {
+ get
+ {
+ return _SourceAddress;
+ }
+
+ set
+ {
+ _SourceAddress = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// Type of number of destination entity.
+ ///
+ public TonType DestinationAddressTon
+ {
+ get
+ {
+ return _DestinationAddressTon;
+ }
+
+ set
+ {
+ _DestinationAddressTon = value;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator of destination entity.
+ ///
+ public NpiType DestinationAddressNpi
+ {
+ get
+ {
+ return _DestinationAddressNpi;
+ }
+
+ set
+ {
+ _DestinationAddressNpi = value;
+ }
+ }
+
+ ///
+ /// Destination address of entity.
+ ///
+ public string DestinationAddress
+ {
+ get
+ {
+ return _DestinationAddress;
+ }
+
+ set
+ {
+ _DestinationAddress = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// Indicates Message Mode and Message Type. See the SMSC
+ /// version 3.4 specification for details on this.
+ ///
+ public byte EsmClass
+ {
+ get
+ {
+ return _EsmClass;
+ }
+
+ set
+ {
+ _EsmClass = value;
+ }
+ }
+
+ ///
+ /// Protocol Identifier; network specific.
+ ///
+ public SmppVersionType ProtocolId
+ {
+ get
+ {
+ return _ProtocolId;
+ }
+
+ set
+ {
+ _ProtocolId = value;
+ }
+ }
+
+ ///
+ /// Designates the priority level of the message.
+ ///
+ public PriorityType PriorityFlag
+ {
+ get
+ {
+ return _PriorityFlag;
+ }
+
+ set
+ {
+ _PriorityFlag = value;
+ }
+ }
+
+ ///
+ /// Use this to indicate if you want delivery confirmation.
+ ///
+ public RegisteredDeliveryType RegisteredDelivery
+ {
+ get
+ {
+ return _RegisteredDelivery;
+ }
+
+ set
+ {
+ _RegisteredDelivery = value;
+ }
+ }
+
+ ///
+ /// Indicates the encoding scheme of the short message.
+ ///
+ public DataCodingType DataCoding
+ {
+ get
+ {
+ return _DataCoding;
+ }
+
+ set
+ {
+ _DataCoding = value;
+ }
+ }
+
+ ///
+ /// Short message length in octets(bytes for x86).
+ ///
+ public byte SmLength
+ {
+ get
+ {
+ return _SmLength;
+ }
+ }
+
+ ///
+ /// The short message for this Pdu. This holds up to 160 characters.
+ /// If the message is longer, the MessagePayload property will be used.
+ /// If this is the case, the short message length will be zero. Note
+ /// that both the ShortMessage and MessagePayload cannot be used
+ /// simultaneously.
+ ///
+ public string ShortMessage
+ {
+ get
+ {
+ return _ShortMessage;
+ }
+
+ set
+ {
+ _ShortMessage = value;
+ }
+ }
+
+ #region optional parameters
+
+ ///
+ /// The message reference number assigned by the ESME.
+ ///
+ public UInt16 UserMessageReference
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)OptionalParamCodes.user_message_reference);
+ }
+
+ set
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.user_message_reference, value);
+ }
+ }
+
+ ///
+ /// The port number associated with the source address of the message. This
+ /// parameter will be present for WAP applications.
+ ///
+ public UInt16 SourcePort
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)OptionalParamCodes.source_port);
+ }
+
+ set
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.source_port, value);
+ }
+ }
+
+ ///
+ /// The port number associated with the destination address of the message. This
+ /// parameter will be present for WAP applications.
+ ///
+ public UInt16 DestinationPort
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)OptionalParamCodes.destination_port);
+ }
+
+ set
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.destination_port, value);
+ }
+ }
+
+ ///
+ /// The reference number for a particular concatenated short message.
+ ///
+ public UInt16 SarMsgRefNumber
+ {
+ get
+ {
+ return GetHostOrderUInt16FromTlv((ushort)OptionalParamCodes.sar_msg_ref_num);
+ }
+
+ set
+ {
+ SetHostOrderValueIntoTlv((UInt16)Pdu.OptionalParamCodes.sar_msg_ref_num, value);
+ }
+ }
+
+ ///
+ /// Total number of short message fragments within the concatenated short message.
+ ///
+ public byte SarTotalSegments
+ {
+ get
+ {
+ return GetOptionalParamBytes((ushort)OptionalParamCodes.sar_total_segments)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.sar_total_segments, new Byte[] {value});
+ }
+ }
+
+ ///
+ /// The sequence number of a particular short message fragment within the
+ /// concatenated short message.
+ ///
+ public byte SarSegmentSeqnum
+ {
+ get
+ {
+ return GetOptionalParamBytes((ushort)OptionalParamCodes.sar_segment_seqnum)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.sar_segment_seqnum, new Byte[] {value});
+ }
+ }
+
+ ///
+ /// A user response code. The actual response codes are SMS application specific.
+ ///
+ public byte UserResponseCode
+ {
+ get
+ {
+ return GetOptionalParamBytes((ushort)OptionalParamCodes.user_response_code)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.user_response_code, new Byte[] {value});
+ }
+ }
+
+ ///
+ /// Indicates a level of privacy associated with the message.
+ ///
+ public PrivacyType PrivacyIndicator
+ {
+ get
+ {
+ return(PrivacyType)
+ GetOptionalParamBytes((ushort)OptionalParamCodes.privacy_indicator)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.privacy_indicator, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Defines the type of payload(e.g. WDP, WCMP, etc.)
+ ///
+ public PayloadTypeType PayloadType
+ {
+ get
+ {
+ return(PayloadTypeType)
+ GetOptionalParamBytes((ushort)OptionalParamCodes.payload_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.payload_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// This can hold up to 64K octets of short message data.
+ /// The actual limit is network/SMSC dependent.
+ ///
+ public string MessagePayload
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.message_payload);
+ }
+
+ set
+ {
+ PduUtil.SetMessagePayload(this, value);
+ }
+ }
+
+ ///
+ /// Associates a callback number with a message. See section 5.3.2.36 of the
+ /// SMPP spec for details. This must be between 4 and 19 characters in length.
+ ///
+ public string CallbackNum
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.callback_num);
+ }
+
+ set
+ {
+ PduUtil.SetCallbackNum(this, value);
+ }
+ }
+
+ ///
+ /// Specifies a source subaddress associated with the originating entity.
+ /// See section 5.3.2.15 of the SMPP spec for details on setting this parameter.
+ ///
+ public string SourceSubaddress
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.source_subaddress);
+ }
+
+ set
+ {
+ PduUtil.SetSourceSubaddress(this, value);
+ }
+ }
+
+ ///
+ /// Specifies a source subaddress associated with the receiving entity.
+ /// See section 5.3.2.15 of the SMPP spec for details on setting this parameter.
+ ///
+ public string DestinationSubaddress
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.dest_subaddress);
+ }
+
+ set
+ {
+ PduUtil.SetDestSubaddress(this, value);
+ }
+ }
+
+ ///
+ /// The language of the short message.
+ ///
+ public LanguageType LanguageIndicator
+ {
+ get
+ {
+ return(LanguageType)
+ GetOptionalParamBytes((ushort)OptionalParamCodes.language_indicator)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.language_indicator, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// From the SMPP spec:
+ /// The its_session_info parameter is a required parameter for the CDMA Interactive
+ /// Teleservice as defined by the Korean PCS carriers [KORITS]. It contains control
+ /// information for the interactive session between an MS and an ESME.
+ ///
+ /// See section 5.3.2.43 of the SMPP spec for how to set this.
+ ///
+ public string ItsSessionInfo
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.its_session_info);
+ }
+
+ set
+ {
+ PduUtil.SetItsSessionInfo(this, value);
+ }
+ }
+
+ ///
+ /// Network Error Code. May be present for Intermediate Notifications
+ /// and SMSC Delivery Receipts. See SMPP spec 5.3.2.31 for details.
+ ///
+ public string NetworkErrorCode
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.network_error_code);
+ }
+
+ set
+ {
+ PduUtil.SetNetworkErrorCode(this, value);
+ }
+ }
+
+ ///
+ /// Indicates to the ESME the final message state for an SMSC Delivery Receipt.
+ ///
+ public MessageStateType MessageState
+ {
+ get
+ {
+ return(MessageStateType)
+ GetOptionalParamBytes((ushort)OptionalParamCodes.message_state)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.message_state, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// Indicates the ID of the message being receipted in an SMSC Delivery Receipt.
+ ///
+ public string ReceiptedMessageId
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.receipted_message_id);
+ }
+
+ set
+ {
+ PduUtil.SetReceiptedMessageId(this, value);
+ }
+ }
+
+ #endregion optional parameters
+
+ #region constructors
+
+ ///
+ /// Creates a deliver_sm Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppDeliverSm(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a deliver_sm Pdu.
+ ///
+ public SmppDeliverSm(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// This decodes the deliver_sm Pdu. The Pdu has basically the same format as
+ /// the submit_sm Pdu, but in this case it is a response.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ ServiceType = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon = (TonType)remainder[0];
+ SourceAddressNpi = (NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ DestinationAddressTon = (TonType)remainder[0];
+ DestinationAddressNpi = (NpiType)remainder[1];
+ DestinationAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ EsmClass = remainder[0];
+ ProtocolId = (SmppVersionType)remainder[1];
+ PriorityFlag = (PriorityType)remainder[2];
+ //schedule_delivery_time and validity_period are null, so don't bother
+ //reading them
+ RegisteredDelivery = (RegisteredDeliveryType)remainder[5];
+ //replace_if_present is always null, so don't bother reading it
+ DataCoding = (DataCodingType)remainder[7];
+ //sm_default_msg_id is always null, so don't bother reading it
+ _SmLength = remainder[9];
+ ShortMessage = SmppStringUtil.GetStringFromBody(ref remainder, 10, 10 + _SmLength);
+ TranslateTlvDataIntoTable(remainder);
+ }
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.deliver_sm;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ServiceType)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ pdu.Add((byte)DestinationAddressTon);
+ pdu.Add((byte)DestinationAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(DestinationAddress)));
+ pdu.Add(EsmClass);
+ pdu.Add((byte)ProtocolId);
+ pdu.Add((byte)PriorityFlag);
+ //schedule_delivery_time and validity_period are null, so set them to zero
+ pdu.Add((byte)0);
+ pdu.Add((byte)0);
+ pdu.Add((byte)RegisteredDelivery);
+ //replace_if_present is always null, so set it to zero
+ pdu.Add((byte)0);
+ pdu.Add((byte)DataCoding);
+ //sm_default_msg_id is always null, so set it to zero
+ pdu.Add((byte)0);
+ _SmLength = PduUtil.InsertShortMessage(pdu, ShortMessage);
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Request/SmppEnquireLink.cs b/Packet/Request/SmppEnquireLink.cs
new file mode 100644
index 0000000..f3f30ff
--- /dev/null
+++ b/Packet/Request/SmppEnquireLink.cs
@@ -0,0 +1,76 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using RoaminSMPP.Packet;
+using System.Collections;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Defines the SMPP enquire_link Pdu. This is basically just the header.
+ ///
+ public class SmppEnquireLink : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates an enquire_link Pdu. Sets command status and command ID.
+ ///
+ public SmppEnquireLink(): base()
+ {}
+
+ ///
+ /// Creates an enquire_link Pdu. Sets command status and command ID.
+ ///
+ /// The bytes received from an ESME.
+ public SmppEnquireLink(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.enquire_link;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the query_sm Pdu.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppGenericNack.cs b/Packet/Request/SmppGenericNack.cs
new file mode 100644
index 0000000..8f270d5
--- /dev/null
+++ b/Packet/Request/SmppGenericNack.cs
@@ -0,0 +1,76 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using RoaminSMPP.Utility;
+using System.Collections;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Class to represent a generic negative acknowledgment.
+ ///
+ public class SmppGenericNack : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates a new generic NACK. Sets the error code to 0.
+ ///
+ public SmppGenericNack(): base()
+ {}
+
+ ///
+ /// Creates a new generic NACK.
+ ///
+ /// The incoming bytes from the ESME.
+ public SmppGenericNack(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.generic_nack;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the query_sm Pdu.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppOutbind.cs b/Packet/Request/SmppOutbind.cs
new file mode 100644
index 0000000..f9f8ab1
--- /dev/null
+++ b/Packet/Request/SmppOutbind.cs
@@ -0,0 +1,116 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Text;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Defines an outbind response(really a request TO us)from the SMSC.
+ ///
+ public class SmppOutbind : Pdu
+ {
+ private string _SystemId = string.Empty;
+ private string _Password = string.Empty;
+
+ ///
+ /// The ID of the SMSC.
+ ///
+ public string SystemId
+ {
+ get
+ {
+ return _SystemId;
+ }
+
+ set
+ {
+ _SystemId = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// Password that the ESME can use for authentication.
+ ///
+ public string Password
+ {
+ get
+ {
+ return _Password;
+ }
+
+ set
+ {
+ _Password = (value == null) ? string.Empty : value;
+ }
+ }
+
+ #region constructors
+
+ ///
+ /// Creates an outbind response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppOutbind(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates an outbind response Pdu.
+ ///
+ public SmppOutbind(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the outbind response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ SystemId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ Password = SmppStringUtil.GetCStringFromBody(ref remainder);
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder);
+ }
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.outbind;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SystemId)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(Password)));
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Request/SmppQuerySm.cs b/Packet/Request/SmppQuerySm.cs
new file mode 100644
index 0000000..06c20ad
--- /dev/null
+++ b/Packet/Request/SmppQuerySm.cs
@@ -0,0 +1,119 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using RoaminSMPP.Packet;
+using System.Collections;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// This class defines a query_sm ESME originated Pdu.
+ ///
+ public class SmppQuerySm : MessageLcd6
+ {
+ private string _MessageId = string.Empty;
+
+ ///
+ /// The ID of the message.
+ ///
+ public string MessageId
+ {
+ get
+ {
+ return _MessageId;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= MSG_LENGTH)
+ {
+ _MessageId = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Message ID must be <= " + MSG_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _MessageId = string.Empty;
+ }
+ }
+ }
+
+ #region constructors
+
+ ///
+ /// Creates a query_sm Pdu. Sets source address TON to international, source address
+ /// NPI to ISDN, source address to "", and message ID to an empty string.
+ ///
+ public SmppQuerySm(): base()
+ {}
+
+ ///
+ /// Creates a new SmppQuerySm for incoming PDUs.
+ ///
+ /// The incoming bytes to decode.
+ public SmppQuerySm(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.query_sm;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the query_sm Pdu.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ MessageId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon =(TonType)remainder[0];
+ SourceAddressNpi =(NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppReplaceSm.cs b/Packet/Request/SmppReplaceSm.cs
new file mode 100644
index 0000000..82030ad
--- /dev/null
+++ b/Packet/Request/SmppReplaceSm.cs
@@ -0,0 +1,253 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Pdu to replace a previously submitted short message that hasn't been delivered.
+ /// The match is based on the message_id and source addresses of the original message.
+ ///
+ public class SmppReplaceSm : MessageLcd4
+ {
+ #region private fields
+
+ private string _MessageId = string.Empty;
+ private string _ScheduleDeliveryTime = string.Empty;
+ private string _ValidityPeriod = string.Empty;
+ private byte _SmDefaultMessageId = 0;
+ private object _ShortMessage = null;
+ private byte _SmLength = 0;
+
+ #endregion private fields
+
+ #region mandatory parameters
+
+ ///
+ /// SMSC message ID of the message to be replaced. This must be the message ID of the
+ /// original message.
+ ///
+ public string MessageId
+ {
+ get
+ {
+ return _MessageId;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.Length <= MSG_LENGTH)
+ {
+ _MessageId = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Message ID must be <= " + MSG_LENGTH + " characters.");
+ }
+ }
+ else
+ {
+ _MessageId = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// New scheduled delivery time for the short message. Set to null, if updating of the
+ /// original scheduled delivery time is not desired.
+ ///
+ public string ScheduleDeliveryTime
+ {
+ get
+ {
+ return _ScheduleDeliveryTime;
+ }
+ set
+ {
+ if(value != null && value != string.Empty)
+ {
+ if(value.Length == DATE_TIME_LENGTH)
+ {
+ _ScheduleDeliveryTime = value;
+ }
+ else
+ {
+ throw new ArgumentException("Scheduled delivery time not in correct format.");
+ }
+ }
+ else
+ {
+ _ScheduleDeliveryTime = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// New expiration time for the short message. Set to null, if updating of the original
+ /// expiration time is not required.
+ ///
+ public string ValidityPeriod
+ {
+ get
+ {
+ return _ValidityPeriod;
+ }
+ set
+ {
+ if(value != null && value != string.Empty)
+ {
+ if(value.Length == DATE_TIME_LENGTH)
+ {
+ _ValidityPeriod = value;
+ }
+ else
+ {
+ throw new ArgumentException("Validity period not in correct format.");
+ }
+ }
+ else
+ {
+ _ValidityPeriod = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// New pre-defined(canned)message identifier. Set to 0 if not using.
+ ///
+ public byte SmDefaultMessageId
+ {
+ get
+ {
+ return _SmDefaultMessageId;
+ }
+ set
+ {
+ _SmDefaultMessageId = value;
+ }
+ }
+
+ ///
+ /// New short message to replace existing message.
+ ///
+ public object ShortMessage
+ {
+ get
+ {
+ return _ShortMessage;
+ }
+ set
+ {
+ _ShortMessage = value;
+ }
+ }
+
+ ///
+ /// The length of the short message.
+ ///
+ public byte SmLength
+ {
+ get
+ {
+ return _SmLength;
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region constructors
+
+ ///
+ /// Creates a replace_sm Pdu. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// message ID, scheduled delivery time, validity period, and short message to
+ /// empty strings(NULL SMSC value). Sets the default message ID to 0.
+ ///
+ public SmppReplaceSm(): base()
+ {}
+
+ ///
+ /// Creates a replace_sm Pdu. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// message ID, scheduled delivery time, validity period, and short message to
+ /// empty strings(NULL SMSC value). Sets the default message ID to 0.
+ ///
+ /// The incoming bytes from an ESME.
+ public SmppReplaceSm(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.replace_sm;
+ }
+
+ ///
+ /// Generates the hex encoded bytes for a replace_sm Pdu.
+ ///
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ScheduleDeliveryTime)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ValidityPeriod)));
+ pdu.Add((byte)RegisteredDelivery);
+ pdu.Add(_SmDefaultMessageId);
+
+ _SmLength = PduUtil.InsertShortMessage(pdu, ShortMessage);
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the submit_sm Pdu. The Pdu has basically the same format as
+ /// the submit_sm Pdu, but in this case it is a response.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ MessageId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon =(TonType)remainder[0];
+ SourceAddressNpi =(NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ ScheduleDeliveryTime = SmppStringUtil.GetCStringFromBody(ref remainder);
+ ValidityPeriod = SmppStringUtil.GetCStringFromBody(ref remainder);
+ RegisteredDelivery =(RegisteredDeliveryType)remainder[0];
+ SmDefaultMessageId = remainder[1];
+ _SmLength = remainder[2];
+ ShortMessage = SmppStringUtil.GetStringFromBody(ref remainder, 3, 3 + _SmLength);
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppSubmitMulti.cs b/Packet/Request/SmppSubmitMulti.cs
new file mode 100644
index 0000000..d5cd7c8
--- /dev/null
+++ b/Packet/Request/SmppSubmitMulti.cs
@@ -0,0 +1,196 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Defines a submit_multi Pdu.
+ ///
+ public class SmppSubmitMulti : MessageLcd2
+ {
+ //note that all of the optional parameters are in the base class.
+ private byte _NumberOfDests = 0;
+ private DestinationAddress[] _DestinationAddresses = new DestinationAddress[0];
+ private const int MAX_DESTS = 254;
+
+ #region properties
+
+ ///
+ /// The number of destinations to send to.
+ ///
+ public byte NumberOfDestinations
+ {
+ get
+ {
+ return _NumberOfDests;
+ }
+ }
+
+ ///
+ /// The destination addresses that will be sent to. This will set the number of
+ /// destination addresses as well. Passing null in will set them to zero. Calling the
+ /// accessor will get you a cloned array. You must use the mutator to modify the values.
+ ///
+ public DestinationAddress[] DestinationAddresses
+ {
+ get
+ {
+ return(DestinationAddress[])_DestinationAddresses.Clone();
+ }
+ set
+ {
+ _DestinationAddresses = (value == null) ? new DestinationAddress[0] : value;
+ _NumberOfDests = (byte)_DestinationAddresses.Length;
+ }
+ }
+
+ #endregion properties
+
+ #region constructors
+
+ ///
+ /// Creates a submit_multi Pdu. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// ESM class to 0, data coding to SMSC default, protocol ID to v3.4, priority to level 1,
+ /// validity period to default, replace if present to false, default message ID to 0,
+ /// the short message to an empty string, the number of destinations to 0 and the
+ /// destination addresses to null. Use the DestAddrFactory class to create
+ /// destination addresses.
+ ///
+ public SmppSubmitMulti(): base()
+ {}
+
+ ///
+ /// Creates a submit_multi Pdu. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// ESM class to 0, data coding to SMSC default, protocol ID to v3.4, priority to level 1,
+ /// validity period to default, replace if present to false, default message ID to 0,
+ /// the short message to an empty string, the number of destinations to 0 and the
+ /// destination addresses to null. Use the DestAddrFactory class to create
+ /// destination addresses.
+ ///
+ /// The incoming bytes from an ESME
+ public SmppSubmitMulti(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.submit_multi;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ServiceType)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ //number of destinations.
+ pdu.Add(NumberOfDestinations);
+
+ //and their addresses
+ foreach(DestinationAddress address in _DestinationAddresses)
+ {
+ if(!address.IsDistributionList)
+ {
+ //pack up the byte array for this address
+ ArrayList sme = new ArrayList();
+ pdu.Add((byte)0x01);
+ pdu.Add((byte)address.DestinationAddressTon);
+ pdu.Add((byte)address.DestinationAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(
+ Encoding.ASCII.GetBytes(address.DestAddress)));
+ }
+ else
+ {
+ ArrayList dln = new ArrayList();
+ pdu.Add((byte)0x02);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(
+ Encoding.ASCII.GetBytes(address.DistributionList)));
+ }
+ }
+
+ pdu.AddRange(base.GetBytesAfterDestination());
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// Decodes the submit_multi response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+
+ ServiceType = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon =(TonType)remainder[0];
+ SourceAddressNpi =(NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+
+ //the SMSC might not send back the number of destinations,
+ //so check if it did
+ if(remainder.Length > 0)
+ {
+ _NumberOfDests = remainder[0];
+ DestinationAddresses = new DestinationAddress[NumberOfDestinations];
+
+ //trim off the number of destinations
+ long length = remainder.Length - 1;
+ byte[] newRemainder = new byte[length];
+ Array.Copy(remainder, 1, newRemainder, 0, length);
+ remainder = newRemainder;
+ newRemainder = null;
+
+ for(int i = 0; i < _DestinationAddresses.Length; i++)
+ {
+ _DestinationAddresses[i] = new DestinationAddress(ref remainder);
+ }
+ }
+
+ EsmClass = remainder[0];
+ ProtocolId =(SmppVersionType)remainder[1];
+ PriorityFlag =(PriorityType)remainder[2];
+ ScheduleDeliveryTime = SmppStringUtil.GetCStringFromBody(ref remainder, 3);
+ ValidityPeriod = SmppStringUtil.GetCStringFromBody(ref remainder);
+ RegisteredDelivery =(RegisteredDeliveryType)remainder[0];
+ ReplaceIfPresentFlag =(remainder[1] == 0)? false : true;
+ DataCoding =(DataCodingType)remainder[2];
+ SmDefaultMessageId = remainder[3];
+ _SmLength = remainder[4];
+ ShortMessage = SmppStringUtil.GetStringFromBody(ref remainder, 5, 5 + _SmLength);
+
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppSubmitSm.cs b/Packet/Request/SmppSubmitSm.cs
new file mode 100644
index 0000000..f2cc333
--- /dev/null
+++ b/Packet/Request/SmppSubmitSm.cs
@@ -0,0 +1,346 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Defines an SMPP submit request.
+ ///
+ public class SmppSubmitSm : MessageLcd2
+ {
+ #region private fields
+
+ private TonType _DestinationAddressTon;
+ private NpiType _DestinationAddressNpi;
+ private string _DestinationAddress;
+
+ #endregion private fields
+
+ #region mandatory parameters
+
+ ///
+ /// Type of Number for destination.
+ ///
+ public TonType DestinationAddressTon
+ {
+ get
+ {
+ return _DestinationAddressTon;
+ }
+ set
+ {
+ _DestinationAddressTon = value;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator for destination.
+ ///
+ public NpiType DestinationAddressNpi
+ {
+ get
+ {
+ return _DestinationAddressNpi;
+ }
+ set
+ {
+ _DestinationAddressNpi = value;
+ }
+ }
+
+ ///
+ /// Destination address of this short message. Null values will be converted to an
+ /// empty string.
+ ///
+ public string DestinationAddress
+ {
+ get
+ {
+ return _DestinationAddress;
+ }
+ set
+ {
+ if(value != null)
+ {
+ if(value.ToString().Length <= ADDRESS_LENGTH)
+ {
+ _DestinationAddress = value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ "Destination Address too long(must be <= "+ ADDRESS_LENGTH + " 20 characters).");
+ }
+ }
+ else
+ {
+ _DestinationAddress = string.Empty;
+ }
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region optional params
+
+ ///
+ /// Indicates to the SMSC that there are further messages for the same destination.
+ ///
+ public bool MoreMessagesToSend
+ {
+ get
+ {
+ byte[] bytes = GetOptionalParamBytes((ushort)OptionalParamCodes.more_messages_to_send);
+
+ return(bytes[0] == 0)? false : true;
+ }
+
+ set
+ {
+ byte sendMore;
+ if(value == false)
+ {
+ sendMore =(byte)0x00;
+ }
+ else
+ {
+ sendMore =(byte)0x01;
+ }
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.more_messages_to_send, new Byte[] {sendMore});
+ }
+ }
+
+ ///
+ /// A response code set by the user in a User Acknowledgement/Reply message. The
+ /// response codes are application specific. From the SMPP spec:
+ ///
+ /// 0 to 255(IS-95 CDMA)
+ /// 0 to 15(CMT-136 TDMA)
+ ///
+ public byte UserResponseCode
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.user_response_code)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.user_response_code, new Byte[] {value});
+ }
+ }
+
+ ///
+ /// Used to indicate the number of messages stored in a mailbox.
+ ///
+ public byte NumberOfMessages
+ {
+ get
+ {
+ return GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.number_of_messages)[0];
+ }
+
+ set
+ {
+ const int MAX_NUM_MSGS = 99;
+
+ if(value <= MAX_NUM_MSGS)
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.number_of_messages, new Byte[] {value});
+ }
+ else
+ {
+ throw new ArgumentException(
+ "number_of_messages must be between 0 and " + MAX_NUM_MSGS + ".");
+ }
+ }
+ }
+
+ ///
+ /// From the SMPP spec:
+ /// The its_reply_type parameter is a required parameter for the CDMA Interactive
+ /// Teleservice as defined by the Korean PCS carriers [KORITS]. It indicates and
+ /// controls the MS users reply method to an SMS delivery message received from
+ /// the ESME.
+ ///
+ public ItsReplyTypeType ItsReplyType
+ {
+ get
+ {
+ return (ItsReplyTypeType)GetOptionalParamBytes(
+ (ushort)OptionalParamCodes.its_reply_type)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.its_reply_type, new Byte[] {(byte)value});
+ }
+ }
+
+ ///
+ /// From the SMPP spec:
+ /// The its_session_info parameter is a required parameter for the CDMA Interactive
+ /// Teleservice as defined by the Korean PCS carriers [KORITS]. It contains control
+ /// information for the interactive session between an MS and an ESME.
+ ///
+ /// See section 5.3.2.43 of the SMPP spec for how to set this.
+ ///
+ public string ItsSessionInfo
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.its_session_info);
+ }
+
+ set
+ {
+ PduUtil.SetItsSessionInfo(this, value);
+ }
+ }
+
+ ///
+ /// From the SMPP spec:
+ /// The ussd_service_op parameter is required to define the USSD service operation
+ /// when SMPP is being used as an interface to a(GSM)USSD system.
+ ///
+ /// See 5.3.2.44 of the SMPP spec for how to set this.
+ ///
+ public string UssdServiceOp
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)OptionalParamCodes.ussd_service_op);
+ }
+
+ set
+ {
+ if(value == null)
+ {
+ SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.ussd_service_op, string.Empty);
+ }
+ else if(value.Length == 1)
+ {
+ SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.ussd_service_op, value);
+ }
+ else
+ {
+ throw new ArgumentException("ussd_service_op must have length 1");
+ }
+ }
+ }
+
+ #endregion optional params
+
+ #region constructors
+
+ ///
+ /// Creates a submit Pdu. Sets source address TON to international,
+ /// source address NPI to ISDN, source address to "", registered delivery type to none,
+ /// ESM class to 0, data coding to SMSC default, protocol ID to v3.4, priority to level 1,
+ /// validity period to default, replace if present to false, default message ID to 0,
+ /// the short message to an empty string, the destination address TON to international,
+ /// destination address NPI to ISDN, the destination address to "", the command status
+ /// to 0, and the Command ID to submit_sm.
+ ///
+ public SmppSubmitSm(): base()
+ {
+ }
+
+ ///
+ /// Creates a new SmppSubmitSm for incoming PDUs.
+ ///
+ /// The incoming bytes to decode.
+ public SmppSubmitSm(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ DestinationAddressTon = Pdu.TonType.International;
+ DestinationAddressNpi = Pdu.NpiType.ISDN;
+ DestinationAddress = null;
+ CommandStatus = 0;
+ CommandID = CommandIdType.submit_sm;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(ServiceType)));
+ pdu.Add((byte)SourceAddressTon);
+ pdu.Add((byte)SourceAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SourceAddress)));
+ pdu.Add((byte)DestinationAddressTon);
+ pdu.Add((byte)DestinationAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(DestinationAddress)));
+ pdu.AddRange(GetBytesAfterDestination());
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the submit_sm Pdu. The Pdu has basically the same format as
+ /// the submit_sm Pdu, but in this case it is a response.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ ServiceType = SmppStringUtil.GetCStringFromBody(ref remainder);
+ SourceAddressTon =(TonType)remainder[0];
+ SourceAddressNpi =(NpiType)remainder[1];
+ SourceAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ DestinationAddressTon =(TonType)remainder[0];
+ DestinationAddressNpi =(NpiType)remainder[1];
+ DestinationAddress = SmppStringUtil.GetCStringFromBody(ref remainder, 2);
+ EsmClass = remainder[0];
+ ProtocolId =(SmppVersionType)remainder[1];
+ PriorityFlag =(PriorityType)remainder[2];
+ ScheduleDeliveryTime = SmppStringUtil.GetCStringFromBody(ref remainder, 3);
+ ValidityPeriod = SmppStringUtil.GetCStringFromBody(ref remainder);
+ RegisteredDelivery =(RegisteredDeliveryType)remainder[0];
+ ReplaceIfPresentFlag =(remainder[1] == 0)? false : true;
+ DataCoding =(DataCodingType)remainder[2];
+ SmDefaultMessageId = remainder[3];
+ _SmLength = remainder[4];
+ ShortMessage = SmppStringUtil.GetStringFromBody(ref remainder, 5, 5 + _SmLength);
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Request/SmppUnbind.cs b/Packet/Request/SmppUnbind.cs
new file mode 100644
index 0000000..633bdd3
--- /dev/null
+++ b/Packet/Request/SmppUnbind.cs
@@ -0,0 +1,76 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Request
+{
+ ///
+ /// Class to issue an unbind request to the SMSC.
+ ///
+ public class SmppUnbind : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates an unbind PDU.
+ ///
+ public SmppUnbind(): base()
+ {}
+
+ ///
+ /// Creates an unbind PDU.
+ ///
+ /// The bytes received from an ESME.
+ public SmppUnbind(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.unbind;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// This decodes the query_sm Pdu.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+
+ TranslateTlvDataIntoTable(remainder);
+ }
+ }
+}
diff --git a/Packet/Response/SmppBindResp.cs b/Packet/Response/SmppBindResp.cs
new file mode 100644
index 0000000..753e758
--- /dev/null
+++ b/Packet/Response/SmppBindResp.cs
@@ -0,0 +1,124 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Text;
+using System.Collections;
+using RoaminSMPP;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Class to define an SMSC bind response.
+ ///
+ public class SmppBindResp : Pdu
+ {
+ private string _SystemId = string.Empty;
+
+ ///
+ /// The ID of the SMSC.
+ ///
+ public string SystemId
+ {
+ get
+ {
+ return _SystemId;
+ }
+
+ set
+ {
+ _SystemId = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// The SMPP version supported by SMSC.
+ ///
+ public string ScInterfaceVersion
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)
+ Pdu.OptionalParamCodes.SC_interface_version);
+ }
+
+ set
+ {
+ string version = value;
+ if(value == null)
+ {
+ version = string.Empty;
+ }
+ SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.SC_interface_version, version);
+ }
+ }
+
+ #region constructors
+
+ ///
+ /// Creates a bind response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppBindResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a bind_resp.
+ ///
+ public SmppBindResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the bind response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ SystemId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes. Note that this sets the bind type to
+ /// transceiver so you will want to change this if you are not dealing with a
+ /// transceiver. This also sets system type to an empty string.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.bind_transceiver_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(SystemId)));
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppCancelSmResp.cs b/Packet/Response/SmppCancelSmResp.cs
new file mode 100644
index 0000000..a1ab132
--- /dev/null
+++ b/Packet/Response/SmppCancelSmResp.cs
@@ -0,0 +1,75 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Response Pdu for the cancel_sm command.
+ ///
+ public class SmppCancelSmResp : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates a cancel_sm Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppCancelSmResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a cancel_sm Pdu.
+ ///
+ public SmppCancelSmResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the cancel_sm response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ TranslateTlvDataIntoTable(BytesAfterHeader);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.cancel_sm_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppDataSmResp.cs b/Packet/Response/SmppDataSmResp.cs
new file mode 100644
index 0000000..6365674
--- /dev/null
+++ b/Packet/Response/SmppDataSmResp.cs
@@ -0,0 +1,189 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Text;
+using RoaminSMPP.Utility;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Response Pdu for the data_sm command.
+ ///
+ public class SmppDataSmResp : SmppSubmitSmResp
+ {
+ ///
+ /// Enumerates the delivery failure types.
+ ///
+ public enum DeliveryFailureType : byte
+ {
+ ///
+ /// DestinationUnavailable
+ ///
+ DestinationUnavailable = 0x00,
+ ///
+ /// DestinationAddressInvalid
+ ///
+ DestinationAddressInvalid = 0x01,
+ ///
+ /// PermanentNetworkError
+ ///
+ PermanentNetworkError = 0x02,
+ ///
+ /// TemporaryNetworkError
+ ///
+ TemporaryNetworkError = 0x03
+ }
+
+ #region optional parameters
+
+ ///
+ /// Indicates the reason for delivery failure.
+ ///
+ public DeliveryFailureType DeliveryFailureReason
+ {
+ get
+ {
+ return(DeliveryFailureType)
+ GetOptionalParamBytes((ushort)
+ Pdu.OptionalParamCodes.delivery_failure_reason)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (UInt16)Pdu.OptionalParamCodes.delivery_failure_reason,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering((byte)value)));
+ }
+ }
+
+ ///
+ /// Error code specific to a wireless network. See SMPP spec section
+ /// 5.3.2.31 for details.
+ ///
+ public string NetworkErrorCode
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)
+ Pdu.OptionalParamCodes.network_error_code);
+ }
+
+ set
+ {
+ PduUtil.SetNetworkErrorCode(this, value);
+ }
+ }
+
+ ///
+ /// Text(ASCII)giving additional info on the meaning of the response.
+ ///
+ public string AdditionalStatusInfoText
+ {
+ get
+ {
+ return GetOptionalParamString((ushort)
+ Pdu.OptionalParamCodes.additional_status_info_text);
+ }
+
+ set
+ {
+ const int MAX_STATUS_LEN = 264;
+ if(value == null)
+ {
+ SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.additional_status_info_text, string.Empty);
+ }
+ else if(value.Length <= MAX_STATUS_LEN)
+ {
+ SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.additional_status_info_text, value);
+ }
+ else
+ {
+ throw new ArgumentException(
+ "additional_status_info_text must have length <= " + MAX_STATUS_LEN);
+ }
+ }
+ }
+
+ ///
+ /// Indicates whether the Delivery Pending Flag was set.
+ ///
+ public DpfResultType DpfResult
+ {
+ get
+ {
+ return(DpfResultType)
+ GetOptionalParamBytes((ushort)
+ Pdu.OptionalParamCodes.dpf_result)[0];
+ }
+
+ set
+ {
+ SetOptionalParamBytes(
+ (UInt16)Pdu.OptionalParamCodes.dpf_result,
+ BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering((byte)value)));
+ }
+ }
+
+ #endregion optional parameters
+
+ #region constructors
+
+ ///
+ /// Creates a data_sm_resp Pdu.
+ ///
+ public SmppDataSmResp(): base()
+ {}
+
+ ///
+ /// Creates a data_sm_resp Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppDataSmResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.data_sm_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppDeliverSmResp.cs b/Packet/Response/SmppDeliverSmResp.cs
new file mode 100644
index 0000000..3854c36
--- /dev/null
+++ b/Packet/Response/SmppDeliverSmResp.cs
@@ -0,0 +1,78 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// This class defines an ESME originated deliver_sm_resp.
+ ///
+ public class SmppDeliverSmResp : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates a deliver_sm_resp Pdu. Sets command status and command ID.
+ ///
+ public SmppDeliverSmResp(): base()
+ {}
+
+ ///
+ /// Creates a deliver_sm_resp Pdu. Sets command status and command ID.
+ ///
+ /// The incoming bytes from the ESME.
+ public SmppDeliverSmResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.deliver_sm_resp;
+ }
+
+ ///
+ /// Creates the byte encoding for this Pdu.
+ ///
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ //the message_id is unused and is always set to null
+ pdu.Add((byte)0x00);
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+
+ ///
+ /// Decodes the deliver_sm response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder, 1);
+ }
+ }
+}
diff --git a/Packet/Response/SmppEnquireLinkResp.cs b/Packet/Response/SmppEnquireLinkResp.cs
new file mode 100644
index 0000000..77ddbaa
--- /dev/null
+++ b/Packet/Response/SmppEnquireLinkResp.cs
@@ -0,0 +1,75 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Defines the response Pdu from an enquire_link.
+ ///
+ public class SmppEnquireLinkResp : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates an enquire_link Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppEnquireLinkResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates an enquire_link Pdu.
+ ///
+ public SmppEnquireLinkResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the enquire_link response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ TranslateTlvDataIntoTable(BytesAfterHeader);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.enquire_link_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppGenericNackResp.cs b/Packet/Response/SmppGenericNackResp.cs
new file mode 100644
index 0000000..22236c8
--- /dev/null
+++ b/Packet/Response/SmppGenericNackResp.cs
@@ -0,0 +1,78 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Represents a generic NACK sent by the SMSC.
+ ///
+ public class SmppGenericNackResp : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates a generic_nack response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppGenericNackResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a generic_nack response Pdu.
+ ///
+ public SmppGenericNackResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the generic NACK response from the SMSC. Since a generic
+ /// NACK response contains essentially nothing other than the header,
+ /// this method does nothing special. It will grab any TLVs that are in
+ /// the Pdu, however.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ TranslateTlvDataIntoTable(BytesAfterHeader);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.generic_nack;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppQuerySmResp.cs b/Packet/Response/SmppQuerySmResp.cs
new file mode 100644
index 0000000..00a401d
--- /dev/null
+++ b/Packet/Response/SmppQuerySmResp.cs
@@ -0,0 +1,175 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Text;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// This class defines the response to a query_sm Pdu.
+ ///
+ public class SmppQuerySmResp : Pdu
+ {
+ private string _MessageId = string.Empty;
+ private string _FinalDate = string.Empty;
+ private MessageStateType _MessageStatus = MessageStateType.Enroute;
+ private byte _ErrorCode = 0;
+
+ #region mandatory parameters
+
+ ///
+ /// SMSC Message ID of the message whose state is being queried.
+ ///
+ public string MessageId
+ {
+ get
+ {
+ return _MessageId;
+ }
+
+ set
+ {
+ _MessageId = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// Date and time when the queried message reached a final state. For messages
+ /// which have not yet reached a final state this field will be null.
+ ///
+ public string FinalDate
+ {
+ get
+ {
+ return _FinalDate;
+ }
+
+ set
+ {
+ if(value != null && value != string.Empty)
+ {
+ if(value.Length == DATE_TIME_LENGTH)
+ {
+ _FinalDate = value;
+ }
+ else
+ {
+ throw new ArgumentException("Final date is not in the correct format.");
+ }
+ }
+ else
+ {
+ _FinalDate = string.Empty;
+ }
+ }
+ }
+
+ ///
+ /// Specifies the status of the queried short message.
+ ///
+ public MessageStateType MessageStatus
+ {
+ get
+ {
+ return _MessageStatus;
+ }
+
+ set
+ {
+ _MessageStatus = value;
+ }
+ }
+
+ ///
+ /// Holds a network error code defining the reason for failure of message delivery.
+ ///
+ public byte ErrorCode
+ {
+ get
+ {
+ return _ErrorCode;
+ }
+
+ set
+ {
+ _ErrorCode = value;
+ }
+ }
+
+ #endregion mandatory parameters
+
+ #region constructors
+
+ ///
+ /// Creates a query_sm response.
+ ///
+ /// The bytes received from an ESME.
+ public SmppQuerySmResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a query_sm response.
+ ///
+ public SmppQuerySmResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the query_sm response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ byte[] remainder = BytesAfterHeader;
+ MessageId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ FinalDate = SmppStringUtil.GetCStringFromBody(ref remainder);
+ MessageStatus = (MessageStateType)remainder[0];
+ ErrorCode = remainder[1];
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder, 2);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.query_sm_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(FinalDate)));
+ pdu.Add((byte)MessageStatus);
+ pdu.Add(ErrorCode);
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppReplaceSmResp.cs b/Packet/Response/SmppReplaceSmResp.cs
new file mode 100644
index 0000000..4290b03
--- /dev/null
+++ b/Packet/Response/SmppReplaceSmResp.cs
@@ -0,0 +1,75 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Defines the replace_sm_resp Pdu.
+ ///
+ public class SmppReplaceSmResp : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates a replace_sm response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppReplaceSmResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a replace_sm response Pdu.
+ ///
+ public SmppReplaceSmResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the replace_sm response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ TranslateTlvDataIntoTable(BytesAfterHeader);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.replace_sm_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppSubmitMultiResp.cs b/Packet/Response/SmppSubmitMultiResp.cs
new file mode 100644
index 0000000..9b4331e
--- /dev/null
+++ b/Packet/Response/SmppSubmitMultiResp.cs
@@ -0,0 +1,145 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Text;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Description of SmppSubmitMultiResp.
+ ///
+ public class SmppSubmitMultiResp : SmppSubmitSmResp
+ {
+ private byte _NumberUnsuccessful = 0;
+ private UnsuccessAddress[] _UnsuccessfulAddresses = new UnsuccessAddress[0];
+
+ ///
+ /// The number of messages that could not be delivered. The mutator is not
+ /// provided as setting the unsucess addresses will set it.
+ ///
+ public byte NumberUnsuccessful
+ {
+ get
+ {
+ return _NumberUnsuccessful;
+ }
+ }
+
+ ///
+ /// The array of unsuccessful addresses. This will set the number of addresses as well.
+ /// Passing in null will set them to zero. Calling the accessor will get you a cloned array.
+ /// You must use the set accessor to modify the values.
+ ///
+ public UnsuccessAddress[] UnsuccessfulAddresses
+ {
+ get
+ {
+ return(UnsuccessAddress[])_UnsuccessfulAddresses.Clone();
+ }
+
+ set
+ {
+ _UnsuccessfulAddresses = (value == null) ? new UnsuccessAddress[0] : value;
+ _NumberUnsuccessful = (byte)_UnsuccessfulAddresses.Length;
+ }
+ }
+
+ #region constructors
+
+ ///
+ /// Creates a submit_multi response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppSubmitMultiResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a submit_multi response Pdu.
+ ///
+ public SmppSubmitMultiResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the submit_multi response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ DecodeNonTlv();
+
+ byte[] remainder = base.ResponseAfterMsgId;
+ //the SMSC might not send back the number of unsuccessful messages,
+ //so check if it did
+ if(remainder.Length > 0)
+ {
+ _NumberUnsuccessful = remainder[0];
+ UnsuccessfulAddresses = new UnsuccessAddress[NumberUnsuccessful];
+ long length = remainder.Length - 1;
+ byte[] newRemainder = new byte[length];
+ Array.Copy(remainder, 1, newRemainder, 0, length);
+ remainder = newRemainder;
+ newRemainder = null;
+ //unsuccessful
+ for(int i = 0; i < UnsuccessfulAddresses.Length; i++)
+ {
+ _UnsuccessfulAddresses[i] = new UnsuccessAddress(ref remainder);
+ }
+ }
+
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(remainder);
+ }
+
+ ///
+ /// Initializes this Pdu.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.submit_multi_resp;
+ }
+
+ ///
+ /// Creates the byte encoding for this Pdu.
+ ///
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+ pdu.Add(NumberUnsuccessful);
+ //add the unsuccess addresses
+ UnsuccessAddress[] unsuccessfulAddresses = UnsuccessfulAddresses;
+
+ for(int i = 0; i < NumberUnsuccessful; i++)
+ {
+ pdu.Add((byte)unsuccessfulAddresses[i].DestinationAddressTon);
+ pdu.Add((byte)unsuccessfulAddresses[i].DestinationAddressNpi);
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(
+ Encoding.ASCII.GetBytes(unsuccessfulAddresses[i].DestinationAddress)));
+ pdu.AddRange(BitConverter.GetBytes(
+ UnsignedNumConverter.SwapByteOrdering(unsuccessfulAddresses[i].ErrorStatusCode)));
+ }
+//
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppSubmitSmResp.cs b/Packet/Response/SmppSubmitSmResp.cs
new file mode 100644
index 0000000..4ce4db6
--- /dev/null
+++ b/Packet/Response/SmppSubmitSmResp.cs
@@ -0,0 +1,123 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Text;
+using RoaminSMPP.Utility;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Defines the submit_sm response from the SMSC.
+ ///
+ public class SmppSubmitSmResp : Pdu
+ {
+ private string _MessageId = string.Empty;
+ private byte[] _ResponseAfterMsgId;
+
+ ///
+ /// The message ID(SMSC-assigned)of the submitted message.
+ ///
+ public string MessageId
+ {
+ get
+ {
+ return _MessageId;
+ }
+
+ set
+ {
+ _MessageId = (value == null) ? string.Empty : value;
+ }
+ }
+
+ ///
+ /// Accessor for the submit_multi to get at the response after the message ID.
+ /// This is, in essence, set only after DecodeSmscResponse()in this base class
+ /// is called.
+ ///
+ protected byte[] ResponseAfterMsgId
+ {
+ get
+ {
+ return _ResponseAfterMsgId;
+ }
+ }
+
+ #region constructors
+
+ ///
+ /// Creates a submit_sm response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppSubmitSmResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates a submit_sm_resp
+ ///
+ public SmppSubmitSmResp(): base()
+ {
+ }
+
+ #endregion constructors
+
+ ///
+ /// Decodes the submit response from the SMSC.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ DecodeNonTlv();
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(_ResponseAfterMsgId);
+ }
+
+ ///
+ /// Decodes the non-TLV bytes. Needed for the submit_multi_resp.
+ ///
+ protected void DecodeNonTlv()
+ {
+ //header
+ byte[] remainder = BytesAfterHeader;
+ MessageId = SmppStringUtil.GetCStringFromBody(ref remainder);
+ _ResponseAfterMsgId = remainder;
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.submit_sm_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+ pdu.AddRange(SmppStringUtil.ArrayCopyWithNull(Encoding.ASCII.GetBytes(MessageId)));
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/Packet/Response/SmppUnbindResp.cs b/Packet/Response/SmppUnbindResp.cs
new file mode 100644
index 0000000..4a6015d
--- /dev/null
+++ b/Packet/Response/SmppUnbindResp.cs
@@ -0,0 +1,77 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+
+namespace RoaminSMPP.Packet.Response
+{
+ ///
+ /// Defines the unbind response from the SMSC.
+ ///
+ public class SmppUnbindResp : Pdu
+ {
+ #region constructors
+
+ ///
+ /// Creates an unbind response Pdu.
+ ///
+ /// The bytes received from an ESME.
+ public SmppUnbindResp(byte[] incomingBytes): base(incomingBytes)
+ {}
+
+ ///
+ /// Creates an unbind response Pdu.
+ ///
+ public SmppUnbindResp(): base()
+ {}
+
+ #endregion constructors
+
+ ///
+ /// Decodes the unbind response from the SMSC. Since an unbind response contains
+ /// essentially nothing other than the header, this method does nothing special.
+ /// It will grab any TLVs that are in the Pdu, however.
+ ///
+ protected override void DecodeSmscResponse()
+ {
+ //fill the TLV table if applicable
+ TranslateTlvDataIntoTable(BytesAfterHeader);
+ }
+
+ ///
+ /// Initializes this Pdu for sending purposes.
+ ///
+ protected override void InitPdu()
+ {
+ base.InitPdu();
+ CommandStatus = 0;
+ CommandID = CommandIdType.unbind_resp;
+ }
+
+ ///
+ /// Gets the hex encoding(big-endian)of this Pdu.
+ ///
+ ///The hex-encoded version of the Pdu
+ public override void ToMsbHexEncoding()
+ {
+ ArrayList pdu = GetPduHeader();
+
+ PacketBytes = EncodePduForTransmission(pdu);
+ }
+ }
+}
diff --git a/README.TXT b/README.TXT
new file mode 100644
index 0000000..5217f78
--- /dev/null
+++ b/README.TXT
@@ -0,0 +1,12 @@
+This software is meant to provide an open source edition of the basic
+SMPP v3.4 functionality. It includes PDU definitions for all of the
+PDUs in the spec.
+
+I will no longer be adding functionality to this app; I may or may not fix bugs. If you find a
+bug and want it fixed, BE NICE! I don't like people who make demands on my (not so free) time.
+
+Please read the enclosed license files, COPYING (GNU GPL) and COPYING.LESSER (GNU LGPL) for more details.
+
+Thanks!
+
+-Chris Bouzek
diff --git a/RoaminSMPP.cmbx b/RoaminSMPP.cmbx
new file mode 100644
index 0000000..d4c6284
--- /dev/null
+++ b/RoaminSMPP.cmbx
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RoaminSMPP.mdsx b/RoaminSMPP.mdsx
new file mode 100644
index 0000000..0bb9bbf
--- /dev/null
+++ b/RoaminSMPP.mdsx
@@ -0,0 +1,3 @@
+
+ ./build/bin
+
\ No newline at end of file
diff --git a/RoaminSMPP.pidb b/RoaminSMPP.pidb
new file mode 100644
index 0000000..bf53c53
Binary files /dev/null and b/RoaminSMPP.pidb differ
diff --git a/RoaminSMPP.prjx b/RoaminSMPP.prjx
new file mode 100644
index 0000000..2ba3426
--- /dev/null
+++ b/RoaminSMPP.prjx
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SMPPCommunicator.cs b/SMPPCommunicator.cs
new file mode 100644
index 0000000..56ca12e
--- /dev/null
+++ b/SMPPCommunicator.cs
@@ -0,0 +1,1052 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Net.Sockets;
+using System.Collections;
+using System.Threading;
+using RoaminSMPP.Packet.Request;
+using RoaminSMPP.Utility;
+using RoaminSMPP.Packet.Response;
+using RoaminSMPP.Packet;
+using RoaminSMPP.EventObjects;
+using System.Timers;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace RoaminSMPP
+{
+ ///
+ /// Wrapper class to provide asynchronous I/O for the RoaminSMPP library. Note that most
+ /// SMPP events have default handlers. If the events are overridden by the caller by adding
+ /// event handlers, it is the caller's responsibility to ensure that the proper response is
+ /// sent. For example: there is a default deliver_sm_resp implemented. If you "listen" to
+ /// the deliver_sm event, it is your responsibility to then send the deliver_sm_resp packet.
+ ///
+ public class SMPPCommunicator : Component
+ {
+ private AsyncSocketClient asClient;
+ private Int16 _Port;
+ private SmppBind.BindingType _BindType;
+ private string _Host;
+ private Pdu.NpiType _NpiType;
+ private Pdu.TonType _TonType;
+ private SmppBind.SmppVersionType _Version;
+ private string _AddressRange;
+ private string _Password;
+ private string _SystemId;
+ private string _SystemType;
+ private System.Timers.Timer timer;
+ private int _EnquireLinkInterval;
+ private int _SleepTimeAfterSocketFailure;
+ private bool _SentUnbindPacket = true; //default to true since we start out unbound
+ private string username;
+
+ ///
+ /// Required designer variable.
+ ///
+ protected Container components = null;
+
+ #region properties
+
+ ///
+ /// The username to use for software validation.
+ ///
+ public string Username
+ {
+ set
+ {
+ username = value;
+ }
+ }
+
+ ///
+ /// Accessor to determine if we have sent the unbind packet out. Once the packet is
+ /// sent, you can consider this object to be unbound.
+ ///
+ public bool SentUnbindPacket
+ {
+ get
+ {
+ return _SentUnbindPacket;
+ }
+ }
+
+ ///
+ /// The port on the SMSC to connect to.
+ ///
+ public Int16 Port
+ {
+ get
+ {
+ return _Port;
+ }
+ set
+ {
+ _Port = value;
+ }
+ }
+
+ ///
+ /// The binding type(receiver, transmitter, or transceiver)to use
+ /// when connecting to the SMSC.
+ ///
+ public SmppBind.BindingType BindType
+ {
+ get
+ {
+ return _BindType;
+ }
+ set
+ {
+ _BindType = value;
+ }
+
+ }
+ ///
+ /// The system type to use when connecting to the SMSC.
+ ///
+ public string SystemType
+ {
+ get
+ {
+ return _SystemType;
+ }
+ set
+ {
+ _SystemType = value;
+ }
+ }
+ ///
+ /// The system ID to use when connecting to the SMSC. This is,
+ /// in essence, a user name.
+ ///
+ public string SystemId
+ {
+ get
+ {
+ return _SystemId;
+ }
+ set
+ {
+ _SystemId = value;
+ }
+ }
+ ///
+ /// The password to use when connecting to an SMSC.
+ ///
+ public string Password
+ {
+ get
+ {
+ return _Password;
+ }
+ set
+ {
+ _Password = value;
+ }
+ }
+
+ ///
+ /// The host to bind this SMPPCommunicator to.
+ ///
+ public string Host
+ {
+ get
+ {
+ return _Host;
+ }
+ set
+ {
+ _Host = value;
+ }
+ }
+ ///
+ /// The number plan indicator that this SMPPCommunicator should use.
+ ///
+ public Pdu.NpiType NpiType
+ {
+ get
+ {
+ return _NpiType;
+ }
+ set
+ {
+ _NpiType = value;
+ }
+ }
+
+ ///
+ /// The type of number that this SMPPCommunicator should use.
+ ///
+ public Pdu.TonType TonType
+ {
+ get
+ {
+ return _TonType;
+ }
+ set
+ {
+ _TonType = value;
+ }
+ }
+
+ ///
+ /// The SMPP specification version to use.
+ ///
+ public SmppBind.SmppVersionType Version
+ {
+ get
+ {
+ return _Version;
+ }
+ set
+ {
+ _Version = value;
+ }
+ }
+
+ ///
+ /// The address range of this SMPPCommunicator.
+ ///
+ public string AddressRange
+ {
+ get
+ {
+ return _AddressRange;
+ }
+ set
+ {
+ _AddressRange = value;
+ }
+ }
+
+ ///
+ /// Set to the number of seconds that should elapse in between enquire_link
+ /// packets. Setting this to anything other than 0 will enable the timer, setting
+ /// it to 0 will disable the timer. Note that the timer is only started/stopped
+ /// during a bind/unbind. Negative values are ignored.
+ ///
+ public int EnquireLinkInterval
+ {
+ get
+ {
+ return _EnquireLinkInterval;
+ }
+
+ set
+ {
+ if(value >= 0)
+ _EnquireLinkInterval = value;
+ }
+ }
+
+ ///
+ /// Sets the number of seconds that the system will wait before trying to rebind
+ /// after a total network failure(due to cable problems, etc). Negative values are
+ /// ignored.
+ ///
+ public int SleepTimeAfterSocketFailure
+ {
+ get
+ {
+ return _SleepTimeAfterSocketFailure;
+ }
+
+ set
+ {
+ if(value >= 0)
+ _SleepTimeAfterSocketFailure = value;
+ }
+ }
+ #endregion properties
+
+ #region events
+ ///
+ /// Event called when the communicator receives a bind response.
+ ///
+ public event BindRespEventHandler OnBindResp;
+ ///
+ /// Event called when an error occurs.
+ ///
+ public event ErrorEventHandler OnError;
+ ///
+ /// Event called when the communicator is unbound.
+ ///
+ public event UnbindRespEventHandler OnUnboundResp;
+ ///
+ /// Event called when the connection is closed.
+ ///
+ public event ClosingEventHandler OnClose;
+ ///
+ /// Event called when an alert_notification comes in.
+ ///
+ public event AlertEventHandler OnAlert;
+ ///
+ /// Event called when a submit_sm_resp is received.
+ ///
+ public event SubmitSmRespEventHandler OnSubmitSmResp;
+ ///
+ /// Event called when a response to an enquire_link_resp is received.
+ ///
+ public event EnquireLinkRespEventHandler OnEnquireLinkResp;
+ ///
+ /// Event called when a submit_sm is received.
+ ///
+ public event SubmitSmEventHandler OnSubmitSm;
+ ///
+ /// Event called when a query_sm is received.
+ ///
+ public event QuerySmEventHandler OnQuerySm;
+ ///
+ /// Event called when a generic_nack is received.
+ ///
+ public event GenericNackEventHandler OnGenericNack;
+ ///
+ /// Event called when an enquire_link is received.
+ ///
+ public event EnquireLinkEventHandler OnEnquireLink;
+ ///
+ /// Event called when an unbind is received.
+ ///
+ public event UnbindEventHandler OnUnbind;
+ ///
+ /// Event called when the communicator receives a request for a bind.
+ ///
+ public event BindEventHandler OnBind;
+ ///
+ /// Event called when the communicator receives a cancel_sm.
+ ///
+ public event CancelSmEventHandler OnCancelSm;
+ ///
+ /// Event called when the communicator receives a cancel_sm_resp.
+ ///
+ public event CancelSmRespEventHandler OnCancelSmResp;
+ ///
+ /// Event called when the communicator receives a query_sm_resp.
+ ///
+ public event QuerySmRespEventHandler OnQuerySmResp;
+ ///
+ /// Event called when the communicator receives a data_sm.
+ ///
+ public event DataSmEventHandler OnDataSm;
+ ///
+ /// Event called when the communicator receives a data_sm_resp.
+ ///
+ public event DataSmRespEventHandler OnDataSmResp;
+ ///
+ /// Event called when the communicator receives a deliver_sm.
+ ///
+ public event DeliverSmEventHandler OnDeliverSm;
+ ///
+ /// Event called when the communicator receives a deliver_sm_resp.
+ ///
+ public event DeliverSmRespEventHandler OnDeliverSmResp;
+ ///
+ /// Event called when the communicator receives a replace_sm.
+ ///
+ public event ReplaceSmEventHandler OnReplaceSm;
+ ///
+ /// Event called when the communicator receives a replace_sm_resp.
+ ///
+ public event ReplaceSmRespEventHandler OnReplaceSmResp;
+ ///
+ /// Event called when the communicator receives a submit_multi.
+ ///
+ public event SubmitMultiEventHandler OnSubmitMulti;
+ ///
+ /// Event called when the communicator receives a submit_multi_resp.
+ ///
+ public event SubmitMultiRespEventHandler OnSubmitMultiResp;
+ #endregion events
+
+ #region delegates
+
+ ///
+ /// Delegate to handle binding responses of the communicator.
+ ///
+ public delegate void BindRespEventHandler(object source, BindRespEventArgs e);
+ ///
+ /// Delegate to handle any errors that come up.
+ ///
+ public delegate void ErrorEventHandler(object source, CommonErrorEventArgs e);
+ ///
+ /// Delegate to handle the unbind_resp.
+ ///
+ public delegate void UnbindRespEventHandler(object source, UnbindRespEventArgs e);
+ ///
+ /// Delegate to handle closing of the connection.
+ ///
+ public delegate void ClosingEventHandler(object source, EventArgs e);
+ ///
+ /// Delegate to handle alert_notification events.
+ ///
+ public delegate void AlertEventHandler(object source, AlertEventArgs e);
+ ///
+ /// Delegate to handle a submit_sm_resp
+ ///
+ public delegate void SubmitSmRespEventHandler(object source, SubmitSmRespEventArgs e);
+ ///
+ /// Delegate to handle the enquire_link response.
+ ///
+ public delegate void EnquireLinkRespEventHandler(object source, EnquireLinkRespEventArgs e);
+ ///
+ /// Delegate to handle the submit_sm.
+ ///
+ public delegate void SubmitSmEventHandler(object source, SubmitSmEventArgs e);
+ ///
+ /// Delegate to handle the query_sm.
+ ///
+ public delegate void QuerySmEventHandler(object source, QuerySmEventArgs e);
+ ///
+ /// Delegate to handle generic_nack.
+ ///
+ public delegate void GenericNackEventHandler(object source, GenericNackEventArgs e);
+ ///
+ /// Delegate to handle the enquire_link.
+ ///
+ public delegate void EnquireLinkEventHandler(object source, EnquireLinkEventArgs e);
+ ///
+ /// Delegate to handle the unbind message.
+ ///
+ public delegate void UnbindEventHandler(object source, UnbindEventArgs e);
+ ///
+ /// Delegate to handle requests for binding of the communicator.
+ ///
+ public delegate void BindEventHandler(object source, BindEventArgs e);
+ ///
+ /// Delegate to handle cancel_sm.
+ ///
+ public delegate void CancelSmEventHandler(object source, CancelSmEventArgs e);
+ ///
+ /// Delegate to handle cancel_sm_resp.
+ ///
+ public delegate void CancelSmRespEventHandler(object source, CancelSmRespEventArgs e);
+ ///
+ /// Delegate to handle query_sm_resp.
+ ///
+ public delegate void QuerySmRespEventHandler(object source, QuerySmRespEventArgs e);
+ ///
+ /// Delegate to handle data_sm.
+ ///
+ public delegate void DataSmEventHandler(object source, DataSmEventArgs e);
+ ///
+ /// Delegate to handle data_sm_resp.
+ ///
+ public delegate void DataSmRespEventHandler(object source, DataSmRespEventArgs e);
+ ///
+ /// Delegate to handle deliver_sm.
+ ///
+ public delegate void DeliverSmEventHandler(object source, DeliverSmEventArgs e);
+ ///
+ /// Delegate to handle deliver_sm_resp.
+ ///
+ public delegate void DeliverSmRespEventHandler(object source, DeliverSmRespEventArgs e);
+ ///
+ /// Delegate to handle replace_sm.
+ ///
+ public delegate void ReplaceSmEventHandler(object source, ReplaceSmEventArgs e);
+ ///
+ /// Delegate to handle replace_sm_resp.
+ ///
+ public delegate void ReplaceSmRespEventHandler(object source, ReplaceSmRespEventArgs e);
+ ///
+ /// Delegate to handle submit_multi.
+ ///
+ public delegate void SubmitMultiEventHandler(object source, SubmitMultiEventArgs e);
+ ///
+ /// Delegate to handle submit_multi_resp.
+ ///
+ public delegate void SubmitMultiRespEventHandler(object source, SubmitMultiRespEventArgs e);
+
+ #endregion delegates
+
+ #region constructors
+
+ ///
+ /// Creates a default SMPPCommunicator, with port 9999, bindtype set to
+ /// transceiver, host set to localhost, NPI type set to ISDN, TON type
+ /// set to International, version set to 3.4, enquire link interval set
+ /// to 0(disabled), sleep time after socket failure set to 10 seconds,
+ /// and address range, password, system type and system ID set to null
+ ///(no value).
+ ///
+ /// The container that will hold this
+ /// component.
+ public SMPPCommunicator(IContainer container)
+ {
+ // Required for Windows.Forms Class Composition Designer support
+ InitCommunicator();
+ container.Add(this);
+ InitializeComponent();
+ }
+
+ ///
+ /// Creates a default SMPPCommunicator, with port 9999, bindtype set to
+ /// transceiver, host set to localhost, NPI type set to ISDN, TON type
+ /// set to International, version set to 3.4, enquire link interval set
+ /// to 0(disabled), sleep time after socket failure set to 10 seconds,
+ /// and address range, password, system type and system ID set to null
+ ///(no value).
+ ///
+ public SMPPCommunicator()
+ {
+ InitCommunicator();
+
+ InitializeComponent();
+ }
+
+ #endregion constructors
+
+
+ private void delTest() {
+
+ }
+ ///
+ /// Sends a user-specified Pdu(see the RoaminSMPP base library for
+ /// Pdu types). This allows complete flexibility for sending Pdus.
+ ///
+ /// The Pdu to send.
+ public void SendPdu(Pdu packet)
+ {
+ bool sendFailed = true;
+
+ while(sendFailed)
+ {
+ try
+ {
+ packet.ToMsbHexEncoding();
+ asClient.Send(packet.PacketBytes);
+ sendFailed = false;
+ }
+ catch(Exception exc)
+ {
+ if(OnError != null)
+ {
+ OnError(this, new CommonErrorEventArgs(exc));
+ }
+
+ //try to stay alive
+ if((exc.Message.ToLower().IndexOf("socket is closed")>= 0 ||
+ exc.Message.ToLower().IndexOf("unable to write data to the transport connection")>= 0))
+ {
+ System.Threading.Thread.Sleep(SleepTimeAfterSocketFailure * 1000);
+ Bind();
+ }
+ else
+ {
+ //don't know what happened, but kick out
+ sendFailed = false;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Connects and binds the SMPPCommunicator to the SMSC, using the
+ /// values that have been set in the constructor and through the
+ /// properties. This will also start the timer that sends enquire_link packets
+ /// at regular intervals, if it has been enabled.
+ ///
+ public void Bind()
+ {
+ try
+ {
+ if(asClient != null)
+ asClient.Disconnect();
+ }
+ catch
+ {
+ //drop it on the floor
+ }
+
+ //connect
+ try
+ {
+ asClient = new AsyncSocketClient(10240, null,
+ new AsyncSocketClient.MessageHandler(ClientMessageHandler),
+ new AsyncSocketClient.SocketClosingHandler(ClientCloseHandler),
+ new AsyncSocketClient.ErrorHandler(ClientErrorHandler));
+
+ asClient.Connect(Host, Port);
+
+ SmppBind request = new SmppBind();
+ request.SystemId = SystemId;
+ request.Password = Password;
+ request.SystemType = SystemType;
+ request.InterfaceVersion = Version;
+ request.AddressTon = TonType;
+ request.AddressNpi = NpiType;
+ request.AddressRange = AddressRange;
+ request.BindType = BindType;
+
+ SendPdu(request);
+ _SentUnbindPacket = false;
+
+ if(_EnquireLinkInterval > 0)
+ {
+ if(timer == null)
+ {
+ timer = new System.Timers.Timer();
+ timer.Elapsed += new ElapsedEventHandler(TimerElapsed);
+ }
+
+ if(timer != null) //reset the old timer
+ {
+ timer.Stop();
+
+ timer.Interval = EnquireLinkInterval * 1000;
+ timer.Start();
+ }
+ }
+ }
+ catch(Exception exc)
+ {
+ if(OnError != null)
+ {
+ OnError(this, new CommonErrorEventArgs(exc));
+ }
+ }
+ }
+
+ ///
+ /// Unbinds the SMPPCommunicator from the SMSC then disconnects the socket
+ /// when it receives the unbind response from the SMSC. This will also stop the
+ /// timer that sends out the enquire_link packets if it has been enabled. You need to
+ /// explicitly call this to unbind.; it will not be done for you.
+ ///
+ public void Unbind()
+ {
+ if(timer != null)
+ timer.Stop();
+
+ if(!_SentUnbindPacket)
+ {
+ SmppUnbind request = new SmppUnbind();
+ SendPdu(request);
+ _SentUnbindPacket = true;
+ }
+ }
+
+ #region internal methods
+ ///
+ /// Callback method to handle received messages. The AsyncSocketClient
+ /// library calls this; don't call it yourself.
+ ///
+ /// The client to receive messages from.
+ internal void ClientMessageHandler(AsyncSocketClient client)
+ {
+ try
+ {
+ Queue responseQueue = new PduFactory().GetPduQueue(client.Buffer);
+ ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessPduQueue), responseQueue);
+ }
+ catch(Exception exception)
+ {
+ if(OnError != null)
+ {
+ CommonErrorEventArgs e = new CommonErrorEventArgs(exception);
+ OnError(this, e);
+ }
+ }
+ }
+
+ ///
+ /// Callback method to handle socket closing.
+ ///
+ /// The client to receive messages from.
+ internal void ClientCloseHandler(AsyncSocketClient client)
+ {
+ //fire off a closing event
+ if(OnClose != null)
+ {
+ System.EventArgs e = new System.EventArgs();
+ OnClose(this, e);
+ }
+ }
+
+ ///
+ /// Callback method to handle errors.
+ ///
+ /// The client to receive messages from.
+ /// The generated exception.
+ internal void ClientErrorHandler(AsyncSocketClient client,
+ Exception exception)
+ {
+ //fire off an error handler
+ if(OnError != null)
+ {
+ CommonErrorEventArgs e = new CommonErrorEventArgs(exception);
+ OnError(this, e);
+ }
+ }
+ #endregion internal methods
+
+ #region private methods
+
+ ///
+ /// Goes through the packets in the queue and fires events for them. Called by the
+ /// threads in the ThreadPool.
+ ///
+ /// The queue of byte packets.
+ private void ProcessPduQueue(object queueStateObj)
+ {
+ Queue responseQueue = queueStateObj as Queue;
+
+ foreach(Pdu response in responseQueue)
+ {
+ //based on each Pdu, fire off an event
+ if(response != null)
+ FireEvents(response);
+ }
+ }
+
+ ///
+ /// Sends out an enquire_link packet.
+ ///
+ ///
+ ///
+ private void TimerElapsed(object sender, ElapsedEventArgs ea)
+ {
+ SendPdu(new SmppEnquireLink());
+ }
+
+ ///
+ /// Fires an event off based on what Pdu is sent in.
+ ///
+ /// The response to fire an event for.
+ private void FireEvents(Pdu response)
+ {
+ //here we go...
+ if(response is SmppBindResp)
+ {
+ if(OnBindResp != null)
+ {
+ OnBindResp(this, new BindRespEventArgs((SmppBindResp)response));
+ }
+ }
+ else if(response is SmppUnbindResp)
+ {
+ //disconnect
+ asClient.Disconnect();
+ if(OnUnboundResp != null)
+ {
+ OnUnboundResp(this, new UnbindRespEventArgs((SmppUnbindResp)response));
+ }
+ }
+ else if(response is SmppAlertNotification)
+ {
+ if(OnAlert != null)
+ {
+ OnAlert(this, new AlertEventArgs((SmppAlertNotification)response));
+ }
+ }
+ else if(response is SmppSubmitSmResp)
+ {
+ if(OnSubmitSmResp != null)
+ {
+ OnSubmitSmResp(this,
+ new SubmitSmRespEventArgs((SmppSubmitSmResp)response));
+ }
+ }
+ else if(response is SmppEnquireLinkResp)
+ {
+ if(OnEnquireLinkResp != null)
+ {
+ OnEnquireLinkResp(this, new EnquireLinkRespEventArgs((SmppEnquireLinkResp)response));
+ }
+ }
+ else if(response is SmppSubmitSm)
+ {
+ if(OnSubmitSm != null)
+ {
+ OnSubmitSm(this, new SubmitSmEventArgs((SmppSubmitSm)response));
+ }
+ else
+ {
+ //default a response
+ SmppSubmitSmResp pdu = new SmppSubmitSmResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.MessageId = System.Guid.NewGuid().ToString().Substring(0, 10);
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppQuerySm)
+ {
+ if(OnQuerySm != null)
+ {
+ OnQuerySm(this, new QuerySmEventArgs((SmppQuerySm)response));
+ }
+ else
+ {
+ //default a response
+ SmppQuerySmResp pdu = new SmppQuerySmResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppGenericNack)
+ {
+ if(OnGenericNack != null)
+ {
+ OnGenericNack(this, new GenericNackEventArgs((SmppGenericNack)response));
+ }
+ }
+ else if(response is SmppEnquireLink)
+ {
+ if(OnEnquireLink != null)
+ {
+ OnEnquireLink(this, new EnquireLinkEventArgs((SmppEnquireLink)response));
+ }
+
+ //send a response back
+ SmppEnquireLinkResp pdu = new SmppEnquireLinkResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ else if(response is SmppUnbind)
+ {
+ if(OnUnbind != null)
+ {
+ OnUnbind(this, new UnbindEventArgs((SmppUnbind)response));
+ }
+ else
+ {
+ //default a response
+ SmppUnbindResp pdu = new SmppUnbindResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppBind)
+ {
+ if(OnBind != null)
+ {
+ OnBind(this, new BindEventArgs((SmppBind)response));
+ }
+ else
+ {
+ //default a response
+ SmppBindResp pdu = new SmppBindResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+ pdu.SystemId = "Generic";
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppCancelSm)
+ {
+ if(OnCancelSm != null)
+ {
+ OnCancelSm(this, new CancelSmEventArgs((SmppCancelSm)response));
+ }
+ else
+ {
+ //default a response
+ SmppCancelSmResp pdu = new SmppCancelSmResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppCancelSmResp)
+ {
+ if(OnCancelSmResp != null)
+ {
+ OnCancelSmResp(this, new CancelSmRespEventArgs((SmppCancelSmResp)response));
+ }
+ }
+ else if(response is SmppCancelSmResp)
+ {
+ if(OnCancelSmResp != null)
+ {
+ OnCancelSmResp(this, new CancelSmRespEventArgs((SmppCancelSmResp)response));
+ }
+ }
+ else if(response is SmppQuerySmResp)
+ {
+ if(OnQuerySmResp != null)
+ {
+ OnQuerySmResp(this, new QuerySmRespEventArgs((SmppQuerySmResp)response));
+ }
+ }
+ else if(response is SmppDataSm)
+ {
+ if(OnDataSm != null)
+ {
+ OnDataSm(this, new DataSmEventArgs((SmppDataSm)response));
+ }
+ else
+ {
+ //default a response
+ SmppDataSmResp pdu = new SmppDataSmResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+ pdu.MessageId = "Generic";
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppDataSmResp)
+ {
+ if(OnDataSmResp != null)
+ {
+ OnDataSmResp(this, new DataSmRespEventArgs((SmppDataSmResp)response));
+ }
+ }
+ else if(response is SmppDeliverSm)
+ {
+ if(OnDeliverSm != null)
+ {
+ OnDeliverSm(this, new DeliverSmEventArgs((SmppDeliverSm)response));
+ }
+ else
+ {
+ //default a response
+ SmppDeliverSmResp pdu = new SmppDeliverSmResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppDeliverSmResp)
+ {
+ if(OnDeliverSmResp != null)
+ {
+ OnDeliverSmResp(this, new DeliverSmRespEventArgs((SmppDeliverSmResp)response));
+ }
+ }
+ else if(response is SmppReplaceSm)
+ {
+ if(OnReplaceSm != null)
+ {
+ OnReplaceSm(this, new ReplaceSmEventArgs((SmppReplaceSm)response));
+ }
+ else
+ {
+ //default a response
+ SmppReplaceSmResp pdu = new SmppReplaceSmResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppReplaceSmResp)
+ {
+ if(OnReplaceSmResp != null)
+ {
+ OnReplaceSmResp(this, new ReplaceSmRespEventArgs((SmppReplaceSmResp)response));
+ }
+ }
+ else if(response is SmppSubmitMulti)
+ {
+ if(OnSubmitMulti != null)
+ {
+ OnSubmitMulti(this, new SubmitMultiEventArgs((SmppSubmitMulti)response));
+ }
+ else
+ {
+ //default a response
+ SmppSubmitMultiResp pdu = new SmppSubmitMultiResp();
+ pdu.SequenceNumber = response.SequenceNumber;
+ pdu.CommandStatus = 0;
+
+ SendPdu(pdu);
+ }
+ }
+ else if(response is SmppSubmitMultiResp)
+ {
+ if(OnSubmitMultiResp != null)
+ {
+ OnSubmitMultiResp(this, new SubmitMultiRespEventArgs((SmppSubmitMultiResp)response));
+ }
+ }
+ }
+
+ ///
+ /// Initializes the SMPPCommunicator with some default values.
+ ///
+ private void InitCommunicator()
+ {
+ Port = 9999;
+ BindType = SmppBind.BindingType.BindAsTransceiver;
+ Host = "localhost";
+ NpiType = Pdu.NpiType.ISDN;
+ TonType = Pdu.TonType.International;
+ Version = SmppBind.SmppVersionType.Version3_4;
+ AddressRange = null;
+ Password = null;
+ SystemId = null;
+ SystemType = null;
+ EnquireLinkInterval = 0;
+ SleepTimeAfterSocketFailure = 10;
+ }
+ #endregion private methods
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ protected void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ }
+ #endregion
+
+ ///
+ /// Disposes of this component. Called by the framework; do not call it
+ /// directly.
+ ///
+ /// This is set to false during garbage collection but
+ /// true during a disposal.
+ protected override void Dispose(bool disposing)
+ {
+ if(disposing)
+ {
+ if(components != null)
+ {
+ components.Dispose();
+ }
+ }
+
+ try
+ {
+ if(!_SentUnbindPacket)
+ Unbind();
+ }
+ catch
+ {
+ //drop it on the floor
+ }
+ base.Dispose(disposing);
+ }
+ }
+}
diff --git a/Utility/DestinationAddress.cs b/Utility/DestinationAddress.cs
new file mode 100644
index 0000000..1956c28
--- /dev/null
+++ b/Utility/DestinationAddress.cs
@@ -0,0 +1,258 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Marker/utility class to define destination addresses for the submit_multi.
+ ///
+ public sealed class DestinationAddress
+ {
+ private Pdu.TonType _DestinationAddressTon = Pdu.TonType.International;
+ private Pdu.NpiType _DestinationAddressNpi = Pdu.NpiType.ISDN;
+ private string _DestinationAddress = string.Empty;
+ private string _DistributionList = string.Empty;
+ private bool _IsDistributionList = false;
+
+ #region properties
+
+ ///
+ /// Type of number for destination SME.
+ ///
+ public Pdu.TonType DestinationAddressTon
+ {
+ get
+ {
+ return _DestinationAddressTon;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator for destination SME
+ ///
+ public Pdu.NpiType DestinationAddressNpi
+ {
+ get
+ {
+ return _DestinationAddressNpi;
+ }
+ }
+
+ ///
+ /// Destination Address of destination SME
+ ///
+ public string DestAddress
+ {
+ get
+ {
+ return _DestinationAddress;
+ }
+ }
+
+ ///
+ /// Distribution list of destination address
+ ///
+ public string DistributionList
+ {
+ get
+ {
+ return _DistributionList;
+ }
+ }
+
+ ///
+ /// Set to true if this DestinationAddress is a DistributionList.
+ ///
+ public bool IsDistributionList
+ {
+ get
+ {
+ return _IsDistributionList;
+ }
+ }
+
+ #endregion properties
+
+ ///
+ /// Creates an DestinationAddress address. This will trim down the address given to
+ /// it for use in future operations.
+ ///
+ /// The bytes of the response.
+ public DestinationAddress(ref byte[] address)
+ {
+ if(address[0] == 0x01)
+ {
+ _IsDistributionList = false;
+ }
+ else if(address[0] == 0x02)
+ {
+ _IsDistributionList = true;
+ }
+ else
+ {
+ throw new ApplicationException("Unable to determine type of destination address");
+ }
+
+ if(!IsDistributionList)
+ {
+ _DestinationAddressTon = (Pdu.TonType)address[1];
+ _DestinationAddressNpi = (Pdu.NpiType)address[2];
+ _DestinationAddress = SmppStringUtil.GetCStringFromBody(ref address, 3);
+//
+// long length = address.Length - 4;
+// byte[] newRemainder = new byte[length];
+// Array.Copy(address, 4, newRemainder, 0, length);
+// //and change the reference
+// address = newRemainder;
+// newRemainder = null;
+ }
+ else
+ {
+ _DistributionList = SmppStringUtil.GetCStringFromBody(ref address, 1);
+//
+// long length = address.Length - 4;
+// byte[] newRemainder = new byte[length];
+// Array.Copy(address, 4, newRemainder, 0, length);
+// //and change the reference
+// address = newRemainder;
+// newRemainder = null;
+ }
+ }
+
+ ///
+ /// Creates a new DestinationAddress.
+ ///
+ /// Type of number for destination SME.
+ /// Numbering Plan Indicator for destination SME
+ /// Destination Address of destination SME
+ public DestinationAddress(
+ Pdu.TonType destinationAddressTon,
+ Pdu.NpiType destinationAddressNpi,
+ string destinationAdress)
+ {
+ if(destinationAdress == null || destinationAdress.Length > 20)
+ {
+ throw new ArgumentException(
+ "Destination Adress must be 20 characters or less.");
+ }
+
+ _IsDistributionList = false;
+
+ this._DestinationAddressTon = destinationAddressTon;
+ this._DestinationAddressNpi = destinationAddressNpi;
+ this._DestinationAddress = destinationAdress;
+ }
+
+ ///
+ /// Creates a new DestinationAddress.
+ ///
+ /// Distribution list of destination address
+ public DestinationAddress(string distributionList)
+ {
+ if(distributionList == null || distributionList.Length > 20)
+ {
+ throw new ArgumentException(
+ "distribution list must be 20 characters or less.");
+ }
+
+ _IsDistributionList = true;
+
+ this._DistributionList = distributionList;
+ }
+
+ ///
+ /// Clones this DestinationAddress.
+ ///
+ /// The cloned object.
+ public object Clone()
+ {
+ DestinationAddress temp = null;
+
+ if(!this.IsDistributionList)
+ {
+ temp = new DestinationAddress(
+ _DestinationAddressTon, _DestinationAddressNpi, _DestinationAddress);
+ }
+ else
+ {
+ temp = new DestinationAddress(_DistributionList);
+ }
+
+ temp._IsDistributionList = this.IsDistributionList;
+
+ return temp;
+ }
+
+ ///
+ /// Checks to see if two UnsuccessAddresses are equal.
+ ///
+ /// The UnsuccessAddresses to check
+ /// true if obj and this are equal
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (this.GetType() != obj.GetType())
+ {
+ return false;
+ }
+
+ DestinationAddress da = (DestinationAddress) obj;
+
+ if(!da.IsDistributionList)
+ {
+ // value member check
+ return
+ _DestinationAddressTon.Equals(da._DestinationAddressTon) &&
+ _DestinationAddressNpi.Equals(da._DestinationAddressNpi) &&
+ _DestinationAddress.Equals(da._DestinationAddress);
+ }
+ else
+ {
+ return _DistributionList.Equals(da._DistributionList);
+ }
+ }
+
+ ///
+ /// Gets the hash code for this object.
+ ///
+ ///
+ public override int GetHashCode()
+ {
+ int hashCode = 0;
+
+ if(!this.IsDistributionList)
+ {
+ hashCode ^= this.DestAddress.GetHashCode();
+ hashCode ^= this.DestinationAddressNpi.GetHashCode();
+ hashCode ^= this.DestinationAddressTon.GetHashCode();
+ }
+ else
+ {
+ hashCode ^= this.DistributionList.GetHashCode();
+ }
+
+ return hashCode;
+ }
+ }
+}
diff --git a/Utility/PduFactory.cs b/Utility/PduFactory.cs
new file mode 100644
index 0000000..fbd5478
--- /dev/null
+++ b/Utility/PduFactory.cs
@@ -0,0 +1,152 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using RoaminSMPP;
+using RoaminSMPP.Packet;
+using RoaminSMPP.Packet.Request;
+using RoaminSMPP.Packet.Response;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Takes incoming packets from an input stream and generates
+ /// PDUs based on the command field.
+ ///
+ public class PduFactory
+ {
+ ///
+ /// Constructor.
+ ///
+ public PduFactory()
+ {
+ }
+
+ ///
+ /// Factory method to generate the PDU.
+ ///
+ /// The SMSC response.
+ /// The PDU.
+ public Queue GetPduQueue(byte[] incomingPDUs)
+ {
+ Queue packetQueue = new Queue();
+ //get the first packet
+ byte[] response = null;
+ Pdu packet = null;
+ int newLength = 0;
+ //this needs to start at zero
+ uint CommandLength = 0;
+
+ //look for multiple PDUs in the response
+ while(incomingPDUs.Length > 0)
+ {
+ //determine if we have another response PDU after this one
+ newLength =(int)(incomingPDUs.Length - CommandLength);
+ //could be empty data or it could be a PDU
+ if(newLength > 0)
+ {
+ //get the next PDU
+ response = Pdu.TrimResponsePdu(incomingPDUs);
+ //there could be none...
+ if(response.Length > 0)
+ {
+ //get the command length and command ID
+ CommandLength = Pdu.DecodeCommandLength(response);
+ //trim the packet down so we can look for more PDUs
+ long length = incomingPDUs.Length - CommandLength;
+ byte[] newRemainder = new byte[length];
+ Array.Copy(incomingPDUs, CommandLength, newRemainder, 0, length);
+ incomingPDUs = newRemainder;
+ newRemainder = null;
+ if(CommandLength > 0)
+ {
+ //process
+ packet = GetPDU(response);
+ if(packet != null)
+ packetQueue.Enqueue(packet);
+ }
+ }
+ else
+ {
+ //kill it off and return
+ incomingPDUs = new Byte[0];
+ }
+ }
+ }
+
+ return packetQueue;
+ }
+
+ ///
+ /// Gets a single PDU based on the response bytes.
+ ///
+ /// The SMSC response.
+ /// The PDU corresponding to the bytes.
+ private Pdu GetPDU(byte[] response)
+ {
+ Pdu.CommandIdType commandID = Pdu.DecodeCommandId(response);
+ Pdu packet;
+ switch(commandID)
+ {
+ case Pdu.CommandIdType.alert_notification:
+ packet = new SmppAlertNotification(response);
+ break;
+ case Pdu.CommandIdType.bind_receiver_resp:
+ case Pdu.CommandIdType.bind_transceiver_resp:
+ case Pdu.CommandIdType.bind_transmitter_resp:
+ packet = new SmppBindResp(response);
+ break;
+ case Pdu.CommandIdType.cancel_sm_resp:
+ packet = new SmppCancelSmResp(response);
+ break;
+ case Pdu.CommandIdType.data_sm_resp:
+ packet = new SmppDataSmResp(response);
+ break;
+ case Pdu.CommandIdType.deliver_sm:
+ packet = new SmppDeliverSm(response);
+ break;
+ case Pdu.CommandIdType.enquire_link_resp:
+ packet = new SmppEnquireLinkResp(response);
+ break;
+ case Pdu.CommandIdType.outbind:
+ packet = new SmppOutbind(response);
+ break;
+ case Pdu.CommandIdType.query_sm_resp:
+ packet = new SmppQuerySmResp(response);
+ break;
+ case Pdu.CommandIdType.replace_sm_resp:
+ packet = new SmppReplaceSmResp(response);
+ break;
+ case Pdu.CommandIdType.submit_multi_resp:
+ packet = new SmppSubmitMultiResp(response);
+ break;
+ case Pdu.CommandIdType.submit_sm_resp:
+ packet = new SmppSubmitSmResp(response);
+ break;
+ case Pdu.CommandIdType.unbind_resp:
+ packet = new SmppUnbindResp(response);
+ break;
+ default:
+ packet = null;
+ break;
+ }
+
+ return packet;
+ }
+ }
+}
diff --git a/Utility/PduUtil.cs b/Utility/PduUtil.cs
new file mode 100644
index 0000000..398f18e
--- /dev/null
+++ b/Utility/PduUtil.cs
@@ -0,0 +1,255 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Holds common functionality for requests.
+ ///
+ public class PduUtil
+ {
+ #region constants
+
+ private const int SUBADDRESS_MIN = 2;
+ private const int SUBADDRESS_MAX = 23;
+
+ #endregion constants
+ ///
+ /// Do not instantiate
+ ///
+ private PduUtil()
+ {
+ }
+
+ ///
+ /// Inserts the short message into the PDU ArrayList.
+ ///
+ /// The PDU to put the short message into.
+ /// The short message to insert.
+ /// The length of the short message.
+ public static byte InsertShortMessage(ArrayList pdu, object ShortMessage)
+ {
+ byte[] msg;
+
+ if(ShortMessage == null)
+ {
+ msg = new Byte[]{0x00};
+ }
+ else if(ShortMessage is string)
+ {
+ msg = Encoding.ASCII.GetBytes((string)ShortMessage);
+ }
+ else if(ShortMessage is byte[])
+ {
+ msg =(byte[])ShortMessage;
+ }
+ else
+ {
+ throw new ArgumentException("Short Message must be a string or byte array.");
+ }
+ // if(msg.Length >= MessageLcd2.SHORT_MESSAGE_LIMIT)
+ // throw new ArgumentException(
+ // "Short message cannot be longer than " +
+ // MessageLcd2.SHORT_MESSAGE_LIMIT + " octets.");
+
+ byte SmLength = (byte)msg.Length;
+ pdu.Add(SmLength);
+ pdu.AddRange(msg);
+
+ return SmLength;
+ }
+
+ ///
+ /// Takes the given PDU and inserts a receipted message ID into the TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetReceiptedMessageId(Pdu pdu, string val)
+ {
+ const int MAX_RECEIPTED_ID_LEN = 65;
+ if(val == null)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.receipted_message_id, string.Empty);
+ }
+ else if(val.Length <= MAX_RECEIPTED_ID_LEN)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.receipted_message_id, val);
+ }
+ else
+ {
+ throw new ArgumentException(
+ "receipted_message_id must have length 1-" + MAX_RECEIPTED_ID_LEN);
+ }
+ }
+
+ ///
+ /// Takes the given PDU and inserts a network error code into the TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetNetworkErrorCode(Pdu pdu, string val)
+ {
+ const int ERR_CODE_LEN = 3;
+ if(val == null || val.Length != ERR_CODE_LEN)
+ {
+ throw new ArgumentException("network_error_code must have length " + ERR_CODE_LEN);
+ }
+ else
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.network_error_code,val);
+ }
+ }
+
+ ///
+ /// Takes the given PDU and inserts ITS session info into the TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetItsSessionInfo(Pdu pdu, string val)
+ {
+ const int MAX_ITS = 16;
+
+ if(val == null)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.its_session_info, string.Empty);
+ }
+ else if(val.Length == MAX_ITS)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.its_session_info, val);
+ }
+ else
+ {
+ throw new ArgumentException("its_session_info must have length " + MAX_ITS);
+ }
+ }
+
+ ///
+ /// Takes the given PDU and inserts a destination subaddress into the TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetDestSubaddress(Pdu pdu, string val)
+ {
+ if(val.Length >= SUBADDRESS_MIN && val.Length <= SUBADDRESS_MAX)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.dest_subaddress, val);
+ }
+ else
+ {
+ throw new ArgumentException(
+ "Destination subaddress must be between " + SUBADDRESS_MIN +
+ " and " + SUBADDRESS_MAX + " characters.");
+ }
+ }
+
+ ///
+ /// Takes the given PDU and inserts a source subaddress into the TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetSourceSubaddress(Pdu pdu, string val)
+ {
+ if(val.Length >= SUBADDRESS_MIN && val.Length <= SUBADDRESS_MAX)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.source_subaddress, val);
+ }
+ else
+ {
+ throw new ArgumentException(
+ "Source subaddress must be between " + SUBADDRESS_MIN +
+ " and " + SUBADDRESS_MAX + " characters.");
+ }
+ }
+
+ ///
+ /// Takes the given PDU and inserts a callback number into the TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetCallbackNum(Pdu pdu, string val)
+ {
+ const int CALLBACK_NUM_MIN = 4;
+ const int CALLBACK_NUM_MAX = 19;
+ if(val.Length >= CALLBACK_NUM_MIN && val.Length <= CALLBACK_NUM_MAX)
+ {
+ pdu.SetOptionalParamString(
+ (ushort)Pdu.OptionalParamCodes.callback_num, val);
+ }
+ else
+ {
+ throw new ArgumentException(
+ "callback_num size must be between " + CALLBACK_NUM_MIN +
+ " and " + CALLBACK_NUM_MAX + " characters.");
+ }
+ }
+
+ ///
+ /// Takes the given PDU and inserts a message payload into its TLV table.
+ ///
+ /// The PDU to operate on.
+ /// The value to insert.
+ public static void SetMessagePayload(Pdu pdu, object val)
+ {
+ if(val != null)
+ {
+ byte[] encodedValue;
+ if(val is string)
+ {
+ encodedValue = Encoding.ASCII.GetBytes((string)val);
+ }
+ else if(val is byte[])
+ {
+ encodedValue =(byte[])val;
+ }
+ else
+ {
+ throw new ArgumentException("Message Payload must be a string or byte array.");
+ }
+
+ const int MAX_PAYLOAD_LENGTH = 64000;
+ if(encodedValue.Length < MAX_PAYLOAD_LENGTH)
+ {
+ pdu.SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.message_payload, encodedValue);
+ }
+ else
+ {
+ throw new ArgumentException(
+ "Message Payload must be " + MAX_PAYLOAD_LENGTH + " characters or less in size.");
+ }
+ }
+ else
+ {
+ pdu.SetOptionalParamBytes(
+ (ushort)Pdu.OptionalParamCodes.message_payload, new byte[]{0});
+ }
+ }
+ }
+}
diff --git a/Utility/SmppStringUtil.cs b/Utility/SmppStringUtil.cs
new file mode 100644
index 0000000..322ee48
--- /dev/null
+++ b/Utility/SmppStringUtil.cs
@@ -0,0 +1,178 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+
+using System;
+using System.Text;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Catchall utility class for dealing with strings in SMPP packets.
+ ///
+ public class SmppStringUtil
+ {
+ ///
+ /// Do not instantiate.
+ ///
+ private SmppStringUtil()
+ {
+ }
+
+ ///
+ /// Gets the next string from the given byte array. Note: this
+ /// method also trims off the string from the byte array, so that it can be easily
+ /// used in subsequent operations. You have to know the string length; this will not
+ /// look for a null character(as it is meant to be used with non-null terminated
+ /// strings).
+ ///
+ /// The byte array to pull the string from.
+ /// This should not contain extraneous data.
+ /// The index to start getting the string from.
+ /// Usually zero.
+ /// The index to end at. The character at
+ /// this index will not be included.
+ /// The string retrieved.
+ public static string GetStringFromBody(ref byte[] remainder, int startIndex, int endIndex)
+ {
+ string result;
+
+ //make sure we aren't trying to read non-command
+ //data
+ if(endIndex <= remainder.Length)
+ {
+ result = System.Text.Encoding.ASCII.GetString(remainder, startIndex, endIndex - startIndex);
+ }
+ else
+ {
+ result = string.Empty;
+ }
+
+ //now trim down the remainder-no null character
+ long length = remainder.Length - endIndex;
+ if(length >= 0)
+ {
+ byte[] newRemainder = new byte[length];
+ Array.Copy(remainder, endIndex, newRemainder, 0, length);
+ remainder = newRemainder;
+ newRemainder = null;
+ }
+
+ return result;
+ }
+
+ ///
+ /// Gets the next null-terminated string from the given byte array. Note: this
+ /// method also trims off the string(including the null character)from the
+ /// byte array, so that it can be easily used in subsequent operations.
+ /// This is equivalent to GetCStringFromBody(ref remainder, 0).
+ ///
+ /// The byte array to
+ /// pull the string from. This should not
+ /// contain extraneous data.
+ /// The string retrieved.
+ public static string GetCStringFromBody(ref byte[] remainder)
+ {
+ return GetCStringFromBody(ref remainder, 0);
+ }
+
+ ///
+ /// Gets the next null-terminated string from the given byte array. Note: this
+ /// method also trims off the string(including the null character)from the
+ /// byte array, so that it can be easily used in subsequent operations.
+ ///
+ /// The byte array to
+ /// pull the string from. This should not
+ /// contain extraneous data.
+ /// The index to start getting the string from.
+ /// Usually zero.
+ /// The string retrieved.
+ public static string GetCStringFromBody(ref byte[] remainder, int startIndex)
+ {
+ int i;
+
+ //find where the null character(end of string)is
+ //this stops ON the null character
+ for(i = startIndex; i < remainder.Length && remainder[i] != 0x00; i++)
+ {
+ ;
+ }
+
+ return GetCStringFromBody(ref remainder, startIndex, i);
+ }
+
+ ///
+ /// Gets the next null-terminated string from the given byte array. Note: this
+ /// method also trims off the string from the byte array, so that it can be easily used
+ /// in subsequent operations.
+ ///
+ /// The byte array to pull the string from.
+ /// This should not contain extraneous data.
+ /// The index to start getting the string from.
+ /// Usually zero.
+ /// The index to end at. The character at
+ /// this index will not be included.
+ /// The string retrieved.
+ public static string GetCStringFromBody(ref byte[] remainder, int startIndex, int endIndex)
+ {
+ string result;
+
+ //make sure we aren't trying to read non-command
+ //data
+ if(endIndex <= remainder.Length)
+ {
+ result = Encoding.ASCII.GetString(remainder, startIndex, endIndex - startIndex);
+ }
+ else
+ {
+ result = string.Empty;
+ }
+
+ //now trim down the remainder-chop off the null character as well
+ long length = remainder.Length - endIndex - 1;
+ if(length >= 0)
+ {
+ byte[] newRemainder = new byte[length];
+ Array.Copy(remainder, endIndex + 1, newRemainder, 0, length);
+ remainder = newRemainder;
+ newRemainder = null;
+ }
+
+ return result;
+ }
+
+ ///
+ /// Copies the data from the source array, appending a null character to the end.
+ /// This really only has a use for creating null terminated arrays that represent
+ /// strings.
+ ///
+ /// The source array to copy from.
+ ///
+ public static byte[] ArrayCopyWithNull(byte[] source)
+ {
+ byte[] temp = new byte[source.Length + 1];
+ for(int i = 0; i < source.Length; i++)
+ {
+ temp[i] = source[i];
+ }
+ //append the null
+ temp[temp.Length - 1] =(byte)0x00;
+
+ return temp;
+ }
+ }
+}
diff --git a/Utility/TlvTable.cs b/Utility/TlvTable.cs
new file mode 100644
index 0000000..6a04b08
--- /dev/null
+++ b/Utility/TlvTable.cs
@@ -0,0 +1,288 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using System.Collections;
+using System.Net;
+using System.Text;
+using System.Diagnostics;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Tag, length, value table for SMPP PDUs. The methods in this class assume
+ /// that the tag passed in is already in network byte order.
+ ///
+ public class TlvTable
+ {
+ private Hashtable tlvTable;
+
+ ///
+ /// Creates a TLV table.
+ ///
+ public TlvTable()
+ {
+ tlvTable = new Hashtable();
+ tlvTable = Hashtable.Synchronized(tlvTable);
+ }
+
+ ///
+ /// Converts the TLV byte array data into the Hashtable. This will check if
+ /// the passed in data is null or is an empty array so you don't need to
+ /// check it before calling this method. This is equivalent to
+ /// TranslateTlvDataIntoTable(tlvData, 0).
+ ///
+ /// The bytes of TLVs.
+ public void TranslateTlvDataIntoTable(byte[] tlvData)
+ {
+ TranslateTlvDataIntoTable(tlvData, 0);
+ }
+
+ ///
+ /// Converts the TLV byte array data into the Hashtable. This will check if
+ /// the passed in data is null or is an empty array so you don't need to check
+ /// it before calling this method.
+ ///
+ /// The bytes of TLVs.
+ /// The index of the byte array to start at. This is here
+ /// because in some instances you may not want to start at the
+ /// beginning.
+ public void TranslateTlvDataIntoTable(byte[] tlvData, Int32 index)
+ {
+ if(tlvData == null || tlvData.Length <= 0)
+ {
+ return;
+ }
+
+ //go through and decode the TLVs
+ while(index < tlvData.Length)
+ {
+ InjectTlv(tlvData, ref index);
+ }
+ }
+
+ ///
+ /// Using the given tlvData byte array and the given starting index, inserts
+ /// the tag and value(as a byte array)into the hashtable. Note that the
+ /// tlvData needs to be in the SMPP v3.4 format(tag, length, value). This
+ /// assumes that the tag and length (from the tlvData array) are in network byte order.
+ ///
+ /// Note also that this will advance the index by the TLV data length so that
+ /// it may be used for consecutive reads from the same array.
+ ///
+ /// The TLV data as a byte array.
+ /// The index of the array to start reading from.
+ private void InjectTlv(byte[] tlvData, ref Int32 index)
+ {
+ byte[] temp = new byte[2];
+ temp[0] = tlvData[index];
+ temp[1] = tlvData[index + 1];
+
+ #if DEBUG
+ Console.WriteLine("tag bytes " + temp[0].ToString("X").PadLeft(2, '0') +
+ temp[1].ToString("X").PadLeft(2, '0'));
+ #endif
+
+ UInt16 tag = BitConverter.ToUInt16(temp, 0);
+ index += 2;
+ temp[0] = tlvData[index];
+ temp[1] = tlvData[index + 1];
+ UInt16 length = UnsignedNumConverter.SwapByteOrdering(BitConverter.ToUInt16(temp, 0));
+ index += 2;
+ //decode the value
+
+ #if DEBUG
+ Console.WriteLine("TLV Length " + length);
+ #endif
+
+ ArrayList data = new ArrayList(length);
+
+ int total = index + length;
+ for(int k = index;(k < index + length)&& k < tlvData.Length; k++)
+ {
+ data.Add(tlvData[k]);
+ }
+
+ data.TrimToSize();
+ //add the values to the hashtable
+ tlvTable.Add(tag, data.ToArray(typeof(byte)));
+ //set it up for the next run
+ index += length;
+ }
+
+ ///
+ /// Gets the optional parameter bytes associated with the given tag.
+ ///
+ /// The tag in TLV.
+ /// The optional parameter bytes, null if not found.
+ /// Thrown if the tag cannot be found.
+ public byte[] GetOptionalParamBytes(UInt16 tag)
+ {
+ object val = tlvTable[tag];
+ if(val == null)
+ {
+ throw new ApplicationException("TLV tag " + tag + " not found.");
+ }
+ else
+ {
+ byte[] bVal = (byte[])val;
+ #if DEBUG
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Getting tag " + UnsignedNumConverter.SwapByteOrdering(tag));
+ sb.Append("\nValue: ");
+
+ for(int i = 0; i < bVal.Length; i++)
+ {
+ sb.Append(bVal[i]);
+ sb.Append(" ");
+ }
+
+ Console.WriteLine(sb);
+
+ #endif
+ return bVal;
+ }
+ }
+
+ ///
+ /// Gets the optional parameter string associated with the given tag.
+ ///
+ /// The tag in TLV.
+ /// The optional parameter string, the empty string if not found.
+ ///
+ /// Thrown if the tag cannot be found.
+ public string GetOptionalParamString(UInt16 tag)
+ {
+ byte[] val = GetOptionalParamBytes(tag);
+
+ return Encoding.ASCII.GetString(val);
+ }
+
+ ///
+ /// Sets the given TLV(as a byte array)into the table. This ignores null values.
+ ///
+ /// The tag in TLV.
+ /// The value of this TLV.
+ public void SetOptionalParamBytes(UInt16 tag, byte[] val)
+ {
+ #if DEBUG
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Setting tag " + UnsignedNumConverter.SwapByteOrdering(tag));
+ sb.Append("\nValue: ");
+
+ for(int i = 0; i < val.Length; i++)
+ {
+ sb.Append(val[i]);
+ sb.Append(" ");
+ }
+
+ Console.WriteLine(sb);
+
+ #endif
+ if(val != null)
+ {
+ if(val.Length > UInt16.MaxValue)
+ {
+ throw new Exception("Optional parameter value for " + tag + " is too large.");
+ }
+ tlvTable.Add(tag, val);
+ }
+ }
+
+ ///
+ /// Sets the given TLV(as a string)into the table. This ignores
+ /// null values.
+ ///
+ /// The tag in TLV.
+ /// The value of this TLV.
+ public void SetOptionalParamString(UInt16 tag, string val)
+ {
+ if(val != null)
+ {
+ SetOptionalParamBytes(tag, Encoding.ASCII.GetBytes(val));
+ }
+ }
+
+ ///
+ /// Allows the updating of TLV values.
+ ///
+ /// The tag in TLV.
+ /// The value of this TLV.
+ /// Thrown if the tag cannot be found.
+ public void UpdateOptionalParamBytes(UInt16 tag, byte[] val)
+ {
+ object obj = tlvTable[tag];
+
+ if(obj != null)
+ {
+ tlvTable[tag] = val;
+ }
+ else
+ {
+ throw new ApplicationException("TLV tag " + tag + " not found");
+ }
+ }
+
+ ///
+ /// Allows the updating of TLV values.
+ ///
+ /// The tag in TLV.
+ /// The value of this TLV.
+ public void UpdateOptionalParamString(UInt16 tag, string val)
+ {
+ UpdateOptionalParamBytes(tag, Encoding.ASCII.GetBytes(val));
+ }
+
+ ///
+ /// Iterates through the hashtable, gathering the tag, length, and
+ /// value as it goes. For each entry, it encodes the TLV into a byte
+ /// array. It is assumed that the tags and length are already in network
+ /// byte order.
+ ///
+ /// An ArrayList consisting of byte array entries, each of which
+ /// is a TLV. Returns an empty ArrayList if the TLV table is empty.
+ public ArrayList GenerateByteEncodedTlv()
+ {
+ if(tlvTable == null || tlvTable.Count <= 0)
+ {
+ return new ArrayList(0);
+ }
+
+ ArrayList tlvs = new ArrayList();
+ IDictionaryEnumerator iterator = tlvTable.GetEnumerator();
+ ArrayList elem = new ArrayList();
+ while(iterator.MoveNext())
+ {
+ elem.Clear();
+ //tag-2 bytes
+ elem.AddRange(BitConverter.GetBytes(((UInt16)iterator.Key)));
+ //length-2 bytes
+ byte[] nextVal = (byte[])iterator.Value;
+ UInt16 tlvLength = UnsignedNumConverter.SwapByteOrdering(((UInt16)(nextVal).Length));
+ elem.AddRange(BitConverter.GetBytes(tlvLength));
+ //value
+ elem.AddRange(nextVal);
+ elem.TrimToSize();
+ //copy it over to a byte array
+ tlvs.Add(elem.ToArray(typeof(byte)));
+ }
+ tlvs.TrimToSize();
+
+ return tlvs;
+ }
+ }
+}
diff --git a/Utility/UnsignedNumConverter.cs b/Utility/UnsignedNumConverter.cs
new file mode 100644
index 0000000..31e7f1c
--- /dev/null
+++ b/Utility/UnsignedNumConverter.cs
@@ -0,0 +1,66 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Utility class to do big-endian to little endian conversions and the like.
+ /// This is for unsigned numbers only; use the IPAddress class for signed values.
+ ///
+ public sealed class UnsignedNumConverter
+ {
+ ///
+ /// Do not instantiate.
+ ///
+ private UnsignedNumConverter()
+ {
+ }
+
+ ///
+ /// Converts from big-endian to little endian and vice versa.
+ ///
+ /// The value to swap.
+ /// The byte-swapped value, 0 if val < 0
+ public static UInt32 SwapByteOrdering(UInt32 val)
+ {
+ if(val < 0)
+ return 0;
+ return((val << 24)& 0xFF000000)+((val << 8)& 0x00FF0000)+
+ ((val >> 8)& 0x0000FF00)+((val >> 24)& 0x000000FF);
+ }
+
+ ///
+ /// Converts from big-endian to little endian and vice versa. Don't use
+ /// for negative integers; it has not been tested for that.
+ ///
+ /// The value to swap.
+ /// The byte-swapped value, 0 if val < 0
+ public static UInt16 SwapByteOrdering(UInt16 val)
+ {
+ if(val < 0)
+ {
+ return 0;
+ }
+
+ UInt16 newVal = (UInt16)(((val << 8)& 0xFF00)+((val >> 8)& 0x00FF));
+
+ return newVal;
+ }
+ }
+}
diff --git a/Utility/UnsuccessAddress.cs b/Utility/UnsuccessAddress.cs
new file mode 100644
index 0000000..1fa349d
--- /dev/null
+++ b/Utility/UnsuccessAddress.cs
@@ -0,0 +1,181 @@
+/* RoaminSMPP: SMPP communication library
+ * Copyright (C) 2004, 2005 Christopher M. Bouzek
+ *
+ * This file is part of RoaminSMPP.
+ *
+ * RoaminSMPP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * RoaminSMPP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lessert General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RoaminSMPP. If not, see .
+ */
+using System;
+using RoaminSMPP.Packet;
+
+namespace RoaminSMPP.Utility
+{
+ ///
+ /// Defines an Unsuccess address, used with the response to submit_multi.
+ /// The spec states that both SME addresses and distribution lists can be
+ /// used here, but it only defines for the SME address, so that is all that
+ /// this will handle.
+ ///
+ public class UnsuccessAddress
+ {
+ private Pdu.TonType _DestinationAddressTon;
+ private Pdu.NpiType _DestinationAddressNpi;
+ private string _DestinationAddress;
+ private uint _ErrorStatusCode;
+
+ #region properties
+
+ ///
+ /// Type of number for destination SME.
+ ///
+ public Pdu.TonType DestinationAddressTon
+ {
+ get
+ {
+ return _DestinationAddressTon;
+ }
+ }
+
+ ///
+ /// Numbering Plan Indicator for destination SME
+ ///
+ public Pdu.NpiType DestinationAddressNpi
+ {
+ get
+ {
+ return _DestinationAddressNpi;
+ }
+ }
+
+ ///
+ /// Destination Address of destination SME
+ ///
+ public string DestinationAddress
+ {
+ get
+ {
+ return _DestinationAddress;
+ }
+ }
+
+ ///
+ /// Indicates the success or failure of the submit_multi request to this
+ /// SME address.
+ ///
+ public UInt32 ErrorStatusCode
+ {
+ get
+ {
+ return _ErrorStatusCode;
+ }
+ }
+
+ #endregion properties
+
+ ///
+ /// Creates an Unsuccess address. This will trim down the address given to
+ /// it for use in future operations.
+ ///
+ /// The bytes of the response.
+ public UnsuccessAddress(ref byte[] address)
+ {
+ _DestinationAddressTon = (Pdu.TonType)address[0];
+ _DestinationAddressNpi = (Pdu.NpiType)address[1];
+ _DestinationAddress = SmppStringUtil.GetCStringFromBody(ref address, 2);
+ //convert error status to host order
+ _ErrorStatusCode = UnsignedNumConverter.SwapByteOrdering(
+ BitConverter.ToUInt32(address, 0));
+ //now we have to trim off four octets to account for the status code
+ long length = address.Length - 4;
+ byte[] newRemainder = new byte[length];
+ Array.Copy(address, 4, newRemainder, 0, length);
+ //and change the reference
+ address = newRemainder;
+ newRemainder = null;
+ }
+
+ ///
+ /// Creates a new UnsuccessAdress.
+ ///
+ /// Type of number for destination SME.
+ /// Numbering Plan Indicator for destination SME
+ /// Destination Address of destination SME
+ /// Indicates the success or failure of the submit_multi request
+ /// to this SME address.
+ public UnsuccessAddress(
+ Pdu.TonType destinationAddressTon,
+ Pdu.NpiType destinationAddressNpi,
+ string destinationAdress,
+ UInt32 ErrorStatusCode)
+ {
+ this._DestinationAddressTon = destinationAddressTon;
+ this._DestinationAddressNpi = destinationAddressNpi;
+ this._DestinationAddress = destinationAdress;
+ this._ErrorStatusCode = ErrorStatusCode;
+ }
+
+ ///
+ /// Clones this UnsuccessAddress.
+ ///
+ /// The cloned object.
+ public object Clone()
+ {
+ UnsuccessAddress temp = new UnsuccessAddress(
+ _DestinationAddressTon, _DestinationAddressNpi, _DestinationAddress, _ErrorStatusCode);
+ return temp;
+ }
+
+ ///
+ /// Checks to see if two UnsuccessAddresses are equal.
+ ///
+ /// The UnsuccessAddresses to check
+ /// true if obj and this are equal
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (this.GetType() != obj.GetType())
+ {
+ return false;
+ }
+
+ // safe because of the GetType check
+ UnsuccessAddress us = (UnsuccessAddress) obj;
+
+ // value member check
+ return
+ _DestinationAddressTon.Equals(us._DestinationAddressTon) &&
+ _DestinationAddressNpi.Equals(us._DestinationAddressNpi) &&
+ _DestinationAddress.Equals(us._DestinationAddress) &&
+ _ErrorStatusCode.Equals(us._ErrorStatusCode);
+ }
+
+ ///
+ /// Gets the hash code for this object.
+ ///
+ ///
+ public override int GetHashCode()
+ {
+ int hashCode = 0;
+ hashCode ^= this.DestinationAddress.GetHashCode();
+ hashCode ^= this.DestinationAddressNpi.GetHashCode();
+ hashCode ^= this.DestinationAddressTon.GetHashCode();
+ hashCode ^= this.ErrorStatusCode.GetHashCode();
+
+ return hashCode;
+ }
+ }
+}
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..1d4c65c
--- /dev/null
+++ b/version.txt
@@ -0,0 +1,3 @@
+major=1
+minor=0
+name=flux