From 6ca0fef6c88b44aa07a338e3db1f085dec0095ba Mon Sep 17 00:00:00 2001 From: Fatemeh Pardakhti Date: Sun, 26 May 2024 15:20:47 +0330 Subject: [PATCH 1/6] change data codings --- Test/SmppTestClient/Program.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Test/SmppTestClient/Program.cs b/Test/SmppTestClient/Program.cs index bbe20e4..8e1504e 100644 --- a/Test/SmppTestClient/Program.cs +++ b/Test/SmppTestClient/Program.cs @@ -99,11 +99,13 @@ private static void SendMessage(ESMEManager connectionManager, string command) // This is set in the Submit PDU to the SMSC // If you are responding to a received message, make this the same as the received message - DataCodings submitDataCoding = DataCodings.Default; + // Adjusted to ucs2 for supporting Arabic character. + DataCodings submitDataCoding = DataCodings.UCS2; // Use this to encode the message // We need to know the actual encoding. - DataCodings encodeDataCoding = DataCodings.ASCII; + // Adjusted to ucs2 for supporting Arabic character. + DataCodings encodeDataCoding = DataCodings.UCS2; // There is a default encoding set for each connection. This is used if the encodeDataCoding is Default From 37dcf5a57a994a10a9418ae0e3806b71c688c187 Mon Sep 17 00:00:00 2001 From: Fatemeh Pardakhti Date: Sat, 1 Jun 2024 14:24:56 +0330 Subject: [PATCH 2/6] adding input option in testing --- Test/SmppTestClient/Program.cs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Test/SmppTestClient/Program.cs b/Test/SmppTestClient/Program.cs index 8e1504e..fe12b29 100644 --- a/Test/SmppTestClient/Program.cs +++ b/Test/SmppTestClient/Program.cs @@ -49,7 +49,27 @@ static void Main(string[] args) Console.Write("\n#>"); - string? command = Console.ReadLine(); + Console.WriteLine("Select language for testing: "); + Console.WriteLine("1. English"); + Console.WriteLine("2. Arabic"); + + string choice = Console.ReadLine(); + string? command; + + switch (choice) + { + case "1": + command = "send 12223334444 Hello"; + break; + case "2": + command = "send 12223334444 سلام علیکم"; + break; + default: + Console.WriteLine("Invalid choice, defaulting to English."); + command = "send 12223334444 Hello"; + break; + } + if (command == null || command.Length == 0) continue; From 7c6fd24dfcba0420b75f65edf5f380316656c18f Mon Sep 17 00:00:00 2001 From: Fatemeh Pardakhti Date: Wed, 19 Aug 2026 16:51:28 +0330 Subject: [PATCH 3/6] add overload of SendMessage method for getting destTon, destNpi as input arguments --- Source/SmppClient/ESMEConnection.cs | 100 +++ Source/SmppClient/ESMEManager.cs | 1256 ++++++++++++++------------- 2 files changed, 749 insertions(+), 607 deletions(-) diff --git a/Source/SmppClient/ESMEConnection.cs b/Source/SmppClient/ESMEConnection.cs index c89c6a0..8233dbd 100644 --- a/Source/SmppClient/ESMEConnection.cs +++ b/Source/SmppClient/ESMEConnection.cs @@ -754,6 +754,106 @@ public int SendMessage(string phoneNumber, string serviceType, Ton destinationTo return retVal; } + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 0 - Successful / 1 - Failed / 2 - Not Connected + public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destinationTon, Npi destinationNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) + { + int retVal = 1; + + submitSm = null; + submitSmResp = null; + + try + { + if (Client.Status != ConnectionStatus.Bound) + { + WriteLog("ESMEConnection : SendMessage : Warning : Not Connected To The SMPP Server"); + return 2; + } + + // The message to send + string sendMessage = null; + + // Do we need to cut the message down + if (encodeDataCoding == DataCodings.UCS2) + { + // UCS2 only supports 140 bytes + if (message.Length > 70) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : WARNING : Truncating UCS2 message to 70 characters."); + + // The default is Unicode so truncate the message + sendMessage = message.Substring(0, 70); + } + } + else if (message.Length > 160) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : WARNING : Truncating Default message to 160 characters."); + sendMessage = message.Substring(0, 160); + } + + // Prepare the message, I have made sure there is only ever one message + // with the trunacting above + submitSm = Client.PrepareSubmit( + SubmitMode.ShortMessage, + serviceType, + (byte)sourceTon, + (byte)sourceNpi, + ShortLongCode, + (byte)destinationTon, + (byte)destinationNpi, + phoneNumber, + submitDataCoding, + encodeDataCoding, + (sendMessage == null) ? message : sendMessage); + + // Send the message + submitSmResp = Client.Submit(submitSm); + + // Log the send call + WriteLog("ESMEConnection : SendMessage : Send : Sequence[{0}] Phone[{1}] Status[{2}]", submitSmResp.Sequence, phoneNumber, submitSmResp.Status); + + // Success + if (submitSmResp.Status == CommandStatus.ESME_ROK) + { + retVal = 0; + } + // Bind Failed + else if (submitSmResp.Status == CommandStatus.ESME_RBINDFAIL) + { + WriteLog("ESMEConnection : SendMessage : ERROR : Bind Failed"); + + retVal = 2; + } + // Isn't successful + else + { + WriteLog("ESMEConnection : SendMessage : ERROR : Failed For Unknown Reason"); + + retVal = 3; + } + + } + catch (Exception ex) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : ERROR : {0}", ex.ToString()); + retVal = 1; + } + + return retVal; + } + /// Called to send the message /// /// diff --git a/Source/SmppClient/ESMEManager.cs b/Source/SmppClient/ESMEManager.cs index 418a660..31ff00f 100644 --- a/Source/SmppClient/ESMEManager.cs +++ b/Source/SmppClient/ESMEManager.cs @@ -1,613 +1,655 @@ -#region Namespaces - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; - -#endregion - -namespace BSN.SmppClient -{ - /// Provides ESME (Extended Short Message Entity) Management - public class ESMEManager : IDisposable +#region Namespaces + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +#endregion + +namespace BSN.SmppClient +{ + /// Provides ESME (Extended Short Message Entity) Management + public class ESMEManager : IDisposable { - #region Delegates + #region Delegates + + /// Called when a message is received + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public delegate void RECEIVED_MESSAGE_HANDLER(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message); + + /// Called when a submit message is acknowledged + /// + /// + public delegate void RECEIVED_GENERICNACK_HANDLER(string logKey, int sequence); + + /// Called when a submit message is acknowledged + /// + /// + /// + public delegate void SUBMIT_MESSAGE_HANDLER(string logKey, int sequence, string messageId); + + /// Called when a query message is responded + /// + /// + /// + /// + /// + /// + public delegate void QUERY_MESSAGE_HANDLER(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode); + + /// Called to log an event + /// + /// + /// + /// + public delegate void LOG_EVENT_HANDLER(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message); + + /// Called when a connection event occurrs + /// + /// + /// + public delegate void CONNECTION_EVENT_HANDLER(string logKey, ConnectionEventTypes connectionEventType, string message); + + /// Called to capture the details of the pdu + /// + /// + /// + /// + /// External Id + public delegate Guid? PDU_DETAILS_EVENT_HANDLER(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details); + + #endregion + + #region Private Properties + + /// Flag that determines whether this instance has been disposed or not yet + protected bool Disposed = false; + + /// The logKey for writing logs to the correct files + private string LogKey = string.Empty; + + /// The short/long code being managed + private string ShortLongCode = null; + + + /// A user supplied method to call when a message is received + private RECEIVED_MESSAGE_HANDLER ReceivedMessageHandler = null; + + /// A user supplied method to call when a generic nack is received + private RECEIVED_GENERICNACK_HANDLER ReceivedGenericNackHandler = null; + + /// A user supplied method to call when a submit is ascknowledged + private SUBMIT_MESSAGE_HANDLER SubmitMessageHandler = null; + + /// A user supplied method to call when a query is responded + private QUERY_MESSAGE_HANDLER QueryMessageHandler = null; + + /// A user supplied method to call to write logs + private LOG_EVENT_HANDLER LogEventHandler = null; + + /// A user supplied method to call for connection events + private CONNECTION_EVENT_HANDLER ConnectionEventHandler = null; + + /// A user supplied method to call for pdu detail data + private PDU_DETAILS_EVENT_HANDLER PduDetailsEventHandler = null; + + + /// A list of receiver connections + private List Receivers = new List(); + + /// A dictionary of transmitter connections + private Dictionary Transmitters = new Dictionary(); + + /// A pointer to the next transmitter to use + private int NextTransmitter = 1; + + #endregion + + #region Constructor + + /// Contructor + /// + /// + /// + /// + /// + /// + /// + /// + /// + public ESMEManager(string logKey, string shortLongCode, + CONNECTION_EVENT_HANDLER connectionEventHandler, RECEIVED_MESSAGE_HANDLER receivedMessageHandler, + RECEIVED_GENERICNACK_HANDLER receivedGenericNackHandler, SUBMIT_MESSAGE_HANDLER submitMessageHandler, + QUERY_MESSAGE_HANDLER queryMessageHandler, LOG_EVENT_HANDLER logEventHandler, + PDU_DETAILS_EVENT_HANDLER pduDetailsEventHandler) + { + LogKey = logKey; + ShortLongCode = shortLongCode; + + ConnectionEventHandler = connectionEventHandler; + ReceivedMessageHandler = receivedMessageHandler; + ReceivedGenericNackHandler = receivedGenericNackHandler; + SubmitMessageHandler = submitMessageHandler; + QueryMessageHandler = queryMessageHandler; + LogEventHandler = logEventHandler; + PduDetailsEventHandler = pduDetailsEventHandler; + } + + /// Dispose + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// Dispose + /// + protected void Dispose(bool disposing) + { + WriteLog("ESMEManager : Dispose : Started"); + + if (!Disposed) + { + // Note disposing has begun + Disposed = true; + + try + { + WriteLog("ESMEManager : Dispose : Info : Disconnect the receiver connections"); + + foreach (ESMEConnection smppConnection in Receivers) + { + smppConnection.Dispose(); + } + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); + } + + try + { + WriteLog("ESMEManager : Dispose : Info : Disconnect the transmitter connections"); + + foreach (ESMEConnection smppConnection in Transmitters.Values) + { + smppConnection.Dispose(); + } + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); + } + } + + WriteLog("ESMEManager : Dispose : Completed"); + } + + #endregion + + #region Log Methods + + /// Called to write out to the log + /// + private void WriteLog(string message) + { + LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, message); + } + + /// Called to write out to the log + /// + /// + private void WriteLog(string message, params object[] logValues) + { + LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, string.Format(message, logValues)); + } + + /// Called to write out to the log + /// + /// + private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message) + { + LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, message); + } + + /// Called to write out to the log + /// + /// + /// + private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message, params object[] logValues) + { + LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, string.Format(message, logValues)); + } + + #endregion + + #region Event Methods + + /// Called when a connection event is fired + /// + /// + /// + public void ConnectionEventConnectionHandler(string logKey, ConnectionEventTypes connectionEventType, string message) + { + if (ConnectionEventHandler != null) + { + ConnectionEventHandler(logKey, connectionEventType, message); + } + } + + /// Called when a message is received on a connection + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void ReceivedMessageConnectionHandler(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message) + { + if (ReceivedMessageHandler != null) + { + ReceivedMessageHandler(logKey, messageType, serviceType, sourceTon, sourceNpi, shortLongCode, dateReceived, phoneNumber, dataCoding, message); + } + } + + /// A user supplied method to call when a generic nack is received + /// + /// + public void ReceivedGenericNackConnectionHandler(string logKey, int sequence) + { + if (ReceivedGenericNackHandler != null) + { + ReceivedGenericNackHandler(logKey, sequence); + } + } + + /// Called when a submit message is acknowledged + /// + /// + /// + public void SubmitMessageConnectionHandler(string logKey, int sequence, string messageId) + { + if (SubmitMessageHandler != null) + { + SubmitMessageHandler(logKey, sequence, messageId); + } + } + + /// Called when a query message is responded + /// + /// + /// + /// + /// + /// + public void QueryMessageConnectionHandler(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode) + { + if (QueryMessageHandler != null) + { + QueryMessageHandler(logKey, sequence, messageId, finalDate, messageState, errorCode); + } + } + + /// Called to log an event + /// + /// + /// + /// + public void LogEventConnectionHandler(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message) + { + if (LogEventHandler != null) + { + LogEventHandler(logEventNotificationType, logKey, shortLongCode, message); + } + } + + /// Called when a pdu details are available + /// + /// + /// + /// + /// External Id + private Guid? PduDetailsConnectionHandler(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details) + { + Guid? externalId = null; + + if (PduDetailsEventHandler != null) + { + externalId = PduDetailsEventHandler(logKey, pduDirectionType, pdu, details); + } + + return externalId; + } + + #endregion + + #region Connection Management Methods - /// Called when a message is received + /// Called to add a transceiver connection + /// + /// + /// + /// + /// /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public delegate void RECEIVED_MESSAGE_HANDLER(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message); - - /// Called when a submit message is acknowledged - /// - /// - public delegate void RECEIVED_GENERICNACK_HANDLER(string logKey, int sequence); - - /// Called when a submit message is acknowledged - /// - /// - /// - public delegate void SUBMIT_MESSAGE_HANDLER(string logKey, int sequence, string messageId); - - /// Called when a query message is responded - /// - /// - /// - /// - /// - /// - public delegate void QUERY_MESSAGE_HANDLER(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode); - - /// Called to log an event - /// - /// - /// - /// - public delegate void LOG_EVENT_HANDLER(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message); - - /// Called when a connection event occurrs - /// - /// - /// - public delegate void CONNECTION_EVENT_HANDLER(string logKey, ConnectionEventTypes connectionEventType, string message); - - /// Called to capture the details of the pdu - /// - /// - /// - /// - /// External Id - public delegate Guid? PDU_DETAILS_EVENT_HANDLER(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details); - - #endregion - - #region Private Properties - - /// Flag that determines whether this instance has been disposed or not yet - protected bool Disposed = false; - - /// The logKey for writing logs to the correct files - private string LogKey = string.Empty; - - /// The short/long code being managed - private string ShortLongCode = null; - - - /// A user supplied method to call when a message is received - private RECEIVED_MESSAGE_HANDLER ReceivedMessageHandler = null; - - /// A user supplied method to call when a generic nack is received - private RECEIVED_GENERICNACK_HANDLER ReceivedGenericNackHandler = null; - - /// A user supplied method to call when a submit is ascknowledged - private SUBMIT_MESSAGE_HANDLER SubmitMessageHandler = null; - - /// A user supplied method to call when a query is responded - private QUERY_MESSAGE_HANDLER QueryMessageHandler = null; - - /// A user supplied method to call to write logs - private LOG_EVENT_HANDLER LogEventHandler = null; - - /// A user supplied method to call for connection events - private CONNECTION_EVENT_HANDLER ConnectionEventHandler = null; - - /// A user supplied method to call for pdu detail data - private PDU_DETAILS_EVENT_HANDLER PduDetailsEventHandler = null; - - - /// A list of receiver connections - private List Receivers = new List(); - - /// A dictionary of transmitter connections - private Dictionary Transmitters = new Dictionary(); - - /// A pointer to the next transmitter to use - private int NextTransmitter = 1; - - #endregion - - #region Constructor - - /// Contructor - /// - /// - /// - /// - /// - /// - /// - /// - /// - public ESMEManager(string logKey, string shortLongCode, - CONNECTION_EVENT_HANDLER connectionEventHandler, RECEIVED_MESSAGE_HANDLER receivedMessageHandler, - RECEIVED_GENERICNACK_HANDLER receivedGenericNackHandler, SUBMIT_MESSAGE_HANDLER submitMessageHandler, - QUERY_MESSAGE_HANDLER queryMessageHandler, LOG_EVENT_HANDLER logEventHandler, - PDU_DETAILS_EVENT_HANDLER pduDetailsEventHandler) - { - LogKey = logKey; - ShortLongCode = shortLongCode; - - ConnectionEventHandler = connectionEventHandler; - ReceivedMessageHandler = receivedMessageHandler; - ReceivedGenericNackHandler = receivedGenericNackHandler; - SubmitMessageHandler = submitMessageHandler; - QueryMessageHandler = queryMessageHandler; - LogEventHandler = logEventHandler; - PduDetailsEventHandler = pduDetailsEventHandler; - } - - /// Dispose - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// Dispose - /// - protected void Dispose(bool disposing) - { - WriteLog("ESMEManager : Dispose : Started"); - - if (!Disposed) - { - // Note disposing has begun - Disposed = true; - - try - { - WriteLog("ESMEManager : Dispose : Info : Disconnect the receiver connections"); - - foreach (ESMEConnection smppConnection in Receivers) - { - smppConnection.Dispose(); - } - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); - } - - try - { - WriteLog("ESMEManager : Dispose : Info : Disconnect the transmitter connections"); - - foreach (ESMEConnection smppConnection in Transmitters.Values) - { - smppConnection.Dispose(); - } - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); - } - } - - WriteLog("ESMEManager : Dispose : Completed"); - } - - #endregion - - #region Log Methods - - /// Called to write out to the log - /// - private void WriteLog(string message) - { - LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, message); - } - - /// Called to write out to the log - /// - /// - private void WriteLog(string message, params object[] logValues) - { - LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, string.Format(message, logValues)); - } - - /// Called to write out to the log - /// - /// - private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message) - { - LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, message); - } - - /// Called to write out to the log - /// - /// - /// - private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message, params object[] logValues) - { - LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, string.Format(message, logValues)); - } - - #endregion - - #region Event Methods - - /// Called when a connection event is fired - /// - /// - /// - public void ConnectionEventConnectionHandler(string logKey, ConnectionEventTypes connectionEventType, string message) - { - if (ConnectionEventHandler != null) - { - ConnectionEventHandler(logKey, connectionEventType, message); - } + /// + private void AddTransceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) + { + lock (Receivers) + { + // Create the smppConnection object + ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transceiver, + host, port, userName, password, logKey, defaultEncoding, + new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), + new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), + new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), + new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), + new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), + new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), + new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); + + // Add the connection to both list + Transmitters.Add(connectionId, smppConnection); + } } - /// Called when a message is received on a connection + /// Called to add a receiver connection + /// + /// + /// + /// + /// /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public void ReceivedMessageConnectionHandler(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message) - { - if (ReceivedMessageHandler != null) - { - ReceivedMessageHandler(logKey, messageType, serviceType, sourceTon, sourceNpi, shortLongCode, dateReceived, phoneNumber, dataCoding, message); - } - } - - /// A user supplied method to call when a generic nack is received - /// - /// - public void ReceivedGenericNackConnectionHandler(string logKey, int sequence) - { - if (ReceivedGenericNackHandler != null) - { - ReceivedGenericNackHandler(logKey, sequence); - } - } - - /// Called when a submit message is acknowledged - /// - /// - /// - public void SubmitMessageConnectionHandler(string logKey, int sequence, string messageId) - { - if (SubmitMessageHandler != null) - { - SubmitMessageHandler(logKey, sequence, messageId); - } - } - - /// Called when a query message is responded - /// - /// - /// - /// - /// - /// - public void QueryMessageConnectionHandler(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode) - { - if (QueryMessageHandler != null) - { - QueryMessageHandler(logKey, sequence, messageId, finalDate, messageState, errorCode); - } - } - - /// Called to log an event - /// - /// - /// - /// - public void LogEventConnectionHandler(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message) - { - if (LogEventHandler != null) - { - LogEventHandler(logEventNotificationType, logKey, shortLongCode, message); - } - } - - /// Called when a pdu details are available - /// - /// - /// - /// - /// External Id - private Guid? PduDetailsConnectionHandler(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details) - { - Guid? externalId = null; - - if (PduDetailsEventHandler != null) - { - externalId = PduDetailsEventHandler(logKey, pduDirectionType, pdu, details); - } - - return externalId; - } - - #endregion - - #region Connection Management Methods - - /// Called to add a transceiver connection - /// - /// - /// - /// - /// - /// - /// - private void AddTransceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) - { - lock (Receivers) - { - // Create the smppConnection object - ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transceiver, - host, port, userName, password, logKey, defaultEncoding, - new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), - new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), - new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), - new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), - new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), - new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), - new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); - - // Add the connection to both list - Transmitters.Add(connectionId, smppConnection); - } - } - - /// Called to add a receiver connection - /// - /// - /// - /// - /// - /// - /// - private void AddReceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) - { - lock (Receivers) - { - // Create the smppConnection object - ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Receiver, - host, port, userName, password, logKey, defaultEncoding, - new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), - new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), - new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), - null, - new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), - new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), - new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); - - // Add the connection to the list - Receivers.Add(smppConnection); - } - } - - /// Called to add a transmitter connection - /// - /// - /// - /// - /// - /// - /// - private void AddTransmitterConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) - { - lock (Transmitters) - { - // Create the smppConnection object - ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transmitter, - host, port, userName, password, logKey, defaultEncoding, - new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), - null, - new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), - new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), - new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), - new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), - new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); - - // Add the connection to the list - Transmitters.Add(connectionId, smppConnection); - } - } - - /// Called to return the next transmitter for sending - /// SmppConnection - private ESMEConnection NextTransmitterConnection() - { - ESMEConnection smppConnection = null; - - int totalConnections = Transmitters.Count(); - - // We only want a bound connection. We will try them all - for (int connection = 0; connection < totalConnections; ++connection) - { - lock (Transmitters) - { - smppConnection = Transmitters[NextTransmitter]; - - if (++NextTransmitter > Transmitters.Count()) - { - NextTransmitter = 1; - } - - if (smppConnection.Status == ConnectionStatus.Bound) - { - break; - } - - smppConnection = null; - } - } - - return smppConnection; - } - - #endregion - - #region Public Methods - - /// Called to add connections - /// - /// - /// - /// - /// - /// - /// - /// - public void AddConnections(int howMany, ConnectionModes connectionMode, string host, int port, - string userName, string password, string logKey, DataCodings defaultEncoding) - { - WriteLog("ESMEManager : AddConnections : Started : HowMany[{0}] ConnectionMode[{1}] Host[{2}] Port[{3}] LogKey[{4}] DefaultEncoding[{5}]", howMany, connectionMode, host, port, logKey, defaultEncoding); - - for (int connection = 1; connection <= howMany; ++connection) - { - if (connectionMode == ConnectionModes.Transceiver) - { - AddTransceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); - } - else if (connectionMode == ConnectionModes.Receiver) - { - AddReceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); - } - else - { - AddTransmitterConnection(connection, host, port, userName, password, logKey, defaultEncoding); - } - } - } - - /// Called to send the message - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1 - Successful / 0 - Failed - public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) - { - int retVal = 0; - - submitSm = null; - submitSmResp = null; - - try - { - // Capture the next transmitter connection - ESMEConnection smppConnection = NextTransmitterConnection(); - - if (smppConnection == null) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); - - return 2; - } - - // Send the message - retVal = smppConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); - } - - return retVal; - } - - /// Called to send the message - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1 - Successful / 0 - Failed - public int SendMessageLarge(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out List submitSmList, out List submitSmRespList) - { - int retVal = 0; - - submitSmList = null; - submitSmRespList = null; - - try - { - // Capture the next transmitter connection - ESMEConnection smppConnection = NextTransmitterConnection(); - - if (smppConnection == null) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); - - return 2; - } - - // Send the message - retVal = smppConnection.SendMessageLarge(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSmList, out submitSmRespList); - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); - } - - return retVal; - } - - /// Called to send a query - /// - /// 1 - Successful / 0 - Failed - public QuerySm SendQuery(string messageId) - { - QuerySm querySm = null; - - try - { - // Capture the next transmitter connection - ESMEConnection smppConnection = NextTransmitterConnection(); - - if (smppConnection.Status != ConnectionStatus.Bound) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Connected To The SMPP Server"); - - return querySm; - } - - // Send the message - querySm = smppConnection.SendQuery(messageId); - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); - } - - return querySm; - } - - #endregion - } -} + /// + private void AddReceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) + { + lock (Receivers) + { + // Create the smppConnection object + ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Receiver, + host, port, userName, password, logKey, defaultEncoding, + new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), + new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), + new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), + null, + new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), + new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), + new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); + + // Add the connection to the list + Receivers.Add(smppConnection); + } + } + + /// Called to add a transmitter connection + /// + /// + /// + /// + /// + /// + /// + private void AddTransmitterConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) + { + lock (Transmitters) + { + // Create the smppConnection object + ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transmitter, + host, port, userName, password, logKey, defaultEncoding, + new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), + null, + new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), + new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), + new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), + new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), + new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); + + // Add the connection to the list + Transmitters.Add(connectionId, smppConnection); + } + } + + /// Called to return the next transmitter for sending + /// SmppConnection + private ESMEConnection NextTransmitterConnection() + { + ESMEConnection smppConnection = null; + + int totalConnections = Transmitters.Count(); + + // We only want a bound connection. We will try them all + for (int connection = 0; connection < totalConnections; ++connection) + { + lock (Transmitters) + { + smppConnection = Transmitters[NextTransmitter]; + + if (++NextTransmitter > Transmitters.Count()) + { + NextTransmitter = 1; + } + + if (smppConnection.Status == ConnectionStatus.Bound) + { + break; + } + + smppConnection = null; + } + } + + return smppConnection; + } + + #endregion + + #region Public Methods + + /// Called to add connections + /// + /// + /// + /// + /// + /// + /// + /// + public void AddConnections(int howMany, ConnectionModes connectionMode, string host, int port, + string userName, string password, string logKey, DataCodings defaultEncoding) + { + WriteLog("ESMEManager : AddConnections : Started : HowMany[{0}] ConnectionMode[{1}] Host[{2}] Port[{3}] LogKey[{4}] DefaultEncoding[{5}]", howMany, connectionMode, host, port, logKey, defaultEncoding); + + for (int connection = 1; connection <= howMany; ++connection) + { + if (connectionMode == ConnectionModes.Transceiver) + { + AddTransceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); + } + else if (connectionMode == ConnectionModes.Receiver) + { + AddReceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); + } + else + { + AddTransmitterConnection(connection, host, port, userName, password, logKey, defaultEncoding); + } + } + } + + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1 - Successful / 0 - Failed + public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) + { + int retVal = 0; + + submitSm = null; + submitSmResp = null; + + try + { + // Capture the next transmitter connection + ESMEConnection smppConnection = NextTransmitterConnection(); + + if (smppConnection == null) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); + + return 2; + } + + // Send the message + retVal = smppConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); + } + + return retVal; + } + + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1 - Successful / 0 - Failed + public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destTon, Npi destNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) + { + int retVal = 0; + + submitSm = null; + submitSmResp = null; + try + { + // Capture the next transmitter connection + ESMEConnection eSMEConnection = NextTransmitterConnection(); + + if (eSMEConnection == null) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); + + return 2; + } + + // Send the message + retVal = eSMEConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, destTon, destNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); + } + catch (Exception ex) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", ex.ToString()); + } + + return retVal; + } + + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1 - Successful / 0 - Failed + public int SendMessageLarge(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out List submitSmList, out List submitSmRespList) + { + int retVal = 0; + + submitSmList = null; + submitSmRespList = null; + + try + { + // Capture the next transmitter connection + ESMEConnection smppConnection = NextTransmitterConnection(); + + if (smppConnection == null) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); + + return 2; + } + + // Send the message + retVal = smppConnection.SendMessageLarge(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSmList, out submitSmRespList); + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); + } + + return retVal; + } + + /// Called to send a query + /// + /// 1 - Successful / 0 - Failed + public QuerySm SendQuery(string messageId) + { + QuerySm querySm = null; + + try + { + // Capture the next transmitter connection + ESMEConnection smppConnection = NextTransmitterConnection(); + + if (smppConnection.Status != ConnectionStatus.Bound) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Connected To The SMPP Server"); + + return querySm; + } + + // Send the message + querySm = smppConnection.SendQuery(messageId); + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); + } + + return querySm; + } + + #endregion + } +} From d0bb37b4dcd0e9f91d537c8a473f27cb47cd451d Mon Sep 17 00:00:00 2001 From: Fatemeh Pardakhti Date: Sat, 22 Aug 2026 10:12:32 +0330 Subject: [PATCH 4/6] Document description for type of failure --- Source/SmppClient/ESMEConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/SmppClient/ESMEConnection.cs b/Source/SmppClient/ESMEConnection.cs index 8233dbd..4197542 100644 --- a/Source/SmppClient/ESMEConnection.cs +++ b/Source/SmppClient/ESMEConnection.cs @@ -766,7 +766,7 @@ public int SendMessage(string phoneNumber, string serviceType, Ton destinationTo /// /// /// - /// 0 - Successful / 1 - Failed / 2 - Not Connected + /// 0 - Successful / 1 - Failed For Exception / 2 - Not Binded / 3 - Failed For Unknown Reason public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destinationTon, Npi destinationNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) { int retVal = 1; From 6cbcecb59487f426f5e18e2cb8133689220d9d56 Mon Sep 17 00:00:00 2001 From: Fatemeh Pardakhti Date: Sat, 22 Aug 2026 10:49:30 +0330 Subject: [PATCH 5/6] revert line ending to LF --- Source/SmppClient/ESMEConnection.cs | 200 ++-- Source/SmppClient/ESMEManager.cs | 1310 +++++++++++++-------------- 2 files changed, 755 insertions(+), 755 deletions(-) diff --git a/Source/SmppClient/ESMEConnection.cs b/Source/SmppClient/ESMEConnection.cs index 4197542..d241e13 100644 --- a/Source/SmppClient/ESMEConnection.cs +++ b/Source/SmppClient/ESMEConnection.cs @@ -12,11 +12,11 @@ namespace BSN.SmppClient { /// Manages a single ESME (Extended Short Message Entity) connection internal class ESMEConnection : IDisposable - { + { #region Delegates - + /// Called when a message is received - /// + /// /// /// /// @@ -754,104 +754,104 @@ public int SendMessage(string phoneNumber, string serviceType, Ton destinationTo return retVal; } - /// Called to send the message - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// /// 0 - Successful / 1 - Failed For Exception / 2 - Not Binded / 3 - Failed For Unknown Reason - public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destinationTon, Npi destinationNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) - { - int retVal = 1; - - submitSm = null; - submitSmResp = null; - - try - { - if (Client.Status != ConnectionStatus.Bound) - { - WriteLog("ESMEConnection : SendMessage : Warning : Not Connected To The SMPP Server"); - return 2; - } - - // The message to send - string sendMessage = null; - - // Do we need to cut the message down - if (encodeDataCoding == DataCodings.UCS2) - { - // UCS2 only supports 140 bytes - if (message.Length > 70) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : WARNING : Truncating UCS2 message to 70 characters."); - - // The default is Unicode so truncate the message - sendMessage = message.Substring(0, 70); - } - } - else if (message.Length > 160) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : WARNING : Truncating Default message to 160 characters."); - sendMessage = message.Substring(0, 160); - } - - // Prepare the message, I have made sure there is only ever one message - // with the trunacting above - submitSm = Client.PrepareSubmit( - SubmitMode.ShortMessage, - serviceType, - (byte)sourceTon, - (byte)sourceNpi, - ShortLongCode, - (byte)destinationTon, - (byte)destinationNpi, - phoneNumber, - submitDataCoding, - encodeDataCoding, - (sendMessage == null) ? message : sendMessage); - - // Send the message - submitSmResp = Client.Submit(submitSm); - - // Log the send call - WriteLog("ESMEConnection : SendMessage : Send : Sequence[{0}] Phone[{1}] Status[{2}]", submitSmResp.Sequence, phoneNumber, submitSmResp.Status); - - // Success - if (submitSmResp.Status == CommandStatus.ESME_ROK) - { - retVal = 0; - } - // Bind Failed - else if (submitSmResp.Status == CommandStatus.ESME_RBINDFAIL) - { - WriteLog("ESMEConnection : SendMessage : ERROR : Bind Failed"); - - retVal = 2; - } - // Isn't successful - else - { - WriteLog("ESMEConnection : SendMessage : ERROR : Failed For Unknown Reason"); - - retVal = 3; - } - - } - catch (Exception ex) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : ERROR : {0}", ex.ToString()); - retVal = 1; - } - - return retVal; + public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destinationTon, Npi destinationNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) + { + int retVal = 1; + + submitSm = null; + submitSmResp = null; + + try + { + if (Client.Status != ConnectionStatus.Bound) + { + WriteLog("ESMEConnection : SendMessage : Warning : Not Connected To The SMPP Server"); + return 2; + } + + // The message to send + string sendMessage = null; + + // Do we need to cut the message down + if (encodeDataCoding == DataCodings.UCS2) + { + // UCS2 only supports 140 bytes + if (message.Length > 70) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : WARNING : Truncating UCS2 message to 70 characters."); + + // The default is Unicode so truncate the message + sendMessage = message.Substring(0, 70); + } + } + else if (message.Length > 160) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : WARNING : Truncating Default message to 160 characters."); + sendMessage = message.Substring(0, 160); + } + + // Prepare the message, I have made sure there is only ever one message + // with the trunacting above + submitSm = Client.PrepareSubmit( + SubmitMode.ShortMessage, + serviceType, + (byte)sourceTon, + (byte)sourceNpi, + ShortLongCode, + (byte)destinationTon, + (byte)destinationNpi, + phoneNumber, + submitDataCoding, + encodeDataCoding, + (sendMessage == null) ? message : sendMessage); + + // Send the message + submitSmResp = Client.Submit(submitSm); + + // Log the send call + WriteLog("ESMEConnection : SendMessage : Send : Sequence[{0}] Phone[{1}] Status[{2}]", submitSmResp.Sequence, phoneNumber, submitSmResp.Status); + + // Success + if (submitSmResp.Status == CommandStatus.ESME_ROK) + { + retVal = 0; + } + // Bind Failed + else if (submitSmResp.Status == CommandStatus.ESME_RBINDFAIL) + { + WriteLog("ESMEConnection : SendMessage : ERROR : Bind Failed"); + + retVal = 2; + } + // Isn't successful + else + { + WriteLog("ESMEConnection : SendMessage : ERROR : Failed For Unknown Reason"); + + retVal = 3; + } + + } + catch (Exception ex) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEConnection : SendMessage : ERROR : {0}", ex.ToString()); + retVal = 1; + } + + return retVal; } /// Called to send the message diff --git a/Source/SmppClient/ESMEManager.cs b/Source/SmppClient/ESMEManager.cs index 31ff00f..82a00f8 100644 --- a/Source/SmppClient/ESMEManager.cs +++ b/Source/SmppClient/ESMEManager.cs @@ -1,655 +1,655 @@ -#region Namespaces - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; - -#endregion - -namespace BSN.SmppClient -{ - /// Provides ESME (Extended Short Message Entity) Management - public class ESMEManager : IDisposable - { - #region Delegates - - /// Called when a message is received - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public delegate void RECEIVED_MESSAGE_HANDLER(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message); - - /// Called when a submit message is acknowledged - /// - /// - public delegate void RECEIVED_GENERICNACK_HANDLER(string logKey, int sequence); - - /// Called when a submit message is acknowledged - /// - /// - /// - public delegate void SUBMIT_MESSAGE_HANDLER(string logKey, int sequence, string messageId); - - /// Called when a query message is responded - /// - /// - /// - /// - /// - /// - public delegate void QUERY_MESSAGE_HANDLER(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode); - - /// Called to log an event - /// - /// - /// - /// - public delegate void LOG_EVENT_HANDLER(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message); - - /// Called when a connection event occurrs - /// - /// - /// - public delegate void CONNECTION_EVENT_HANDLER(string logKey, ConnectionEventTypes connectionEventType, string message); - - /// Called to capture the details of the pdu - /// - /// - /// - /// - /// External Id - public delegate Guid? PDU_DETAILS_EVENT_HANDLER(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details); - - #endregion - - #region Private Properties - - /// Flag that determines whether this instance has been disposed or not yet - protected bool Disposed = false; - - /// The logKey for writing logs to the correct files - private string LogKey = string.Empty; - - /// The short/long code being managed - private string ShortLongCode = null; - - - /// A user supplied method to call when a message is received - private RECEIVED_MESSAGE_HANDLER ReceivedMessageHandler = null; - - /// A user supplied method to call when a generic nack is received - private RECEIVED_GENERICNACK_HANDLER ReceivedGenericNackHandler = null; - - /// A user supplied method to call when a submit is ascknowledged - private SUBMIT_MESSAGE_HANDLER SubmitMessageHandler = null; - - /// A user supplied method to call when a query is responded - private QUERY_MESSAGE_HANDLER QueryMessageHandler = null; - - /// A user supplied method to call to write logs - private LOG_EVENT_HANDLER LogEventHandler = null; - - /// A user supplied method to call for connection events - private CONNECTION_EVENT_HANDLER ConnectionEventHandler = null; - - /// A user supplied method to call for pdu detail data - private PDU_DETAILS_EVENT_HANDLER PduDetailsEventHandler = null; - - - /// A list of receiver connections - private List Receivers = new List(); - - /// A dictionary of transmitter connections - private Dictionary Transmitters = new Dictionary(); - - /// A pointer to the next transmitter to use - private int NextTransmitter = 1; - - #endregion - - #region Constructor - - /// Contructor - /// - /// - /// - /// - /// - /// - /// - /// - /// - public ESMEManager(string logKey, string shortLongCode, - CONNECTION_EVENT_HANDLER connectionEventHandler, RECEIVED_MESSAGE_HANDLER receivedMessageHandler, - RECEIVED_GENERICNACK_HANDLER receivedGenericNackHandler, SUBMIT_MESSAGE_HANDLER submitMessageHandler, - QUERY_MESSAGE_HANDLER queryMessageHandler, LOG_EVENT_HANDLER logEventHandler, - PDU_DETAILS_EVENT_HANDLER pduDetailsEventHandler) - { - LogKey = logKey; - ShortLongCode = shortLongCode; - - ConnectionEventHandler = connectionEventHandler; - ReceivedMessageHandler = receivedMessageHandler; - ReceivedGenericNackHandler = receivedGenericNackHandler; - SubmitMessageHandler = submitMessageHandler; - QueryMessageHandler = queryMessageHandler; - LogEventHandler = logEventHandler; - PduDetailsEventHandler = pduDetailsEventHandler; - } - - /// Dispose - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// Dispose - /// - protected void Dispose(bool disposing) - { - WriteLog("ESMEManager : Dispose : Started"); - - if (!Disposed) - { - // Note disposing has begun - Disposed = true; - - try - { - WriteLog("ESMEManager : Dispose : Info : Disconnect the receiver connections"); - - foreach (ESMEConnection smppConnection in Receivers) - { - smppConnection.Dispose(); - } - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); - } - - try - { - WriteLog("ESMEManager : Dispose : Info : Disconnect the transmitter connections"); - - foreach (ESMEConnection smppConnection in Transmitters.Values) - { - smppConnection.Dispose(); - } - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); - } - } - - WriteLog("ESMEManager : Dispose : Completed"); - } - - #endregion - - #region Log Methods - - /// Called to write out to the log - /// - private void WriteLog(string message) - { - LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, message); - } - - /// Called to write out to the log - /// - /// - private void WriteLog(string message, params object[] logValues) - { - LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, string.Format(message, logValues)); - } - - /// Called to write out to the log - /// - /// - private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message) - { - LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, message); - } - - /// Called to write out to the log - /// - /// - /// - private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message, params object[] logValues) - { - LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, string.Format(message, logValues)); - } - - #endregion - - #region Event Methods - - /// Called when a connection event is fired - /// - /// - /// - public void ConnectionEventConnectionHandler(string logKey, ConnectionEventTypes connectionEventType, string message) - { - if (ConnectionEventHandler != null) - { - ConnectionEventHandler(logKey, connectionEventType, message); - } - } - - /// Called when a message is received on a connection - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public void ReceivedMessageConnectionHandler(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message) - { - if (ReceivedMessageHandler != null) - { - ReceivedMessageHandler(logKey, messageType, serviceType, sourceTon, sourceNpi, shortLongCode, dateReceived, phoneNumber, dataCoding, message); - } - } - - /// A user supplied method to call when a generic nack is received - /// - /// - public void ReceivedGenericNackConnectionHandler(string logKey, int sequence) - { - if (ReceivedGenericNackHandler != null) - { - ReceivedGenericNackHandler(logKey, sequence); - } - } - - /// Called when a submit message is acknowledged - /// - /// - /// - public void SubmitMessageConnectionHandler(string logKey, int sequence, string messageId) - { - if (SubmitMessageHandler != null) - { - SubmitMessageHandler(logKey, sequence, messageId); - } - } - - /// Called when a query message is responded - /// - /// - /// - /// - /// - /// - public void QueryMessageConnectionHandler(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode) - { - if (QueryMessageHandler != null) - { - QueryMessageHandler(logKey, sequence, messageId, finalDate, messageState, errorCode); - } - } - - /// Called to log an event - /// - /// - /// - /// - public void LogEventConnectionHandler(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message) - { - if (LogEventHandler != null) - { - LogEventHandler(logEventNotificationType, logKey, shortLongCode, message); - } - } - - /// Called when a pdu details are available - /// - /// - /// - /// - /// External Id - private Guid? PduDetailsConnectionHandler(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details) - { - Guid? externalId = null; - - if (PduDetailsEventHandler != null) - { - externalId = PduDetailsEventHandler(logKey, pduDirectionType, pdu, details); - } - - return externalId; - } - - #endregion - - #region Connection Management Methods - - /// Called to add a transceiver connection - /// - /// - /// - /// - /// - /// - /// - private void AddTransceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) - { - lock (Receivers) - { - // Create the smppConnection object - ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transceiver, - host, port, userName, password, logKey, defaultEncoding, - new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), - new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), - new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), - new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), - new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), - new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), - new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); - - // Add the connection to both list - Transmitters.Add(connectionId, smppConnection); - } - } - - /// Called to add a receiver connection - /// - /// - /// - /// - /// - /// - /// - private void AddReceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) - { - lock (Receivers) - { - // Create the smppConnection object - ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Receiver, - host, port, userName, password, logKey, defaultEncoding, - new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), - new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), - new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), - null, - new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), - new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), - new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); - - // Add the connection to the list - Receivers.Add(smppConnection); - } - } - - /// Called to add a transmitter connection - /// - /// - /// - /// - /// - /// - /// - private void AddTransmitterConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) - { - lock (Transmitters) - { - // Create the smppConnection object - ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transmitter, - host, port, userName, password, logKey, defaultEncoding, - new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), - null, - new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), - new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), - new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), - new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), - new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); - - // Add the connection to the list - Transmitters.Add(connectionId, smppConnection); - } - } - - /// Called to return the next transmitter for sending - /// SmppConnection - private ESMEConnection NextTransmitterConnection() - { - ESMEConnection smppConnection = null; - - int totalConnections = Transmitters.Count(); - - // We only want a bound connection. We will try them all - for (int connection = 0; connection < totalConnections; ++connection) - { - lock (Transmitters) - { - smppConnection = Transmitters[NextTransmitter]; - - if (++NextTransmitter > Transmitters.Count()) - { - NextTransmitter = 1; - } - - if (smppConnection.Status == ConnectionStatus.Bound) - { - break; - } - - smppConnection = null; - } - } - - return smppConnection; - } - - #endregion - - #region Public Methods - - /// Called to add connections - /// - /// - /// - /// - /// - /// - /// - /// - public void AddConnections(int howMany, ConnectionModes connectionMode, string host, int port, - string userName, string password, string logKey, DataCodings defaultEncoding) - { - WriteLog("ESMEManager : AddConnections : Started : HowMany[{0}] ConnectionMode[{1}] Host[{2}] Port[{3}] LogKey[{4}] DefaultEncoding[{5}]", howMany, connectionMode, host, port, logKey, defaultEncoding); - - for (int connection = 1; connection <= howMany; ++connection) - { - if (connectionMode == ConnectionModes.Transceiver) - { - AddTransceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); - } - else if (connectionMode == ConnectionModes.Receiver) - { - AddReceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); - } - else - { - AddTransmitterConnection(connection, host, port, userName, password, logKey, defaultEncoding); - } - } - } - - /// Called to send the message - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1 - Successful / 0 - Failed - public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) - { - int retVal = 0; - - submitSm = null; - submitSmResp = null; - - try - { - // Capture the next transmitter connection - ESMEConnection smppConnection = NextTransmitterConnection(); - - if (smppConnection == null) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); - - return 2; - } - - // Send the message - retVal = smppConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); - } - - return retVal; - } - - /// Called to send the message - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1 - Successful / 0 - Failed - public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destTon, Npi destNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) - { - int retVal = 0; - - submitSm = null; - submitSmResp = null; - try - { - // Capture the next transmitter connection - ESMEConnection eSMEConnection = NextTransmitterConnection(); - - if (eSMEConnection == null) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); - - return 2; - } - - // Send the message - retVal = eSMEConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, destTon, destNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); - } - catch (Exception ex) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", ex.ToString()); - } - - return retVal; - } - - /// Called to send the message - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1 - Successful / 0 - Failed - public int SendMessageLarge(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out List submitSmList, out List submitSmRespList) - { - int retVal = 0; - - submitSmList = null; - submitSmRespList = null; - - try - { - // Capture the next transmitter connection - ESMEConnection smppConnection = NextTransmitterConnection(); - - if (smppConnection == null) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); - - return 2; - } - - // Send the message - retVal = smppConnection.SendMessageLarge(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSmList, out submitSmRespList); - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); - } - - return retVal; - } - - /// Called to send a query - /// - /// 1 - Successful / 0 - Failed - public QuerySm SendQuery(string messageId) - { - QuerySm querySm = null; - - try - { - // Capture the next transmitter connection - ESMEConnection smppConnection = NextTransmitterConnection(); - - if (smppConnection.Status != ConnectionStatus.Bound) - { - WriteLog("ESMEManager : SendMessage : Warning : Not Connected To The SMPP Server"); - - return querySm; - } - - // Send the message - querySm = smppConnection.SendQuery(messageId); - } - - catch (Exception exception) - { - WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); - } - - return querySm; - } - - #endregion - } -} +#region Namespaces + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +#endregion + +namespace BSN.SmppClient +{ + /// Provides ESME (Extended Short Message Entity) Management + public class ESMEManager : IDisposable + { + #region Delegates + + /// Called when a message is received + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public delegate void RECEIVED_MESSAGE_HANDLER(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message); + + /// Called when a submit message is acknowledged + /// + /// + public delegate void RECEIVED_GENERICNACK_HANDLER(string logKey, int sequence); + + /// Called when a submit message is acknowledged + /// + /// + /// + public delegate void SUBMIT_MESSAGE_HANDLER(string logKey, int sequence, string messageId); + + /// Called when a query message is responded + /// + /// + /// + /// + /// + /// + public delegate void QUERY_MESSAGE_HANDLER(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode); + + /// Called to log an event + /// + /// + /// + /// + public delegate void LOG_EVENT_HANDLER(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message); + + /// Called when a connection event occurrs + /// + /// + /// + public delegate void CONNECTION_EVENT_HANDLER(string logKey, ConnectionEventTypes connectionEventType, string message); + + /// Called to capture the details of the pdu + /// + /// + /// + /// + /// External Id + public delegate Guid? PDU_DETAILS_EVENT_HANDLER(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details); + + #endregion + + #region Private Properties + + /// Flag that determines whether this instance has been disposed or not yet + protected bool Disposed = false; + + /// The logKey for writing logs to the correct files + private string LogKey = string.Empty; + + /// The short/long code being managed + private string ShortLongCode = null; + + + /// A user supplied method to call when a message is received + private RECEIVED_MESSAGE_HANDLER ReceivedMessageHandler = null; + + /// A user supplied method to call when a generic nack is received + private RECEIVED_GENERICNACK_HANDLER ReceivedGenericNackHandler = null; + + /// A user supplied method to call when a submit is ascknowledged + private SUBMIT_MESSAGE_HANDLER SubmitMessageHandler = null; + + /// A user supplied method to call when a query is responded + private QUERY_MESSAGE_HANDLER QueryMessageHandler = null; + + /// A user supplied method to call to write logs + private LOG_EVENT_HANDLER LogEventHandler = null; + + /// A user supplied method to call for connection events + private CONNECTION_EVENT_HANDLER ConnectionEventHandler = null; + + /// A user supplied method to call for pdu detail data + private PDU_DETAILS_EVENT_HANDLER PduDetailsEventHandler = null; + + + /// A list of receiver connections + private List Receivers = new List(); + + /// A dictionary of transmitter connections + private Dictionary Transmitters = new Dictionary(); + + /// A pointer to the next transmitter to use + private int NextTransmitter = 1; + + #endregion + + #region Constructor + + /// Contructor + /// + /// + /// + /// + /// + /// + /// + /// + /// + public ESMEManager(string logKey, string shortLongCode, + CONNECTION_EVENT_HANDLER connectionEventHandler, RECEIVED_MESSAGE_HANDLER receivedMessageHandler, + RECEIVED_GENERICNACK_HANDLER receivedGenericNackHandler, SUBMIT_MESSAGE_HANDLER submitMessageHandler, + QUERY_MESSAGE_HANDLER queryMessageHandler, LOG_EVENT_HANDLER logEventHandler, + PDU_DETAILS_EVENT_HANDLER pduDetailsEventHandler) + { + LogKey = logKey; + ShortLongCode = shortLongCode; + + ConnectionEventHandler = connectionEventHandler; + ReceivedMessageHandler = receivedMessageHandler; + ReceivedGenericNackHandler = receivedGenericNackHandler; + SubmitMessageHandler = submitMessageHandler; + QueryMessageHandler = queryMessageHandler; + LogEventHandler = logEventHandler; + PduDetailsEventHandler = pduDetailsEventHandler; + } + + /// Dispose + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// Dispose + /// + protected void Dispose(bool disposing) + { + WriteLog("ESMEManager : Dispose : Started"); + + if (!Disposed) + { + // Note disposing has begun + Disposed = true; + + try + { + WriteLog("ESMEManager : Dispose : Info : Disconnect the receiver connections"); + + foreach (ESMEConnection smppConnection in Receivers) + { + smppConnection.Dispose(); + } + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); + } + + try + { + WriteLog("ESMEManager : Dispose : Info : Disconnect the transmitter connections"); + + foreach (ESMEConnection smppConnection in Transmitters.Values) + { + smppConnection.Dispose(); + } + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : Dispose : ERROR : {0}", exception.ToString()); + } + } + + WriteLog("ESMEManager : Dispose : Completed"); + } + + #endregion + + #region Log Methods + + /// Called to write out to the log + /// + private void WriteLog(string message) + { + LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, message); + } + + /// Called to write out to the log + /// + /// + private void WriteLog(string message, params object[] logValues) + { + LogEventHandler(LogEventNotificationTypes.None, LogKey, ShortLongCode, string.Format(message, logValues)); + } + + /// Called to write out to the log + /// + /// + private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message) + { + LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, message); + } + + /// Called to write out to the log + /// + /// + /// + private void WriteLog(LogEventNotificationTypes logEventNotificationType, string message, params object[] logValues) + { + LogEventHandler(logEventNotificationType, LogKey, ShortLongCode, string.Format(message, logValues)); + } + + #endregion + + #region Event Methods + + /// Called when a connection event is fired + /// + /// + /// + public void ConnectionEventConnectionHandler(string logKey, ConnectionEventTypes connectionEventType, string message) + { + if (ConnectionEventHandler != null) + { + ConnectionEventHandler(logKey, connectionEventType, message); + } + } + + /// Called when a message is received on a connection + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void ReceivedMessageConnectionHandler(string logKey, MessageTypes messageType, string serviceType, Ton sourceTon, Npi sourceNpi, string shortLongCode, DateTime dateReceived, string phoneNumber, DataCodings dataCoding, string message) + { + if (ReceivedMessageHandler != null) + { + ReceivedMessageHandler(logKey, messageType, serviceType, sourceTon, sourceNpi, shortLongCode, dateReceived, phoneNumber, dataCoding, message); + } + } + + /// A user supplied method to call when a generic nack is received + /// + /// + public void ReceivedGenericNackConnectionHandler(string logKey, int sequence) + { + if (ReceivedGenericNackHandler != null) + { + ReceivedGenericNackHandler(logKey, sequence); + } + } + + /// Called when a submit message is acknowledged + /// + /// + /// + public void SubmitMessageConnectionHandler(string logKey, int sequence, string messageId) + { + if (SubmitMessageHandler != null) + { + SubmitMessageHandler(logKey, sequence, messageId); + } + } + + /// Called when a query message is responded + /// + /// + /// + /// + /// + /// + public void QueryMessageConnectionHandler(string logKey, int sequence, string messageId, DateTime finalDate, int messageState, long errorCode) + { + if (QueryMessageHandler != null) + { + QueryMessageHandler(logKey, sequence, messageId, finalDate, messageState, errorCode); + } + } + + /// Called to log an event + /// + /// + /// + /// + public void LogEventConnectionHandler(LogEventNotificationTypes logEventNotificationType, string logKey, string shortLongCode, string message) + { + if (LogEventHandler != null) + { + LogEventHandler(logEventNotificationType, logKey, shortLongCode, message); + } + } + + /// Called when a pdu details are available + /// + /// + /// + /// + /// External Id + private Guid? PduDetailsConnectionHandler(string logKey, PduDirectionTypes pduDirectionType, Header pdu, List details) + { + Guid? externalId = null; + + if (PduDetailsEventHandler != null) + { + externalId = PduDetailsEventHandler(logKey, pduDirectionType, pdu, details); + } + + return externalId; + } + + #endregion + + #region Connection Management Methods + + /// Called to add a transceiver connection + /// + /// + /// + /// + /// + /// + /// + private void AddTransceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) + { + lock (Receivers) + { + // Create the smppConnection object + ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transceiver, + host, port, userName, password, logKey, defaultEncoding, + new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), + new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), + new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), + new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), + new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), + new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), + new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); + + // Add the connection to both list + Transmitters.Add(connectionId, smppConnection); + } + } + + /// Called to add a receiver connection + /// + /// + /// + /// + /// + /// + /// + private void AddReceiverConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) + { + lock (Receivers) + { + // Create the smppConnection object + ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Receiver, + host, port, userName, password, logKey, defaultEncoding, + new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), + new ESMEConnection.RECEIVED_MESSAGE_HANDLER(ReceivedMessageConnectionHandler), + new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), + null, + new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), + new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), + new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); + + // Add the connection to the list + Receivers.Add(smppConnection); + } + } + + /// Called to add a transmitter connection + /// + /// + /// + /// + /// + /// + /// + private void AddTransmitterConnection(int connectionId, string host, int port, string userName, string password, string logKey, DataCodings defaultEncoding) + { + lock (Transmitters) + { + // Create the smppConnection object + ESMEConnection smppConnection = new ESMEConnection(connectionId, ShortLongCode, ConnectionModes.Transmitter, + host, port, userName, password, logKey, defaultEncoding, + new ESMEConnection.CONNECTION_EVENT_HANDLER(ConnectionEventConnectionHandler), + null, + new ESMEConnection.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackConnectionHandler), + new ESMEConnection.SUBMIT_MESSAGE_HANDLER(SubmitMessageConnectionHandler), + new ESMEConnection.QUERY_MESSAGE_HANDLER(QueryMessageConnectionHandler), + new ESMEConnection.LOG_EVENT_HANDLER(LogEventConnectionHandler), + new ESMEConnection.PDU_DETAILS_EVENT_HANDLER(PduDetailsConnectionHandler)); + + // Add the connection to the list + Transmitters.Add(connectionId, smppConnection); + } + } + + /// Called to return the next transmitter for sending + /// SmppConnection + private ESMEConnection NextTransmitterConnection() + { + ESMEConnection smppConnection = null; + + int totalConnections = Transmitters.Count(); + + // We only want a bound connection. We will try them all + for (int connection = 0; connection < totalConnections; ++connection) + { + lock (Transmitters) + { + smppConnection = Transmitters[NextTransmitter]; + + if (++NextTransmitter > Transmitters.Count()) + { + NextTransmitter = 1; + } + + if (smppConnection.Status == ConnectionStatus.Bound) + { + break; + } + + smppConnection = null; + } + } + + return smppConnection; + } + + #endregion + + #region Public Methods + + /// Called to add connections + /// + /// + /// + /// + /// + /// + /// + /// + public void AddConnections(int howMany, ConnectionModes connectionMode, string host, int port, + string userName, string password, string logKey, DataCodings defaultEncoding) + { + WriteLog("ESMEManager : AddConnections : Started : HowMany[{0}] ConnectionMode[{1}] Host[{2}] Port[{3}] LogKey[{4}] DefaultEncoding[{5}]", howMany, connectionMode, host, port, logKey, defaultEncoding); + + for (int connection = 1; connection <= howMany; ++connection) + { + if (connectionMode == ConnectionModes.Transceiver) + { + AddTransceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); + } + else if (connectionMode == ConnectionModes.Receiver) + { + AddReceiverConnection(connection, host, port, userName, password, logKey, defaultEncoding); + } + else + { + AddTransmitterConnection(connection, host, port, userName, password, logKey, defaultEncoding); + } + } + } + + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1 - Successful / 0 - Failed + public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) + { + int retVal = 0; + + submitSm = null; + submitSmResp = null; + + try + { + // Capture the next transmitter connection + ESMEConnection smppConnection = NextTransmitterConnection(); + + if (smppConnection == null) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); + + return 2; + } + + // Send the message + retVal = smppConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); + } + + return retVal; + } + + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1 - Successful / 0 - Failed + public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destTon, Npi destNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) + { + int retVal = 0; + + submitSm = null; + submitSmResp = null; + try + { + // Capture the next transmitter connection + ESMEConnection eSMEConnection = NextTransmitterConnection(); + + if (eSMEConnection == null) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); + + return 2; + } + + // Send the message + retVal = eSMEConnection.SendMessage(phoneNumber, serviceType, sourceTon, sourceNpi, destTon, destNpi, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp); + } + catch (Exception ex) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", ex.ToString()); + } + + return retVal; + } + + /// Called to send the message + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1 - Successful / 0 - Failed + public int SendMessageLarge(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out List submitSmList, out List submitSmRespList) + { + int retVal = 0; + + submitSmList = null; + submitSmRespList = null; + + try + { + // Capture the next transmitter connection + ESMEConnection smppConnection = NextTransmitterConnection(); + + if (smppConnection == null) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Bound To The SMPP Server"); + + return 2; + } + + // Send the message + retVal = smppConnection.SendMessageLarge(phoneNumber, serviceType, sourceTon, sourceNpi, submitDataCoding, encodeDataCoding, message, out submitSmList, out submitSmRespList); + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); + } + + return retVal; + } + + /// Called to send a query + /// + /// 1 - Successful / 0 - Failed + public QuerySm SendQuery(string messageId) + { + QuerySm querySm = null; + + try + { + // Capture the next transmitter connection + ESMEConnection smppConnection = NextTransmitterConnection(); + + if (smppConnection.Status != ConnectionStatus.Bound) + { + WriteLog("ESMEManager : SendMessage : Warning : Not Connected To The SMPP Server"); + + return querySm; + } + + // Send the message + querySm = smppConnection.SendQuery(messageId); + } + + catch (Exception exception) + { + WriteLog(LogEventNotificationTypes.Email, "ESMEManager : SendMessage : ERROR : {0}", exception.ToString()); + } + + return querySm; + } + + #endregion + } +} From 47000b127724bd29c6bc44eb02c309e9ba48f952 Mon Sep 17 00:00:00 2001 From: Fatemeh Pardakhti Date: Sat, 22 Aug 2026 12:13:08 +0330 Subject: [PATCH 6/6] fix document about retun value --- Source/SmppClient/ESMEManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/SmppClient/ESMEManager.cs b/Source/SmppClient/ESMEManager.cs index 82a00f8..596bc15 100644 --- a/Source/SmppClient/ESMEManager.cs +++ b/Source/SmppClient/ESMEManager.cs @@ -503,7 +503,7 @@ public void AddConnections(int howMany, ConnectionModes connectionMode, string h /// /// /// - /// 1 - Successful / 0 - Failed + /// 0 - Successful / 1 - Failed public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) { int retVal = 0; @@ -547,7 +547,7 @@ public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Np /// /// /// - /// 1 - Successful / 0 - Failed + /// 0 - Successful / 1 - Failed public int SendMessage(string phoneNumber, string serviceType, Ton sourceTon, Npi sourceNpi, Ton destTon, Npi destNpi, DataCodings submitDataCoding, DataCodings encodeDataCoding, string message, out SubmitSm submitSm, out SubmitSmResp submitSmResp) { int retVal = 0;