/server

Usage Overview

Communication Outline

The following diagram shows functions and events flow in communication flow:

Communication outline diagram

Create Instance

Server class requires one instance to handle multiple client connections:


  SMSCserverSMPP serverSMPP = new smscs.SMPP.SMSCserverSMPP();
  

Start Listening for Connections

There are two methods for server functionality maintenance: InitializeServer and FinalizeServer. After calling InitializeServer server starts to listen for incoming connections on desired port and/or IP address:


//
// Start server listening on all TCP/IP interfaces on port 2048
//
int result = serverSMPP.smppInitializeServer("", 2048, "");

if(result == 0) {
  // Server initialized correctly, awaiting client connections
} else {
  // Error initializing server
}

Client Connection Notification

The example below shows OnTcpConnected event which reports incoming connection on TCP/IP level. In the event code information like client's IP address (e.RemoteHost) and/or port (e.RemotePort) can be examined and the connection can either be accepted using tcpAcceptConnection method or rejected with tcpCloseConnection.

this.serverSMPP.OnTcpConnected +=
  new smscs.tcpConnectedEvent(
    this.serverSMPP_OnTcpConnected);

// [...]

//
// Event fired when client connects on TCP/IP level
//
private void serverSMPP_OnTcpConnected(object sender,
  smscs.tcpConnectedEventArgs e)
{
  serverSMPP.tcpAcceptConnection(e.ClientID);
}

Above example shows how to accept incoming connections unconditionally.

Client Login Notification

After connecting on TCP/IP level client initializes session on SMSC protocol level. SMPP protocol login is reported via OnSmppLoginReveived event. Inside event code series of login parameters can be analyzed and then decision can be made whether to accept or reject user login. Information that can be examined is account name (e.SystemID), password (e.Password), bind mode (transceiver, transmitter or receiver contained in e.BindMode) etc.

If client is rejected the connection should also be closed using tcpCloseConnection.


this.serverSMPP.OnSmppLoginReceived +=
  new smscs.SMPP.smppLoginReceivedEvent(
    this.serverSMPP_OnSmppLoginReceived);

// [...]

//
// Event fired on login (bind) message receive
//
private void serverSMPP_OnSmppLoginReceived(object sender,
  smscs.SMPP.smppLoginReceivedEventArgs e)
{
  serverSMPP.smppSendLoginResponse(e.ClientID,
    e.SequenceNumber, e.BindMode, 0, "tops-smsc");
}

Message Received Notification

Event OnSmppSubmitMessageReceived is fired when client submits a message.


this.serverSMPP.OnSmppSubmitMessageCompleted +=
  new smscs.SMPP.smppSubmitMessageCompletedEvent(
    this.serverSMPP_OnSmppSubmitMessageCompleted);
this.serverSMPP.OnSmppSubmitMessageReceived +=
  new smscs.SMPP.smppSubmitMessageReceivedEvent(
    this.serverSMPP_OnSmppSubmitMessageReceived);

// [...]

private void serverSMPP_OnSmppSubmitMessageCompleted(
  object sender,
  smscs.SMPP.smppSubmitMessageCompletedEventArgs e)
{
  // Message received here is completed if it was a long/multipart
  // message or if no completing is necessary.
}

//
// Event fired when message to submit is received
// (send_sm or submit_multi) from client
//
private void serverSMPP_OnSmppSubmitMessageReceived(
  object sender,
  smscs.SMPP.smppSubmitMessageReceivedEventArgs e)
{
  // Here every basic partial message is reported to the user.

  //
  // Use some method to generate unique message ID
  //
  string MessageID = getMessageID();

  bool MultipleDestinations = (e.Destination.IndexOf(";") != -1);

  serverSMPP.smppSendSubmitMessageResponse(e.ClientID,
    e.SequenceNumber, 0, MessageID, MultipleDestinations);
}

