netget/server/ethernet_ip/
mod.rs1pub mod actions;
2pub mod codec;
3use crate::protocol::SpawnContext;
4use anyhow::{ensure, Result};
5use std::{net::SocketAddr, sync::Arc};
6pub async fn spawn(ctx: SpawnContext) -> Result<SocketAddr> {
7 let types = ctx
8 .startup_params
9 .as_ref()
10 .map(|p| p.get_optional_array("attribute_types"))
11 .transpose()?
12 .flatten()
13 .cloned()
14 .unwrap_or_default();
15 ensure!(types.len() <= 128, "at most 128 attribute schemas");
16 for t in &types {
17 let mut a = t.clone();
18 a["type"] = serde_json::json!("ethernet_ip_get");
19 codec::validate(&a)?;
20 }
21 let listener =
24 crate::server::socket_helpers::create_reusable_tcp_listener(ctx.legacy_listen_addr())
25 .await?;
26 let addr = listener.local_addr()?;
27 let socket = tokio::net::UdpSocket::bind(addr).await?;
28 let schemas = types.clone();
29 let addr = crate::server::ics_support::spawn_accept_bounded(
30 ctx.clone(),
31 Arc::new(actions::EthernetIpProtocol),
32 move || {
33 let mut device = codec::Device::default();
34 device.types = schemas.clone();
35 device
36 },
37 &actions::EVENTS,
38 listener,
39 )
40 .await?;
41 let state = ctx.state.clone();
42 let sid = ctx.server_id;
43 state
44 .spawn_server_task(sid, async move {
45 let mut buf = [0; codec::MAX_FRAME + 1];
46 while let Ok((n, peer)) = socket.recv_from(&mut buf).await {
47 if n == 24
48 && buf[0..4] == [0x63, 0, 0, 0]
49 && buf[4..12] == [0; 8]
50 && buf[20..24] == [0; 4]
51 {
52 let mut context = [0; 8];
53 context.copy_from_slice(&buf[12..20]);
54 let response = codec::encapsulate(0x63, 0, context, 0, &codec::identity(addr));
55 let _ = socket.send_to(&response, peer).await;
56 }
57 }
58 })
59 .await;
60 Ok(addr)
61}