Skip to main content

tcp_receive_once/
tcp_receive_once.rs

1use std::{
2    env, process,
3    time::{Duration, Instant},
4};
5
6use rns_embedded_runtime::{
7    node::NODE_EXTENSION_ID_RECEIVED_SUMMARY, EmbeddedNode, NodeBackendConfig, NodeConfig,
8    NodeEventKind, NodeTransportMode, PollResult, RuntimeConfig, TcpServerConfig,
9};
10
11const SERVER_LXMF_ADDRESS: [u8; 16] = [0x44; 16];
12const SERVER_STORE_IDENTITY: [u8; 32] = [0x55; 32];
13
14fn main() {
15    let Some(port) = env::args().nth(1).and_then(|value| value.parse::<u16>().ok()) else {
16        eprintln!("usage: cargo run -p rns-embedded-runtime --example tcp_receive_once -- <port>");
17        process::exit(2);
18    };
19
20    println!("LISTENING port={port} destination={}", encode_hex(&SERVER_LXMF_ADDRESS));
21
22    let node = EmbeddedNode::new();
23    let subscription = node.subscribe_events().expect("subscribe");
24    node.start(NodeConfig {
25        runtime: RuntimeConfig {
26            store_identity: SERVER_STORE_IDENTITY,
27            lxmf_address: SERVER_LXMF_ADDRESS,
28            node_mode: NodeTransportMode::TcpServer,
29            announce_interval_ms: 1_000,
30            max_outbound_queue: 8,
31            max_events: 32,
32            capture_defaults: Default::default(),
33        },
34        backend: NodeBackendConfig::TcpServer(TcpServerConfig { listen_port: port }),
35    })
36    .expect("start tcp server");
37    node.set_network_provisioned(true).expect("set network provisioned");
38
39    let deadline = Instant::now() + Duration::from_secs(10);
40    loop {
41        match subscription.next(500).expect("poll") {
42            PollResult::Event(event) => match event.kind {
43                NodeEventKind::Extension {
44                    extension_id: NODE_EXTENSION_ID_RECEIVED_SUMMARY,
45                    value0,
46                    value1,
47                } => {
48                    println!("RECEIVED sequence={value0} bytes={value1}");
49                    break;
50                }
51                NodeEventKind::Error { error, .. } => {
52                    eprintln!("ERROR {error:?}");
53                    process::exit(1);
54                }
55                _ => {}
56            },
57            PollResult::NodeRestarted { .. } | PollResult::NodeStopped => continue,
58            PollResult::Timeout if Instant::now() < deadline => continue,
59            PollResult::Timeout => {
60                eprintln!("timeout waiting for inbound message");
61                process::exit(1);
62            }
63            other => {
64                eprintln!("unexpected poll result: {other:?}");
65            }
66        }
67    }
68
69    node.stop().expect("stop");
70}
71
72fn encode_hex(bytes: &[u8]) -> String {
73    let mut out = String::with_capacity(bytes.len() * 2);
74    for byte in bytes {
75        use std::fmt::Write as _;
76        let _ = write!(&mut out, "{byte:02x}");
77    }
78    out
79}