After the message is received server has to confirm it's reception to the client using smppSendSubmitMessageResponse method.

Deliver Message

To send a message to the client (which is referred to as "deliver" to distinguish between message "submit" from the client to the server) smppSendDeliverMessage method should be used:


//
// To deliver message to the client use
// smppSendDeliverMessage method
//
int result = serverSMPP.smppSendDeliverMessage(clientID,
  sequenceNumber++, "48999123456", 1, 1, "48999654321", 1, 1,
  "Hello from SMSC Server Library", EncodingEnum.et7BitText,
  "", 0, "", "");

if(result == 0) {
  // Message delivery started correctly
} else {
  // Error delivering message
}

Deliver Status Report

Method to deliver Status Report is smppSendDeliverStatusReport as shown below:


//
// To deliver status report to the client use
// smppSendDeliverStatusReport method
//
int result = serverSMPP.smppSendDeliverStatusReport(clientID,
  sequenceNumber++, "48999123456", 1, 1, "48999654321", 1, 1,
  smppReportTypeEnum.rtFinal, "", "", 1, 1, DateTime.Now,
  DateTime.Now, smppMessageStateEnum.msDelivered, 0, "", "");

if(result == 0) {
  // Status report delivery started correctly
} else {
  // Error delivering message
}

Handling Client Response

A confirmation from the client to any of the above two methods would be delivered using OnSmppDeliverResponseReceived event:


this.serverSMPP.OnSmppDeliverResponseReceived +=
  new smscs.SMPP.smppDeliverResponseReceivedEvent(
    this.serverSMPP_OnSmppDeliverResponseReceived);

//
// Event fired when response to message or status response
// (deliver_sm) has been received from the client party
//
private void serverSMPP_OnSmppDeliverResponseReceived(
  object sender,
  smscs.SMPP.smppDeliverResponseReceivedEventArgs e)
{

}

Answer can be matched with submitted data via e.SequenceNumber parameter.

Client Logout Notification

Logout operation is reported via OnSmppLogoutReceived event. Logout operation is not always required in real communication - clients often simply drop the connection without sending logout message. Some SMSC access protocols do not have this operation at all.

To gently terminate the connection a response should be sent to the client using smppSendLogoutResponse method. Then after giving some time to let client receive and process logout response if the connection is not closed by the client it may be closed using tcpCloseConnection method.


this.serverSMPP.OnSmppLogoutReceived +=
  new smscs.SMPP.smppLogoutReceivedEvent(
    this.serverSMPP_OnSmppLogoutReceived);

// [...]

//
// Event fired on logout (unbind) message receive
//
private void serverSMPP_OnSmppLogoutReceived(object sender,
  smscs.SMPP.smppLogoutReceivedEventArgs e)
{
  serverSMPP.smppSendLogoutResponse(e.ClientID,
    e.SequenceNumber, 0);
}

Client Disconnect Notification

When client connection is disconnected it is reported by OnTcpDisconnected event. The event does not require any action in response and is used to remove connection from internal structures:


this.serverSMPP.OnTcpDisconnected +=
  new smscs.tcpDisconnectedEvent(
    this.serverSMPP_OnTcpDisconnected);

// [...]

//
// Event fired when client disconnects on TCP/IP level
//
private void serverSMPP_OnTcpDisconnected(object sender,
  smscs.tcpDisconnectedEventArgs e)
{

}

Stop Listening for Connections

Call FinalizeServer to make server stop listening for connections. This however does not disconnect any previously established connection:


//
// Make server stop listening for incoming connections
//
serverSMPP.smppFinalizeServer();

// No longer awaiting client connections

Other Protocols

All the above examples use SMPP protocol prefix part of the name. To translate the examples to other protocol this part has to be changed to ucp or cimd2 respectively. For example:

smppInitializeServer = ucpInitializeServer

See Also

SMSCserverSMPP, SMSCserverUCP, SMSCserverCIMD2