### Basic Setup and Connection with SmppClient Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md Demonstrates how to create, configure, and start an SmppClient instance. It includes setting system credentials, host, port, source address, and configuring connection behaviors like auto-reconnect and keep-alive intervals. Event subscriptions for connection state and message reception are also shown. ```csharp // Create and configure client SmppClient client = new SmppClient(); client.Properties.SystemID = "your_system_id"; client.Properties.Password = "your_password"; client.Properties.Host = "smpp.provider.com"; client.Properties.Port = 2775; client.Properties.SourceAddress = "12345"; // Configure connection behavior client.AutoReconnectDelay = 10000; // 10 seconds client.KeepAliveInterval = 30000; // 30 seconds client.ConnectionTimeout = 5000; // 5 seconds // Subscribe to events client.ConnectionStateChanged += (sender, e) => { Console.WriteLine($"Connection state: {e.NewState}"); }; client.MessageReceived += (sender, e) => { Console.WriteLine($"Received: {e.Message.Text} from {e.Message.SourceAddress}"); }; client.MessageDelivered += (sender, e) => { Console.WriteLine($"Message delivered: {e.Message.ReceiptedMessageId}"); }; // Start the client client.Start(); ``` -------------------------------- ### Configure and Start SmppClient Instance in C# Source: https://github.com/adhamawadhi/jamaasmpp/wiki/Connecting-to-an-SMSC This snippet shows how to instantiate an SmppClient, populate its connection properties (SystemID, Password, Port, Host, SystemType, DefaultServiceType), set reconnection and keep-alive intervals, and start the client. It assumes the necessary JamaaSMPP library is available. ```csharp SmppClient client = new SmppClient(); SmppConnectionProperties properties = client.Properties; properties.SystemID = "mysystemid"; properties.Password = "mypassword"; properties.Port = 2034; //IP port to use properties.Host = "196.23.3.12"; //SMSC host name or IP Address properties.SystemType = "mysystemtype"; properties.DefaultServiceType = "mydefaultservicetype"; //Resume a lost connection after 30 seconds client.AutoReconnectDelay = 3000; //Send Enquire Link PDU every 15 seconds client.KeepAliveInterval = 15000; //Start smpp client client.Start(); ``` -------------------------------- ### C# Basic StreamParser Setup and Usage Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/StreamParser.md This C# example illustrates the basic setup and usage of the StreamParser class. It covers creating a TCP/IP session, initializing a response handler, setting up an encoding service, defining a processor callback for incoming PDUs, and configuring event handlers for PDU and parser exceptions before starting the parser. ```csharp // Create TCP/IP session TcpIpSession session = TcpIpSession.OpenClientSession("smpp.provider.com", 2775); // Create response handler ResponseHandler responseHandler = new ResponseHandler(); // Create encoding service SmppEncodingService encodingService = new SmppEncodingService(); // Create processor callback PduProcessorCallback processorCallback = (RequestPDU pdu) => { // Handle incoming request PDUs Console.WriteLine($"Received request: {pdu.Header.CommandType}"); }; // Create and start StreamParser StreamParser parser = new StreamParser(session, responseHandler, processorCallback, encodingService); parser.PDUError += (sender, e) => { Console.WriteLine($"PDU Error: {e.Exception.Message}"); }; parser.ParserException += (sender, e) => { Console.WriteLine($"Parser Exception: {e.Exception.Message}"); }; parser.Start(); ``` -------------------------------- ### C# Start Connection Method Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md The Start methods initiate the client connection process. An optional delay can be specified for the first connection attempt. This method sets the client to a started state and activates the auto-reconnect timer. ```csharp public virtual void Start(); public virtual void Start(int connectDelay); // Behavior: // - Sets Started to true // - Starts auto-reconnect timer // - Raises StateChanged event ``` -------------------------------- ### Install JamaaSMPP via NuGet Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/README.md This command installs the JamaaSMPP library using the NuGet Package Manager. This is the primary method for incorporating the library into your .NET project. ```powershell Install-Package JamaaSMPP ``` -------------------------------- ### Basic Text Message Sending Example (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/ShortMessage.md Provides a simple example of creating and sending a basic text message using the TextMessage class and SmppClient. It demonstrates setting essential properties like source and destination addresses, message text, and requesting delivery notifications before sending the message via the client. ```csharp // Create simple text message TextMessage message = new TextMessage(); message.SourceAddress = "12345"; message.DestinationAddress = "1234567890"; message.Text = "Hello, World!"; message.RegisterDeliveryNotification = true; // Send via SmppClient client.SendMessage(message); ``` -------------------------------- ### Wire Event Handlers and Start Stream Parser (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md This C# code snippet demonstrates how to wire event handlers for parser exceptions and PDU errors, and then start the stream parser. It initializes key components like PDUTransmitter, ResponseHandler, and StreamParser. ```csharp private void AssembleComponents() { vTrans = new PDUTransmitter(vTcpIpSession); vRespHandler = new ResponseHandler(); vStreamParser = new StreamParser( vTcpIpSession, vRespHandler, new PduProcessorCallback(PduRequestProcessorCallback), vSmppEncodingService); // Wire event handlers vStreamParser.ParserException += ParserExceptionEventHandler; vStreamParser.PDUError += PduErrorEventHandler; // Start stream parser vStreamParser.Start(); } ``` -------------------------------- ### Creating and Binding an SMPP Session in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Provides a C# example for establishing an SMPP session. It covers creating `SessionBindInfo`, configuring connection details like server address and port, and initiating the bind process using `SmppClientSession.Bind`. Event subscriptions for PDU reception and session closure are also demonstrated. ```csharp // Create binding information SessionBindInfo bindInfo = new SessionBindInfo(); bindInfo.SystemID = "your_system_id"; bindInfo.Password = "your_password"; bindInfo.ServerName = "smpp.provider.com"; bindInfo.Port = 2775; bindInfo.InterfaceVersion = InterfaceVersion.v34; bindInfo.AddressTon = TypeOfNumber.International; bindInfo.AddressNpi = NumberingPlanIndicator.ISDN; bindInfo.SystemType = "SMS"; // Create encoding service SmppEncodingService encodingService = new SmppEncodingService(); // Bind session SmppClientSession session = SmppClientSession.Bind(bindInfo, 5000, encodingService); // Configure session session.EnquireLinkInterval = 30000; // 30 seconds session.DefaultResponseTimeout = 5000; // 5 seconds // Subscribe to events session.PduReceived += (sender, e) => { Console.WriteLine($"Received PDU: {e.Request.Header.CommandType}"); // Handle specific PDU types if (e.Request is DeliverSm) { // Process incoming message DeliverSm deliverSm = (DeliverSm)e.Request; Console.WriteLine($"Message from: {deliverSm.SourceAddress.Address}"); // Send response e.Response = deliverSm.CreateDefaultResponce(); } }; session.SessionClosed += (sender, e) => { Console.WriteLine($"Session closed: {e.Reason}"); }; ``` -------------------------------- ### Connection Management API Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md This section details the methods for managing the connection lifecycle, including starting, stopping, and restarting the client. ```APIDOC ## Connection Management ### Start Methods ```csharp public virtual void Start() public virtual void Start(int connectDelay) ``` #### Description Starts the client and begins connection attempts. Optionally, a delay can be specified before the first attempt. #### Method GET #### Endpoint N/A (Method invocation) #### Parameters ##### Path Parameters None ##### Query Parameters None ##### Request Body None ### Shutdown ```csharp public virtual void Shutdown() ``` #### Description Gracefully shuts down the client, stopping all active connections and timers. #### Method GET #### Endpoint N/A (Method invocation) #### Parameters None ### Restart ```csharp public virtual void Restart() ``` #### Description Restarts the client by first shutting it down and then starting it again. #### Method GET #### Endpoint N/A (Method invocation) #### Parameters None ### Force Connect ```csharp public virtual void ForceConnect() public virtual void ForceConnect(int timeout) ``` #### Description Immediately attempts to connect to the SMSC without waiting for the automatic reconnect timer. An optional timeout can be specified. #### Method GET #### Endpoint N/A (Method invocation) #### Parameters ##### Path Parameters None ##### Query Parameters None ##### Request Body None ``` -------------------------------- ### Utilize SmppEncodingService for Encoding Source: https://github.com/adhamawadhi/jamaasmpp/wiki/Smpp-Encoding Provides examples of using the SmppEncodingService for message encoding. This includes initializing it with default settings and with a custom encoding class, such as GSMEncoding, which inherits from System.Text.Encoding. ```csharp client.SmppEncodingService = new SmppEncodingService(); ``` ```csharp var enc = new JamaaTech.Smpp.Net.Lib.Util.GSMEncoding(); client.SmppEncodingService = new SmppEncodingService(enc); ``` -------------------------------- ### C# Restart Connection Method Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md The Restart method provides a convenient way to re-initialize the client by first calling Shutdown and then calling Start. ```csharp public virtual void Restart(); // Behavior: // Calls Shutdown() followed by Start() ``` -------------------------------- ### SMPP Error Handling Example in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Provides a detailed C# example for handling session closure events and PDU processing errors. It uses a `switch` statement to differentiate between various `SmppSessionCloseReason` and includes a `try-catch` block within the `PduReceived` event handler to manage exceptions during PDU processing and send appropriate error responses. ```csharp session.SessionClosed += (sender, e) => { switch (e.Reason) { case SmppSessionCloseReason.EndSessionCalled: Console.WriteLine("Session closed normally"); break; case SmppSessionCloseReason.EnquireLinkTimeout: Console.WriteLine("Keep-alive timeout - connection lost"); break; case SmppSessionCloseReason.TcpIpSessionError: Console.WriteLine($"Network error: {e.Exception?.Message}"); break; case SmppSessionCloseReason.UnbindRequested: Console.WriteLine("SMSC requested unbind"); break; } }; session.PduReceived += (sender, e) => { try { // Process PDU ProcessPdu(e.Request); } catch (Exception ex) { Console.WriteLine($"Error processing PDU: {ex.Message}"); // Send error response if (e.Request.HasResponse) { e.Response = e.Request.CreateDefaultResponce(); e.Response.Header.ErrorCode = SmppErrorCode.ESME_RX_P_APPN; } } }; ``` -------------------------------- ### Advanced PDU Generation - C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/ShortMessage.md Provides an example of manually generating PDUs (Protocol Data Units) for advanced scenarios. This involves creating message objects, addresses, and then sending individual PDUs via the client. ```csharp // Generate PDUs manually for advanced scenarios TextMessage message = new TextMessage(); message.DestinationAddress = "1234567890"; message.Text = "Advanced message"; // Create addresses SmppAddress destAddress = new SmppAddress("1234567890"); SmppAddress srcAddress = new SmppAddress("12345"); // Generate PDUs var pdus = message.GetMessagePDUs(DataCoding.ASCII, encodingService, destAddress, srcAddress); // Send each PDU individually foreach (var pdu in pdus) { ResponsePDU response = client.SendPdu(pdu, 5000); if (response is SubmitSmResp submitResp) { Console.WriteLine($"Message ID: {submitResp.MessageID}"); } } ``` -------------------------------- ### Memory Usage Monitoring for PDU Transmission in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/PDUTransmitter.md Provides an example of monitoring memory allocation during PDU transmission. This helps in understanding the memory footprint and potential garbage collection pressure in high-volume scenarios. ```csharp using System; using Jamaa.Smpp.Net.Network; using Jamaa.Smpp.Net.PDU; // Assuming 'transmitter' and 'pdu' are initialized long memoryBefore = GC.GetTotalMemory(false); transmitter.Send(pdu); long memoryAfter = GC.GetTotalMemory(false); Console.WriteLine($"Memory allocated: {memoryAfter - memoryBefore} bytes"); ``` -------------------------------- ### Handle SmppClient Connection State Changes in C# Source: https://github.com/adhamawadhi/jamaasmpp/wiki/Connecting-to-an-SMSC This code demonstrates how to subscribe to the SmppClient.ConnectionStateChanged event and handle different connection states (Closed, Connected, Connecting). It includes logic for setting a custom reconnect interval when the connection is lost. ```csharp client.ConnectionStateChanged += client_ConnectionStateChanged; private void client_ConnectionStateChanged(object sender, ConnectionStateChangedEventArgs e) { switch (e.CurrentState) { case SmppConnectionState.Closed: //Connection to the remote server is lost //Do something here e.ReconnectInteval = 60000; //Try to reconnect after 1 min break; case SmppConnectionState.Connected: //A successful connection has been established break; case SmppConnectionState.Connecting: //A connection attemp is still on progress break; } } ``` -------------------------------- ### Integration of SmppEncodingService in PDU Classes (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Shows a practical example of how SmppEncodingService can be used within a Protocol Data Unit (PDU) class, such as SubmitSm, to handle the conversion of string fields (like serviceType) to and from byte arrays according to protocol specifications. ```csharp // In PDU class public class SubmitSm : SmPDU { public void SetServiceType(string serviceType) { // Use encoding service to convert string to bytes byte[] bytes = vSmppEncodingService.GetBytesFromCString(serviceType, DataCoding.ASCII); // Store bytes in PDU } public string GetServiceType() { // Use encoding service to convert bytes to string return vSmppEncodingService.GetCStringFromBytes(serviceTypeBytes, DataCoding.ASCII); } } ``` -------------------------------- ### ASCII Encoding Example (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Demonstrates the use of ASCII encoding for converting strings to byte arrays. ASCII is a 7-bit encoding suitable for English characters, using 1 byte per character and offering high efficiency for English text. ```csharp case DataCoding.ASCII: bytes = System.Text.Encoding.ASCII.GetBytes(cStr); break; ``` -------------------------------- ### Sending PDUs Synchronously in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Illustrates how to send SMPP PDUs synchronously using C#. The example shows the creation and configuration of a `SubmitSm` PDU and its transmission via `session.SendPdu`. It includes error handling for potential `SmppResponseTimedOutException` and general `SmppException`. ```csharp // Send a SubmitSm PDU SubmitSm submitSm = new SubmitSm(encodingService); submitSm.ServiceType = "SMS"; submitSm.SourceAddress = new SmppAddress("12345"); submitSm.DestinationAddress = new SmppAddress("1234567890"); submitSm.ShortMessage = "Hello, World!"; try { SubmitSmResp response = (SubmitSmResp)session.SendPdu(submitSm, 10000); Console.WriteLine($"Message ID: {response.MessageID}"); } catch (SmppResponseTimedOutException) { Console.WriteLine("Request timed out"); } catch (SmppException ex) { Console.WriteLine($"SMPP Error: {ex.ErrorCode}"); } ``` -------------------------------- ### SMSC Default Encoding Example (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Details the SMSC Default encoding, a provider-specific encoding type that varies among SMSCs. It is often an 8-bit encoding and may support local character sets, making it adaptable but less standardized. ```csharp case DataCoding.SMSCDefault: bytes = SMSCDefaultEncoding.GetBytes(cStr); break; ``` -------------------------------- ### C# State Changed Event Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md The StateChanged event is raised upon client startup or shutdown. It indicates whether the client has started via a boolean flag and is part of the client's lifecycle management. ```csharp public event EventHandler StateChanged; // Event Args: StateChangedEventArgs // - Started: Boolean indicating if client is started ``` -------------------------------- ### Latin1 Encoding Example (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Illustrates the Latin1 (ISO-8859-1) encoding for converting strings to byte arrays. This 8-bit encoding supports Western European languages and uses 1 byte per character, extending the basic ASCII set. ```csharp case DataCoding.Latin1: bytes = Latin1Encoding.GetBytes(cStr); break; ``` -------------------------------- ### Error Handling for Connection and Message Events Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md Provides examples of how to implement error handling within event handlers for `ConnectionStateChanged` and `MessageReceived`. This includes using a switch statement for connection states and a try-catch block for processing incoming messages. ```csharp client.ConnectionStateChanged += (sender, e) => { switch (e.NewState) { case SmppConnectionState.Connected: Console.WriteLine("Connected to SMSC"); break; case SmppConnectionState.Connecting: Console.WriteLine("Connecting to SMSC..."); break; case SmppConnectionState.Closed: Console.WriteLine($"Connection closed. Reconnecting in {e.ReconnectInteval}ms"); break; } }; client.MessageReceived += (sender, e) => { try { // Process received message ProcessIncomingMessage(e.Message); } catch (Exception ex) { Console.WriteLine($"Error processing message: {ex.Message}"); } }; ``` -------------------------------- ### Basic PDU Transmission in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/PDUTransmitter.md Demonstrates the basic steps to establish a TCP/IP session, create a PDUTransmitter, and send a SubmitSm PDU. Includes essential error handling for network issues. ```csharp using Jamaa.Smpp.Net.Protocols; using Jamaa.Smpp.Net.Network; using Jamaa.Smpp.Net.PDU; using Jamaa.Smpp.Net.Encoding; // Assume encodingService is properly initialized EncodingService encodingService = new EncodingService(); // Create TCP/IP session TcpIpSession session = TcpIpSession.OpenClientSession("smpp.provider.com", 2775); // Create PDUTransmitter PDUTransmitter transmitter = new PDUTransmitter(session); // Create and send a PDU SubmitSm submitSm = new SubmitSm(encodingService); submitSm.ServiceType = "SMS"; submitSm.SourceAddress = new SmppAddress("12345"); submitSm.DestinationAddress = new SmppAddress("1234567890"); submitSm.ShortMessage = "Hello, World!"; try { transmitter.Send(submitSm); Console.WriteLine("PDU sent successfully"); } catch (TcpIpException ex) { Console.WriteLine($"Network error: {ex.Message}"); } ``` -------------------------------- ### Resource Management for SmppClient (using and manual) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md Demonstrates proper resource management for the SmppClient, showing both the preferred `using` statement for automatic disposal and manual disposal using a `try...finally` block to ensure the client is properly disposed. ```csharp // Proper disposal using (SmppClient client = new SmppClient()) { // Configure and use client client.Start(); // Send messages // ... // Client will be automatically disposed } // Manual disposal SmppClient client = new SmppClient(); try { client.Start(); // Use client } finally { client.Dispose(); } ``` -------------------------------- ### Component Assembly Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Details on how the components of the SMPP client session are created and their dependencies. ```APIDOC ## Component Assembly ### Component Creation Order 1. **TcpIpSession**: Establishes TCP connection. 2. **PDUTransmitter**: Handles PDU transmission. 3. **ResponseHandler**: Manages response queuing. 4. **StreamParser**: Parses incoming data. 5. **Event Wiring**: Connects component events. 6. **Parser Start**: Begins parsing incoming data. ### Component Dependencies - **PDUTransmitter** depends on **TcpIpSession**. - **StreamParser** depends on **TcpIpSession**, **ResponseHandler**, and **SmppEncodingService**. - **ResponseHandler** depends on **PDUTransmitter**. ``` -------------------------------- ### SmppClient Overview Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md The SmppClient is the main entry point for the Jamaa SMPP Library. It encapsulates the complexity of SMPP protocol handling, session management, and message processing, offering a simple and robust API for SMS applications. ```APIDOC ## Overview The `SmppClient` is the main entry point for the Jamaa SMPP Library, providing a high-level interface for SMPP (Short Message Peer-to-Peer) communication. It encapsulates the complexity of SMPP protocol handling, session management, and message processing, offering a simple and robust API for SMS applications. ### Key Responsibilities - **Connection Management**: Establishes and maintains SMPP connections with SMSC servers - **Session Coordination**: Manages transmitter and receiver sessions (separate or combined) - **Message Processing**: Handles sending and receiving SMS messages - **Automatic Reconnection**: Provides automatic reconnection capabilities - **Event Handling**: Raises events for connection state changes and message events - **Protocol Abstraction**: Hides SMPP protocol complexity from application developers ``` -------------------------------- ### SmppEncodingService Constructors Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Provides constructors for initializing the SmppEncodingService, allowing for default UCS2 encoding or a custom one. ```APIDOC ## SmppEncodingService Constructors ### Default Constructor ```csharp public SmppEncodingService() ``` **Description**: Initializes the service with the default UCS2 encoding (BigEndianUnicode). ### Custom Encoding Constructor ```csharp public SmppEncodingService(System.Text.Encoding ucs2Encoding) ``` **Description**: Initializes the service with a specified UCS2 encoding. **Parameters**: * `ucs2Encoding` (System.Text.Encoding) - The custom encoding to use for UCS2 operations. ``` -------------------------------- ### SmppClient Class Hierarchy and Dependencies Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md Illustrates the inheritance of the SmppClient class from IDisposable and its core dependencies, including SmppConnectionProperties, SmppClientSession, SmppEncodingService, ShortMessage, and PDU Objects. This provides an overview of the class's structure and its reliance on other components for SMPP communication. ```mermaid classDiagram class IDisposable { +Dispose() } class SmppClient { -SmppConnectionProperties vProperties -SmppClientSession vTrans -SmppClientSession vRecv -Exception vLastException -SmppConnectionState vState -object vConnSyncRoot -System.Threading.Timer vTimer -int vTimeOut -int vAutoReconnectDelay -string vName -int vKeepAliveInterval -SendMessageCallBack vSendMessageCallBack -bool vStarted -SmppEncodingService vSmppEncodingService +PduReceived event +MessageReceived event +MessageDelivered event +ConnectionStateChanged event +MessageSent event +StateChanged event +Start() +Start(int connectDelay) +Shutdown() +Restart() +SendMessage(ShortMessage message) +SendMessage(ShortMessage message, int timeOut) +SendPdu(RequestPDU pdu, int timeout) +BeginSendMessage(...) +EndSendMessage(...) +ForceConnect() +ForceConnect(int timeout) } IDisposable <|-- SmppClient ``` -------------------------------- ### UCS2 Encoding Example (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Shows the application of UCS2 encoding for string-to-byte array conversion. UCS2 is a 16-bit Unicode encoding supporting international characters, using 2 bytes per character with big-endian byte order. ```csharp case DataCoding.UCS2: bytes = UCS2Encoding.GetBytes(cStr); break; ``` -------------------------------- ### SmppClientSession Architecture Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Diagram illustrating the architecture of the SmppClientSession, showing its interaction with core components, the protocol layer, and external dependencies. ```APIDOC ## Architecture The SmppClientSession operates as a coordinator for multiple lower-level components: ```mermaid graph TB subgraph "SmppClientSession" SCS[SmppClientSession] TIMER[Keep-Alive Timer] SYNC[SyncRoot] end subgraph "Core Components" SP[StreamParser] PT[PDUTransmitter] RH[ResponseHandler] TCP[TcpIpSession] end subgraph "Protocol Layer" PDU[PDU Objects] REQ[RequestPDU] RESP[ResponsePDU] end subgraph "External Dependencies" SMSC[SMSC Server] APP[Application] end SCS --> TIMER SCS --> SYNC SCS --> SP SCS --> PT SCS --> RH SCS --> TCP SP --> PDU PT --> PDU RH --> RESP TCP --> SMSC SCS --> APP PDU --> REQ PDU --> RESP ``` ``` -------------------------------- ### SmppClientSession Class Structure Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Details the class hierarchy and core dependencies of the SmppClientSession, outlining its properties and relationships with other components. ```APIDOC ## Class Structure ### Class Hierarchy ```mermaid classDiagram class SmppClientSession { -Timer vTimer -PDUTransmitter vTrans -ResponseHandler vRespHandler -StreamParser vStreamParser -TcpIpSession vTcpIpSession -object vSyncRoot -bool vIsAlive -SmppSessionState vState -int vDefaultResponseTimeout -string vSmscId -string vSystemId -string vPassword -TypeOfNumber vAddressTon -NumberingPlanIndicator vAddressNpi -SmppEncodingService vSmppEncodingService -SendPduCallback vCallback +PduReceived event +SessionClosed event +SendPdu(RequestPDU pdu) +SendPdu(RequestPDU pdu, int timeout) +BeginSendPdu(...) +EndSendPdu(...) +EndSession() +Bind(SessionBindInfo, int, SmppEncodingService) } ``` ### Core Dependencies - **StreamParser**: Parses incoming byte streams into PDUs - **PDUTransmitter**: Sends PDUs to the SMSC - **ResponseHandler**: Manages response PDU queuing and timeouts - **TcpIpSession**: Provides TCP/IP communication - **SmppEncodingService**: Handles character encoding/decoding ``` -------------------------------- ### Handle Delivery Receipts - C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/ShortMessage.md Demonstrates how to subscribe to message delivery events and process delivery receipts. It includes extracting information like the receipted message ID, message state, and user reference. ```csharp // Subscribe to delivery events client.MessageDelivered += (sender, e) => { ShortMessage receipt = e.Message; Console.WriteLine($"Message delivered: {receipt.ReceiptedMessageId}"); Console.WriteLine($"Message state: {receipt.MessageState}"); Console.WriteLine($"User reference: {receipt.UserMessageReference}"); if (receipt.NetworkErrorCode != null) { Console.WriteLine($"Network error: {BitConverter.ToString(receipt.NetworkErrorCode)}"); } }; // Send message with delivery notification TextMessage message = new TextMessage(); message.DestinationAddress = "1234567890"; message.Text = "Message with delivery receipt"; message.RegisterDeliveryNotification = true; message.UserMessageReference = "MSG-002"; client.SendMessage(message); ``` -------------------------------- ### StreamParser Constructor - C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/StreamParser.md Initializes the StreamParser with essential dependencies for network communication, PDU processing, and encoding/decoding. It requires instances of TcpIpSession, ResponseHandler, PduProcessorCallback, and SmppEncodingService. ```csharp public StreamParser(TcpIpSession session, ResponseHandler responseQueue, PduProcessorCallback requestProcessor, SmppEncodingService smppEncodingService) ``` -------------------------------- ### SmppClientSession Properties Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Lists and describes the various properties of the SmppClientSession, categorized into Session State, Configuration, and Address properties. ```APIDOC ## Properties ### Session State Properties | Property | Type | Description | |----------|------|-------------| | `IsAlive` | `bool` | Indicates if the session is active and bound | | `State` | `SmppSessionState` | Current session state (Open, Transmitter, Receiver, Transceiver, Closed) | | `SmscID` | `string` | SMSC identifier received during binding | | `SystemID` | `string` | System identifier used for binding | | `Password` | `string` | Password used for authentication | ### Configuration Properties | Property | Type | Description | |----------|------|-------------| | `EnquireLinkInterval` | `int` | Interval for keep-alive EnquireLink PDUs (minimum 1000ms) | | `DefaultResponseTimeout` | `int` | Default timeout for PDU responses | | `TcpIpProperties` | `TcpIpSessionProperties` | TCP/IP session properties | | `SyncRoot` | `object` | Synchronization object for thread safety | | `SmppEncodingService` | `SmppEncodingService` | Encoding service for character handling | ### Address Properties | Property | Type | Description | |----------|------|-------------| | `AddressTon` | `TypeOfNumber` | Type of Number for addresses | | `AddressNpi` | `NumberingPlanIndicator` | Numbering Plan Indicator for addresses | ### Session States ```mermaid stateDiagram-v2 [*] --> Open Open --> Transmitter : BindTransmitter Open --> Receiver : BindReceiver Open --> Transceiver : BindTransceiver Transmitter --> Closed : Unbind/Error Receiver --> Closed : Unbind/Error Transceiver --> Closed : Unbind/Error Closed --> [*] ``` ``` -------------------------------- ### Handle SmppClient.MessageDelivered Event in C# Source: https://github.com/adhamawadhi/jamaasmpp/wiki/Receiving-Delivery-Notifications This snippet demonstrates how to subscribe to the SmppClient.MessageDelivered event and provides an example of an event handler. The handler extracts the TextMessage from the event arguments and displays its text content. It notes that the message text needs to be parsed for additional details as the format can vary. ```csharp SmppClient client = GetSmppClient(); client.MessageDelivered += client_MessageDelivered; void client_MessageDelivered(object sender, MessageEventArgs e) { TextMessage msg = e.ShortMessage as TextMessage; //parse msg.Text for more details MessageBox.Show(msg.Text, "Message Delivered"); } ``` -------------------------------- ### Advanced SmppClient Configuration Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md Covers advanced configuration options for the SmppClient, such as enabling separate connections for legacy SMSCs, setting custom encoding (e.g., UTF-8), specifying the SMPP interface version, and configuring address TON and NPI. ```csharp // Configure for separate connections (legacy SMSC) client.Properties.UseSeparateConnections = true; // Configure encoding client.SmppEncodingService = new SmppEncodingService(Encoding.UTF8); // Configure interface version client.Properties.InterfaceVersion = InterfaceVersion.v34; // Configure address types client.Properties.AddressTon = TypeOfNumber.International; client.Properties.AddressNpi = NumberingPlanIndicator.ISDN; ``` -------------------------------- ### Setting User Message Reference in .NET Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/README.md This C# code illustrates how to set and retrieve a UserMessageReference for a message using the JamaaSMPP library. The UserMessageReference can be a GUID or any string identifier, useful for correlating messages sent with their delivery reports or events. It's used in conjunction with the MessageSent event. ```csharp // set user message reference msg.UserMessageReference = Guid.NewGuid().ToString(); on MessageSent event Console.WriteLine("Message Id {0} Sent to: {1}", e.ShortMessage.UserMessageReference, e.ShortMessage.DestinationAddress); ``` -------------------------------- ### Error Handling for PDU and Parser Exceptions in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/StreamParser.md This C# code provides examples of handling PDU parsing errors and general parser exceptions. It logs detailed information about PDU errors, including the exception message, command type, sequence number, and byte dump. It also handles specific exceptions like InvalidPDUCommandException and PDUParseException. Parser exceptions, such as TcpIpSessionClosedException, are also managed to allow for reconnection attempts or cleanup. ```csharp parser.PDUError += (sender, e) => { Console.WriteLine($"PDU Error Details:"); Console.WriteLine($" Exception: {e.Exception.Message}"); Console.WriteLine($" Command Type: {e.Header?.CommandType}"); Console.WriteLine($" Sequence Number: {e.Header?.SequenceNumber}"); Console.WriteLine($" Byte Dump: {BitConverter.ToString(e.ByteDump)}"); if (e.Exception is InvalidPDUCommandException) { Console.WriteLine("Invalid PDU command received"); } else if (e.Exception is PDUParseException) { Console.WriteLine("Failed to parse PDU body"); } }; parser.ParserException += (sender, e) => { Console.WriteLine($"Parser Exception: {e.Exception.Message}"); if (e.Exception is TcpIpSessionClosedException) { Console.WriteLine("TCP/IP session was closed"); } }; ``` -------------------------------- ### SmppClientSession State Machine Diagram Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Visualizes the session lifecycle states for SmppClientSession. It shows the transitions between states like Open, Transmitter, Receiver, Transceiver, and Closed, triggered by binding operations or session closure events. ```mermaid stateDiagram-v2 [*] --> Open Open --> Transmitter : BindTransmitter Open --> Receiver : BindReceiver Open --> Transceiver : BindTransceiver Transmitter --> Closed : Unbind/Error Receiver --> Closed : Unbind/Error Transceiver --> Closed : Unbind/Error Closed --> [*] ``` -------------------------------- ### Monitoring Parser Performance with Tracing and Timing in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/StreamParser.md This C# code demonstrates how to monitor the performance of the StreamParser. It includes enabling verbose tracing using `TraceSwitch` for debugging purposes and measuring the time taken to parse a PDU using `Stopwatch`. This helps in identifying performance bottlenecks and understanding parsing durations. ```csharp // Enable tracing for debugging TraceSwitch traceSwitch = new TraceSwitch("StreamParserSwitch", "Stream parser switch"); traceSwitch.Level = TraceLevel.Verbose; // Monitor parser performance Stopwatch stopwatch = Stopwatch.StartNew(); PDU pdu = WaitPDU(); stopwatch.Stop(); Console.WriteLine($"PDU parsing took: {stopwatch.ElapsedMilliseconds}ms"); ``` -------------------------------- ### Factory Pattern for PDUTransmitter Creation in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/PDUTransmitter.md Implements the Factory pattern to abstract the creation of PDUTransmitter instances. This promotes loose coupling and makes it easier to manage the lifecycle and dependencies of transmitters. ```csharp using Jamaa.Smpp.Net.Network; using System; public static class PDUTransmitterFactory { public static PDUTransmitter Create(TcpIpSession session) { if (session == null) throw new ArgumentNullException(nameof(session)); return new PDUTransmitter(session); } } ``` -------------------------------- ### SmppClient Properties Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClient.md This section details the properties of the SmppClient, categorized into Connection Properties and Configuration Properties. ```APIDOC ## Properties ### Connection Properties | Property | Type | Description | |----------|------|-------------| | `ConnectionState` | `SmppConnectionState` | Current connection state (Closed, Connecting, Connected) | | `Started` | `bool` | Indicates if the client is started | | `Properties` | `SmppConnectionProperties` | Connection configuration properties | | `LastException` | `Exception` | Last exception that occurred during connection | ### Configuration Properties | Property | Type | Description | |----------|------|-------------| | `AutoReconnectDelay` | `int` | Delay in milliseconds before attempting reconnection | | `KeepAliveInterval` | `int` | Interval for sending EnquireLink PDUs | | `ConnectionTimeout` | `int` | Timeout for synchronous operations | | `Name` | `string` | Name identifier for this client instance | | `SmppEncodingService` | `SmppEncodingService` | Encoding service for character handling | ``` -------------------------------- ### Integrating PDUTransmitter with SmppClientSession in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/PDUTransmitter.md Illustrates how a PDUTransmitter is integrated within an SmppClientSession class. It shows the initialization of the transmitter with a TCP session and a method for sending PDUs with internal error logging. ```csharp public class SmppClientSession { private PDUTransmitter vTrans; private TcpIpSession vTcpIpSession; // Assume this is initialized elsewhere private ILog _Log; // Assume this is a logging interface private void AssembleComponents() { // Create PDUTransmitter with TCP session vTrans = new PDUTransmitter(vTcpIpSession); } private void SendPduBase(PDU pdu) { try { vTrans.Send(pdu); } catch (Exception ex) { // Log error and handle _Log.ErrorFormat("PDU send operation failed - {0}", ex, ex.Message); throw; } } } ``` -------------------------------- ### Decorator Pattern for Logging PDUTransmitter in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/PDUTransmitter.md Demonstrates the Decorator pattern by creating a LoggingPDUTransmitter that wraps the base PDUTransmitter. It adds logging capabilities before and after sending a PDU without altering its core functionality. ```csharp using Jamaa.Smpp.Net.Network; using Jamaa.Smpp.Net.PDU; using System; public class LoggingPDUTransmitter : PDUTransmitter { private readonly ILog _logger; // Assume ILog is a logging interface public LoggingPDUTransmitter(TcpIpSession session, ILog logger) : base(session) { _logger = logger; } public new void Send(PDU pdu) { _logger.Debug($"Sending PDU: {pdu.Header.CommandType}"); base.Send(pdu); _logger.Debug("PDU sent successfully"); } } ``` -------------------------------- ### Send Message with Custom Properties - C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/ShortMessage.md Illustrates sending a message with custom properties, such as source address, a user message reference, and enabling the submission of the user message reference. ```csharp // Create message with custom properties TextMessage customMessage = new TextMessage(); customMessage.SourceAddress = "MyApp"; customMessage.DestinationAddress = "1234567890"; customMessage.Text = "Custom message"; customMessage.RegisterDeliveryNotification = true; customMessage.UserMessageReference = "MSG-001"; customMessage.SubmitUserMessageReference = true; // Send with custom reference client.SendMessage(customMessage); ``` -------------------------------- ### PDU Operations Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Documentation for sending PDUs, both synchronously and asynchronously. ```APIDOC ## PDU Operations ### Send PDU (Synchronous) **Purpose**: Sends a request PDU and waits for response. **Parameters**: - `pdu` (RequestPDU): The request PDU to send. - `timeout` (int, Optional): Timeout for response (uses default if not specified). **Returns**: `ResponsePDU` from SMSC. **Behavior**: - Validates session state and PDU compatibility. - Sends PDU via `PDUTransmitter`. - Waits for response via `ResponseHandler`. - Handles timeout scenarios. ### Send PDU (Asynchronous) **Purpose**: Sends a request PDU asynchronously. **Parameters**: - `pdu` (RequestPDU): The request PDU to send. - `timeout` (int): Timeout for response. - `callback` (AsyncCallback): Callback for completion notification. - `state` (object): User state object. **Returns**: `IAsyncResult` for async operation tracking. **Methods**: - `BeginSendPdu(RequestPDU pdu, int timeout, AsyncCallback callback, object @object)` - `BeginSendPdu(RequestPDU pdu, AsyncCallback callback, object @object)` - `EndSendPdu(IAsyncResult result)` ``` -------------------------------- ### Encode/Decode C-String with SmppEncodingService (C#) Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Demonstrates encoding a string into a null-terminated C-style byte array and decoding a byte array back into a string. Supports ASCII and other encodings. Requires an instance of SmppEncodingService. ```csharp // Create encoding service SmppEncodingService encodingService = new SmppEncodingService(); // Encode string as C-string string text = "Hello, World!"; byte[] asciiBytes = encodingService.GetBytesFromCString(text, DataCoding.ASCII); // Result: [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33, 0] // Decode C-string string decoded = encodingService.GetCStringFromBytes(asciiBytes, DataCoding.ASCII); // Result: "Hello, World!" ``` -------------------------------- ### Initialize SmppEncodingService with Custom UCS2 Encoding Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Initializes the SmppEncodingService with a user-specified UCS2 encoding. This allows for flexibility in handling different byte orders or specific Unicode implementations for UCS2 data. ```csharp public SmppEncodingService(System.Text.Encoding ucs2Encoding) { // Initialization logic here } ``` -------------------------------- ### Event Details Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppClientSession.md Detailed information about PduReceived and SessionClosed events, including their arguments. ```APIDOC ## Event Details ### PduReceived **Purpose**: Raised when a request PDU is received from the SMSC. **Event Args**: `PduReceivedEventArgs` - `Request`: The received request PDU. - `Response`: Optional response PDU to send back. ### SessionClosed **Purpose**: Raised when the session is closed. **Event Args**: `SmppSessionClosedEventArgs` - `Reason`: Reason for session closure. - `Exception`: Exception that caused closure (if any). ``` -------------------------------- ### String Handling Methods Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Methods for general string encoding and decoding to/from byte arrays, supporting various data codings. ```APIDOC ## String Handling Methods ### GetBytesFromString ```csharp public byte[] GetBytesFromString(string str) public byte[] GetBytesFromString(string str, DataCoding dataCoding) ``` **Description**: Converts a string to a byte array using the specified or default data coding. ### GetStringFromBytes ```csharp public string GetStringFromBytes(byte[] data) public string GetStringFromBytes(byte[] data, DataCoding dataCoding) ``` **Description**: Converts a byte array to a string using the specified or default data coding. ``` -------------------------------- ### Numeric Conversion Methods Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Methods for converting integers and shorts to and from byte arrays. ```APIDOC ## Numeric Conversion Methods ### GetBytesFromInt ```csharp public byte[] GetBytesFromInt(uint value) ``` **Description**: Converts an unsigned integer to a byte array. ### GetIntFromBytes ```csharp public uint GetIntFromBytes(byte[] data) ``` **Description**: Converts a byte array to an unsigned integer. ### GetBytesFromShort ```csharp public byte[] GetBytesFromShort(ushort value) ``` **Description**: Converts an unsigned short to a byte array. ### GetShortFromBytes ```csharp public ushort GetShortFromBytes(byte[] data) ``` **Description**: Converts a byte array to an unsigned short. ``` -------------------------------- ### Monitoring PDU Transmission Performance in C# Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/PDUTransmitter.md Demonstrates how to measure the time taken for a single PDU transmission using Stopwatch. This is useful for performance tuning and identifying bottlenecks in the communication. ```csharp using System.Diagnostics; using Jamaa.Smpp.Net.Network; using Jamaa.Smpp.Net.PDU; // Assuming 'transmitter' and 'pdu' are initialized Stopwatch stopwatch = Stopwatch.StartNew(); transmitter.Send(pdu); stopwatch.Stop(); Console.WriteLine($"PDU transmission took: {stopwatch.ElapsedMilliseconds}ms"); ``` -------------------------------- ### C-String Handling Methods Source: https://github.com/adhamawadhi/jamaasmpp/blob/master/docs/SmppEncodingService.md Methods for handling C-style null-terminated strings, including conversion to and from byte arrays with specified data codings. ```APIDOC ## C-String Handling Methods ### GetBytesFromCString ```csharp public byte[] GetBytesFromCString(string cStr) public byte[] GetBytesFromCString(string cStr, DataCoding dataCoding) public byte[] GetBytesFromCString(string cStr, DataCoding dataCoding, bool nullTerminated) ``` **Description**: Converts a C-style string to a byte array. Overloads allow specifying data coding and null termination behavior. ### GetCStringFromBytes ```csharp public string GetCStringFromBytes(byte[] data) public string GetCStringFromBytes(byte[] data, DataCoding dataCoding) ``` **Description**: Converts a byte array to a C-style string. Allows specifying the data coding for decoding. ```