1use rns_core::types::{DestHash, IdentityHash, LinkId, PacketHash};
2use rns_net::destination::AnnouncedIdentity;
3use rns_net::Callbacks;
4
5use crate::encode::{to_base64, to_hex};
6use crate::state::*;
7
8pub struct CtlCallbacks {
10 state: SharedState,
11 ws_broadcast: WsBroadcast,
12}
13
14impl CtlCallbacks {
15 pub fn new(state: SharedState, ws_broadcast: WsBroadcast) -> Self {
16 CtlCallbacks { state, ws_broadcast }
17 }
18}
19
20impl Callbacks for CtlCallbacks {
21 fn on_announce(&mut self, announced: AnnouncedIdentity) {
22 let record = make_announce_record(&announced);
23 let event = WsEvent::announce(&record);
24 push_announce(&self.state, record);
25 broadcast(&self.ws_broadcast, event);
26 }
27
28 fn on_path_updated(&mut self, _dest_hash: DestHash, _hops: u8) {
29 }
31
32 fn on_local_delivery(&mut self, dest_hash: DestHash, raw: Vec<u8>, packet_hash: PacketHash) {
33 let record = PacketRecord {
34 dest_hash: to_hex(&dest_hash.0),
35 packet_hash: to_hex(&packet_hash.0),
36 data_base64: to_base64(&raw),
37 received_at: rns_net::time::now(),
38 };
39 let event = WsEvent::packet(&record);
40 push_packet(&self.state, record);
41 broadcast(&self.ws_broadcast, event);
42 }
43
44 fn on_proof(&mut self, dest_hash: DestHash, packet_hash: PacketHash, rtt: f64) {
45 let record = ProofRecord {
46 dest_hash: to_hex(&dest_hash.0),
47 packet_hash: to_hex(&packet_hash.0),
48 rtt,
49 };
50 let event = WsEvent::proof(&record);
51 push_proof(&self.state, record);
52 broadcast(&self.ws_broadcast, event);
53 }
54
55 fn on_proof_requested(&mut self, _dest_hash: DestHash, _packet_hash: PacketHash) -> bool {
56 true
57 }
58
59 fn on_link_established(&mut self, link_id: LinkId, _dest_hash: DestHash, rtt: f64, is_initiator: bool) {
60 let node_handle = {
62 let s = self.state.read().unwrap();
63 s.node_handle.clone()
64 };
65 if let Some(nh) = node_handle {
66 if let Some(node) = nh.lock().unwrap().as_ref() {
67 let _ = node.set_resource_strategy(link_id.0, 1); }
69 }
70
71 let record = LinkEventRecord {
72 link_id: to_hex(&link_id.0),
73 event_type: "established".into(),
74 is_initiator: Some(is_initiator),
75 rtt: Some(rtt),
76 identity_hash: None,
77 reason: None,
78 };
79 let event = WsEvent::link(&record);
80 push_link_event(&self.state, record);
81 broadcast(&self.ws_broadcast, event);
82 }
83
84 fn on_link_closed(&mut self, link_id: LinkId, reason: Option<rns_core::link::TeardownReason>) {
85 let record = LinkEventRecord {
86 link_id: to_hex(&link_id.0),
87 event_type: "closed".into(),
88 is_initiator: None,
89 rtt: None,
90 identity_hash: None,
91 reason: reason.map(|r| format!("{:?}", r)),
92 };
93 let event = WsEvent::link(&record);
94 push_link_event(&self.state, record);
95 broadcast(&self.ws_broadcast, event);
96 }
97
98 fn on_remote_identified(&mut self, link_id: LinkId, identity_hash: IdentityHash, _public_key: [u8; 64]) {
99 let record = LinkEventRecord {
100 link_id: to_hex(&link_id.0),
101 event_type: "identified".into(),
102 is_initiator: None,
103 rtt: None,
104 identity_hash: Some(to_hex(&identity_hash.0)),
105 reason: None,
106 };
107 let event = WsEvent::link(&record);
108 push_link_event(&self.state, record);
109 broadcast(&self.ws_broadcast, event);
110 }
111
112 fn on_resource_received(&mut self, link_id: LinkId, data: Vec<u8>, metadata: Option<Vec<u8>>) {
113 let record = ResourceEventRecord {
114 link_id: to_hex(&link_id.0),
115 event_type: "received".into(),
116 data_base64: Some(to_base64(&data)),
117 metadata_base64: metadata.as_ref().map(|m| to_base64(m)),
118 error: None,
119 received: None,
120 total: None,
121 };
122 let event = WsEvent::resource(&record);
123 push_resource_event(&self.state, record);
124 broadcast(&self.ws_broadcast, event);
125 }
126
127 fn on_resource_completed(&mut self, link_id: LinkId) {
128 let record = ResourceEventRecord {
129 link_id: to_hex(&link_id.0),
130 event_type: "completed".into(),
131 data_base64: None,
132 metadata_base64: None,
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_failed(&mut self, link_id: LinkId, error: String) {
143 let record = ResourceEventRecord {
144 link_id: to_hex(&link_id.0),
145 event_type: "failed".into(),
146 data_base64: None,
147 metadata_base64: None,
148 error: Some(error),
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_progress(&mut self, link_id: LinkId, received: usize, total: usize) {
158 let record = ResourceEventRecord {
159 link_id: to_hex(&link_id.0),
160 event_type: "progress".into(),
161 data_base64: None,
162 metadata_base64: None,
163 error: None,
164 received: Some(received),
165 total: Some(total),
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_accept_query(
173 &mut self,
174 _link_id: LinkId,
175 _resource_hash: Vec<u8>,
176 _transfer_size: u64,
177 _has_metadata: bool,
178 ) -> bool {
179 true
180 }
181
182 fn on_channel_message(&mut self, link_id: LinkId, msgtype: u16, payload: Vec<u8>) {
183 let record = PacketRecord {
184 dest_hash: format!("channel:{}:{}", to_hex(&link_id.0), msgtype),
185 packet_hash: String::new(),
186 data_base64: to_base64(&payload),
187 received_at: rns_net::time::now(),
188 };
189 let event = WsEvent::packet(&record);
190 push_packet(&self.state, record);
191 broadcast(&self.ws_broadcast, event);
192 }
193
194 fn on_response(&mut self, link_id: LinkId, request_id: [u8; 16], data: Vec<u8>) {
195 let record = PacketRecord {
196 dest_hash: format!("response:{}:{}", to_hex(&link_id.0), to_hex(&request_id)),
197 packet_hash: String::new(),
198 data_base64: to_base64(&data),
199 received_at: rns_net::time::now(),
200 };
201 let event = WsEvent::packet(&record);
202 push_packet(&self.state, record);
203 broadcast(&self.ws_broadcast, event);
204 }
205}