# SMPP Codec (Rust)
A Rust library for encoding and decoding Short Message Peer-to-Peer (SMPP) v3.4 Protocol Data Units (PDUs).
> [!WARNING]
> **Disclaimer**:Portions of this codebase were generated by Google's Gemini AI.
> While efforts have been made to ensure correctness, users should review and test the code thoroughly before using it in production environments.
## Features
- **PDU Support**: Currently supports Session Management PDUs (Bind, Unbind, EnquireLink, AlertNotification, Outlbind, GenericNack).
- **TLV Support**: Includes a comprehensive list of Tag-Length-Value (TLV) optional parameters.
- **Zero-Dependency Core**: Built with standard library usages (mostly) to keep it lightweight.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
smpp-codec = { path = "." } # Or git url
```
### Example: Binding as Transceiver
```rust
use smpp_codec::common::{BindMode, Ton, Npi};
use smpp_codec::pdus::BindRequest;
fn main() {
let bind_req = BindRequest::new(
1, // Sequence Number
BindMode::Transceiver,
"my_system_id".to_string(),
"password".to_string(),
).with_address_range(Ton::International, Npi::Isdn, "12345".to_string());
let mut buffer = Vec::new();
bind_req.encode(&mut buffer).unwrap();
// Send `buffer` over TCP stream...
}
```
### 2. Submit Short Message
```rust
use smpp_codec::pdus::{SubmitSmRequest, MessageSplitter, SplitMode, EncodingType};
fn main() {
let text = "Hello, world!".to_string();
// Split message (handles encoding and valid chunking)
let (parts, data_coding) = MessageSplitter::split(
text,
EncodingType::Gsm7Bit,
SplitMode::Udh // Use UDH for concatenation
).unwrap();
// Iterate over parts and send each PDU
for (i, part) in parts.into_iter().enumerate() {
let mut submit_req = SubmitSmRequest::new(
(i + 2) as u32, // Sequence Number
"source_addr".to_string(),
"dest_addr".to_string(),
part,
);
submit_req.data_coding = data_coding; // Important: Set correct encoding!
let mut buffer = Vec::new();
submit_req.encode(&mut buffer).unwrap();
// Send buffer...
}
}
```
### 3. Deliver Short Message
(Included in `examples/deliver_sm.rs`)
```rust
use smpp_codec::pdus::{DeliverSmRequest, MessageSplitter, SplitMode, EncodingType};
fn main() {
let text = "Incoming message...".to_string();
// Split message
let (parts, data_coding) = MessageSplitter::split(
text,
EncodingType::Gsm7Bit,
SplitMode::Udh
).unwrap();
let parts_len = parts.len();
for (i, part) in parts.into_iter().enumerate() {
let mut deliver_req = DeliverSmRequest::new(
(i + 100) as u32,
"sender".to_string(),
"shortcode".to_string(),
part,
);
deliver_req.data_coding = data_coding;
// CRITICAL: Set UDHI bit (0x40) if using UDH
if parts_len > 1 {
deliver_req.esm_class |= 0x40;
}
let mut buffer = Vec::new();
deliver_req.encode(&mut buffer).unwrap();
// Send buffer...
}
}
```
### 4. Unbind
```rust
use smpp_codec::pdus::UnbindRequest;
fn main() {
let unbind_req = UnbindRequest::new(3); // Sequence Number
let mut buffer = Vec::new();
unbind_req.encode(&mut buffer).unwrap();
}
```
## Running cargo test --test benchmarks --release -- --nocapture
| BindRequest | 2.11ms | 47.48 | 46.71ms | 2.14 |
| BindResponse | 6.26ms | 15.97 | 11.09ms | 9.02 |
| OutbindRequest | 12.68ms | 7.89 | 12.51ms | 7.99 |
| UnbindRequest | 0.61ms | 162.63 | 0.23ms | 434.40 |
| UnbindResponse | 0.43ms | 234.69 | 5.27ms | 18.96 |
| EnquireLinkRequest | 0.36ms | 274.65 | 0.18ms | 543.77 |
| EnquireLinkResponse | 0.41ms | 245.64 | 4.79ms | 20.89 |
| GenericNack | 0.40ms | 252.78 | 30.67ms | 3.26 |
| AlertNotification | 13.50ms | 7.41 | 13.38ms | 7.48 |
| SubmitSmRequest (Multi)| 2.81s | 10.66 | 10.37s | 2.89 |
| SubmitSmResponse | 39.00ms | 2.56 | 36.65ms | 2.73 |
| DeliverSmRequest | 5.34ms | 18.73 | 47.83ms | 2.09 |
| DeliverSmResponse | 0.42ms | 237.53 | 5.30ms | 18.86 |
| CancelSmRequest | 20.31ms | 4.92 | 19.05ms | 5.25 |
| CancelSmResponse | 0.42ms | 240.56 | 5.24ms | 19.09 |
| QuerySmRequest | 13.44ms | 7.44 | 12.70ms | 7.88 |
| QuerySmResponse | 13.31ms | 7.51 | 11.57ms | 8.65 |
## License
This project is licensed under the Apache-2.0 license.
## Running Tests
```sh
cargo test
```