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