1use rns_core::transport::types::InterfaceId;
2use rns_core::types::{DestHash, IdentityHash, LinkId, PacketHash};
3use rns_net::destination::AnnouncedIdentity;
4use rns_net::Callbacks;
5
6use crate::encode::{to_base64, to_hex};
7use crate::state::*;
8
9pub struct CtlCallbacks {
11 state: SharedState,
12 ws_broadcast: WsBroadcast,
13}
14
15impl CtlCallbacks {
16 pub fn new(state: SharedState, ws_broadcast: WsBroadcast) -> Self {
17 CtlCallbacks {
18 state,
19 ws_broadcast,
20 }
21 }
22}
23
24impl Callbacks for CtlCallbacks {
25 fn on_announce(&mut self, announced: AnnouncedIdentity) {
26 let record = make_announce_record(&announced);
27 let event = WsEvent::announce(&record);
28 push_announce(&self.state, record);
29 broadcast(&self.ws_broadcast, event);
30 }
31
32 fn on_path_updated(&mut self, _dest_hash: DestHash, _hops: u8) {
33 }
35
36 fn on_local_delivery(&mut self, dest_hash: DestHash, raw: Vec<u8>, packet_hash: PacketHash) {
37 let record = PacketRecord {
38 dest_hash: to_hex(&dest_hash.0),
39 packet_hash: to_hex(&packet_hash.0),
40 data_base64: to_base64(&raw),
41 received_at: rns_net::time::now(),
42 };
43 let event = WsEvent::packet(&record);
44 push_packet(&self.state, record);
45 broadcast(&self.ws_broadcast, event);
46 }
47
48 fn on_proof(&mut self, dest_hash: DestHash, packet_hash: PacketHash, rtt: f64) {
49 let record = ProofRecord {
50 dest_hash: to_hex(&dest_hash.0),
51 packet_hash: to_hex(&packet_hash.0),
52 rtt,
53 };
54 let event = WsEvent::proof(&record);
55 push_proof(&self.state, record);
56 broadcast(&self.ws_broadcast, event);
57 }
58
59 fn on_proof_requested(&mut self, _dest_hash: DestHash, _packet_hash: PacketHash) -> bool {
60 true
61 }
62
63 fn on_link_established(
64 &mut self,
65 link_id: LinkId,
66 _dest_hash: DestHash,
67 rtt: f64,
68 is_initiator: bool,
69 ) {
70 let node_handle = {
72 let s = self.state.read().unwrap();
73 s.node_handle.clone()
74 };
75 if let Some(nh) = node_handle {
76 if let Some(node) = nh.lock().unwrap().as_ref() {
77 let _ = node.set_resource_strategy(link_id.0, 1); }
79 }
80
81 let record = LinkEventRecord {
82 link_id: to_hex(&link_id.0),
83 event_type: "established".into(),
84 is_initiator: Some(is_initiator),
85 rtt: Some(rtt),
86 identity_hash: None,
87 reason: None,
88 };
89 let event = WsEvent::link(&record);
90 push_link_event(&self.state, record);
91 broadcast(&self.ws_broadcast, event);
92 }
93
94 fn on_link_closed(&mut self, link_id: LinkId, reason: Option<rns_core::link::TeardownReason>) {
95 let record = LinkEventRecord {
96 link_id: to_hex(&link_id.0),
97 event_type: "closed".into(),
98 is_initiator: None,
99 rtt: None,
100 identity_hash: None,
101 reason: reason.map(|r| format!("{:?}", r)),
102 };
103 let event = WsEvent::link(&record);
104 push_link_event(&self.state, record);
105 broadcast(&self.ws_broadcast, event);
106 }
107
108 fn on_remote_identified(
109 &mut self,
110 link_id: LinkId,
111 identity_hash: IdentityHash,
112 _public_key: [u8; 64],
113 ) {
114 let record = LinkEventRecord {
115 link_id: to_hex(&link_id.0),
116 event_type: "identified".into(),
117 is_initiator: None,
118 rtt: None,
119 identity_hash: Some(to_hex(&identity_hash.0)),
120 reason: None,
121 };
122 let event = WsEvent::link(&record);
123 push_link_event(&self.state, record);
124 broadcast(&self.ws_broadcast, event);
125 }
126
127 fn on_resource_received(&mut self, link_id: LinkId, data: Vec<u8>, metadata: Option<Vec<u8>>) {
128 let record = ResourceEventRecord {
129 link_id: to_hex(&link_id.0),
130 event_type: "received".into(),
131 data_base64: Some(to_base64(&data)),
132 metadata_base64: metadata.as_ref().map(|m| to_base64(m)),
133 error: None,
134 received: None,
135 total: None,
136 };
137 let event = WsEvent::resource(&record);
138 push_resource_event(&self.state, record);
139 broadcast(&self.ws_broadcast, event);
140 }
141
142 fn on_resource_completed(&mut self, link_id: LinkId) {
143 let record = ResourceEventRecord {
144 link_id: to_hex(&link_id.0),
145 event_type: "completed".into(),
146 data_base64: None,
147 metadata_base64: None,
148 error: None,
149 received: None,
150 total: None,
151 };
152 let event = WsEvent::resource(&record);
153 push_resource_event(&self.state, record);
154 broadcast(&self.ws_broadcast, event);
155 }
156
157 fn on_resource_failed(&mut self, link_id: LinkId, error: String) {
158 let record = ResourceEventRecord {
159 link_id: to_hex(&link_id.0),
160 event_type: "failed".into(),
161 data_base64: None,
162 metadata_base64: None,
163 error: Some(error),
164 received: None,
165 total: None,
166 };
167 let event = WsEvent::resource(&record);
168 push_resource_event(&self.state, record);
169 broadcast(&self.ws_broadcast, event);
170 }
171
172 fn on_resource_progress(&mut self, link_id: LinkId, received: usize, total: usize) {
173 let record = ResourceEventRecord {
174 link_id: to_hex(&link_id.0),
175 event_type: "progress".into(),
176 data_base64: None,
177 metadata_base64: None,
178 error: None,
179 received: Some(received),
180 total: Some(total),
181 };
182 let event = WsEvent::resource(&record);
183 push_resource_event(&self.state, record);
184 broadcast(&self.ws_broadcast, event);
185 }
186
187 fn on_resource_accept_query(
188 &mut self,
189 _link_id: LinkId,
190 _resource_hash: Vec<u8>,
191 _transfer_size: u64,
192 _has_metadata: bool,
193 ) -> bool {
194 true
195 }
196
197 fn on_channel_message(&mut self, link_id: LinkId, msgtype: u16, payload: Vec<u8>) {
198 let record = PacketRecord {
199 dest_hash: format!("channel:{}:{}", to_hex(&link_id.0), msgtype),
200 packet_hash: String::new(),
201 data_base64: to_base64(&payload),
202 received_at: rns_net::time::now(),
203 };
204 let event = WsEvent::packet(&record);
205 push_packet(&self.state, record);
206 broadcast(&self.ws_broadcast, event);
207 }
208
209 fn on_response(&mut self, link_id: LinkId, request_id: [u8; 16], data: Vec<u8>) {
210 let record = PacketRecord {
211 dest_hash: format!("response:{}:{}", to_hex(&link_id.0), to_hex(&request_id)),
212 packet_hash: String::new(),
213 data_base64: to_base64(&data),
214 received_at: rns_net::time::now(),
215 };
216 let event = WsEvent::packet(&record);
217 push_packet(&self.state, record);
218 broadcast(&self.ws_broadcast, event);
219 }
220
221 fn on_direct_connect_established(&mut self, link_id: LinkId, interface_id: InterfaceId) {
222 let record = LinkEventRecord {
223 link_id: to_hex(&link_id.0),
224 event_type: "direct_established".into(),
225 is_initiator: None,
226 rtt: None,
227 identity_hash: None,
228 reason: Some(format!("interface_id={}", interface_id.0)),
229 };
230 let event = WsEvent::link(&record);
231 push_link_event(&self.state, record);
232 broadcast(&self.ws_broadcast, event);
233 }
234
235 fn on_direct_connect_failed(&mut self, link_id: LinkId, reason: u8) {
236 let record = LinkEventRecord {
237 link_id: to_hex(&link_id.0),
238 event_type: "direct_failed".into(),
239 is_initiator: None,
240 rtt: None,
241 identity_hash: None,
242 reason: Some(format!("reason_code={}", reason)),
243 };
244 let event = WsEvent::link(&record);
245 push_link_event(&self.state, record);
246 broadcast(&self.ws_broadcast, event);
247 }
248}