Installation

Unpacking the archive will create a directory smppcxx/src that contains all source files.

Building

All code is standard C++, therefore it should build using any modern C++ compiler. To start you off there are two make files included
(i) Makefile.nmake that should be called by the nmake make for building on windows.
(ii) Makefile.gmake that should be called by gmake make for compiling on unix type systems.

Usage

There is a sample program in the directory smppcxx/sample_app that shows usage of the most commonly used PDUs, it is a good idea to look at that code. It is also useful to look at the library header files for the respective PDUs, e.g. bind_transceiver.hpp, etc.

Basic types

The following basic types are used through out the library. (Currently they are basic typedefs)
Smpp::Char; // 8 bit signed (typedef char - used in a C-Octet string)
Smpp::String; // C-Octet string (typedef std::basic_string)
Smpp::Uint8; // Octet (unsigned) (typedef unsigned char)
Smpp::Uint16; // 16 bit unsigned integer (typedef unsigned short)
Smpp::Uint32; // 32 bit unsigned integer(typedef unsigned int)

Protocol Data Units (PDUs) representation

Each SMPP PDU is represented as a C++ class, e.g. BindTransceiver, SubmitSm, EnquireLink, etc. All classes are defined inside the Smpp namespace.
Therefore to construct a PDU just declare an instance of the specific PDU class, e.g.
Smpp::SubmitSm pdu;
All PDUs have the same set of constructors
(i) Default constructor, in the above example a basic submit_sm PDU is created; the command_id is set to 0x00000004, the sequence_number set to 0x00000001 and the command_length set to the minimum length of a submit_sm (33 octets).
(ii) Constructor that takes the sequence_number followed by all the mandatory parameters in the order listed in the spec (in the case of response PDUs the command_status is also required before the sequence_number.
(iii) Contructor that takes an octet stream as an argument. The length of the octet stream is determined internally by looking at the first 4 bytes (the command_length parameter).

Mandatory parameters

All mandatory parameters have a specific class, in most cases these are just wrappers that are used to performed basic verification of the data, e.g. string length.

The parameters (with the exceptions of address and short message) can be assigned to and from their underlining basic type e.g.
std::string s = "xyz";
Smpp::ServiceType servtype(s);
Smpp::String s1 = servtype;

Smpp::DataCoding datacoding;
datacoding = 2;
int i = datacoding;

The mandatory parameters can be set using operations with a similar name to the parameter descriptions in the SMPP specification, e.g.
pdu.service_type("ABCDE");
Similarly the parameter value can be accessed by
const Smpp::ServiceType& s = pdu.service_type();

Address parameter

The address parameters (source_addr, destination_addr, etc) are of type Smpp::SmeAddress. It is composed of a TON, NPI and address (Smpp::Ton, Smpp::Npi and Smpp::Address respectively). The address len defaults to 21 characters but can be changed by setting the len argument. The constructors are
Smpp::SmeAddress();
Smpp::SmeAddress(const Smpp::Ton& ton, const Smpp::Npi& npi, const Smpp::Address& addr, size_t len);
Smpp::SmeAddress(const Smpp::Address& addr, size_t len);

The individual parameters can be accessed using the member functions
const Smpp::Ton& ton() const;
const Smpp::Npi& npi() const;
const Smpp::Address& address() const;
size_t length() const;

Short message parameter

The sm_length and short_message parameters are encapsulated in an Smpp::ShortMessage which can be constructed using
/* Octet array and length */
Smpp::ShortMessage(Smpp::Uint8* data, Smpp::Uint8 length);
/* C++ String (std::string) */
Smpp::ShortMessage(Smpp::String& data);
/* NULL terminated C string */
Smpp::ShortMessage(Smpp::Char* data);

Internally the data is stored as a std::vector<Smpp::Uint8> and can be accessed as follows
// a constance reference
const std::vector<Smpp::Uint8>& sm = pdu.short_message();

// therefore you can do the following
pdu.short_message().size();
pdu.short_message().begin();
pdu.short_message().end();

Tag, Length, Value (TLV) parameters

TLVs (or optional parameters) are added to a PDU using an insert member function. An Smpp::Tlv can be created stand alone and then inserted using the insert_tlv(const Smpp::Tlv&) member function.
A stand alone SMPP TLV can be created using a tag, length and value.
Smpp::Tlv(Smpp::Uint16& tag, Smpp::Uint16& length, Smpp::Uint8* value);
This can then be inserted into a PDU using the member function
void insert_tlv( const Smpp::Tlv& tlv );
e.g.
Smpp::SubmitSm pdu;
Smpp::Tlv tlv(Smpp::Tlv::message_payload, 5, "Hello");
pdu.insert_tlv(tlv);

There are also special TLV member functions for the different value types
void insert_8bit_tlv(Smpp::Uint16 tag, const Smpp::Uint8 value);
void insert_16bit_tlv(Smpp::Uint16 tag, const Smpp::Uint16 value);
void insert_32bit_tlv(Smpp::Uint16 tag, const Smpp::Uint32 value);
void insert_string_tlv(Smpp::Uint16 tag, const Smpp::String& value);
void insert_array_tlv(Smpp::Uint16 tag, Smpp::Uint16 length, const Smpp::Uint8* value);

There are three ways of accessing TLVs. A user should not modify the TLVs returned as it may corrupt the entire PDU.
(i) By accessing the entire list (internally the TLVs are stored in a std::list<const Tlv*> list which is typedef'd to TlvList.
const TlvList& tlv_list() const;
(ii) If it is possible to have more than one occurance of a TLV use the member function
const TlvList find_tlv_list(Uint16 tag) const;
(iii) By accessing an individual element
const Tlv* find_tlv(Uint16 tag) const;

If in the first two cases there are no TLVs then the list will have zero elements, in the third case a 0 is returned.

A TLV can also be removed by
void remove_tlv(Uint16 tag);