use std::net::IpAddr;
use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use smpp34::client::{SmppClient, SmppClientListener, BIND_TYPE, SMSC};
use smpp34::{
bind_transceiver, bind_transceiver_resp, query_sm, query_sm_resp, replace_sm, replace_sm_resp,
submit_sm_multi, submit_sm_multi_resp, DestAddress, SmppConnectionInformation, SmppError,
SmppServer, SmppServerListener, UnsuccessSme,
};
use tokio::sync::{oneshot, Mutex};
struct Handler;
#[async_trait]
impl SmppServerListener for Handler {
async fn on_bind_transceiver(
&self,
req: bind_transceiver,
_c: &SmppConnectionInformation,
_s: &String,
) -> bind_transceiver_resp {
req.accept("TEST-SMSC".to_string(), Some(0x34))
}
async fn on_query_sm(
&self,
req: query_sm,
_c: &SmppConnectionInformation,
_s: &String,
) -> query_sm_resp {
let message_id = req.message_id.clone();
req.accept(
message_id,
"2401011200000".to_string(),
2,
0,
)
}
async fn on_replace_sm(
&self,
req: replace_sm,
_c: &SmppConnectionInformation,
_s: &String,
) -> replace_sm_resp {
assert_eq!(req.short_message, b"replacement");
req.accept()
}
async fn on_submit_sm_multi(
&self,
req: submit_sm_multi,
_c: &SmppConnectionInformation,
_s: &String,
) -> submit_sm_multi_resp {
assert_eq!(req.number_of_dests, 2);
assert_eq!(req.short_message, b"broadcast");
req.accept(
"multi-1".to_string(),
vec![UnsuccessSme {
dest_addr_ton: 1,
dest_addr_npi: 1,
destination_addr: "31699999999".to_string(),
error_status_code: SmppError::ESME_RINVDSTADR as u32,
}],
)
}
}
struct Binder {
tx: Mutex<Option<oneshot::Sender<Arc<SMSC>>>>,
}
#[async_trait]
impl SmppClientListener for Binder {
async fn on_smsc_bound(&self, smsc: SMSC, _s: &String) {
if let Some(tx) = self.tx.lock().await.take() {
let _ = tx.send(Arc::new(smsc));
}
}
}
fn free_port() -> u16 {
std::net::TcpListener::bind("127.0.0.1:0")
.unwrap()
.local_addr()
.unwrap()
.port()
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn query_and_replace_round_trip() {
let port = free_port();
let mut server = SmppServer::new(IpAddr::from([127, 0, 0, 1]), port, Arc::new(Handler));
server.start().await;
tokio::time::sleep(Duration::from_millis(100)).await;
let (tx, rx) = oneshot::channel();
let binder = Arc::new(Binder {
tx: Mutex::new(Some(tx)),
});
let mut client = SmppClient::new(
"127.0.0.1".to_string(),
port,
false,
BIND_TYPE::TRX,
"u".to_string(),
"p".to_string(),
String::new(),
1,
1,
String::new(),
binder,
16,
);
client.start().await;
let smsc = tokio::time::timeout(Duration::from_secs(5), rx)
.await
.expect("bind timed out")
.expect("bind channel dropped");
assert!(smsc.can_send());
let qresp = smsc
.send_query_sm("MSGID-42".to_string(), 1, 1, "12345".to_string())
.await
.expect("query_sm failed");
assert!(qresp.is_success());
assert_eq!(qresp.message_id, "MSGID-42");
assert_eq!(qresp.message_state, 2);
assert_eq!(qresp.final_date, "2401011200000");
let rresp = smsc
.send_replace_sm(
"MSGID-42".to_string(),
1,
1,
"12345".to_string(),
String::new(),
String::new(),
0,
0,
b"replacement".to_vec(),
)
.await
.expect("replace_sm failed");
assert!(rresp.is_success());
let mresp = smsc
.send_submit_sm_multi(
String::new(),
1,
1,
"12345".to_string(),
vec![
DestAddress::sme("31600000000"),
DestAddress::distribution_list("vip-list"),
],
0,
0,
0,
String::new(),
String::new(),
0,
0,
0,
0,
b"broadcast".to_vec(),
)
.await
.expect("submit_sm_multi failed");
assert!(mresp.is_success());
assert_eq!(mresp.message_id.as_deref(), Some("multi-1"));
assert_eq!(mresp.no_unsuccess, 1);
assert_eq!(mresp.unsuccess_sme.len(), 1);
assert_eq!(mresp.unsuccess_sme[0].destination_addr, "31699999999");
client.stop().await;
}