ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
consensus_integration.c
Go to the documentation of this file.
1
16#include <ascii-chat/session/consensus.h>
17#include <ascii-chat/network/consensus/metrics.h>
18#include <ascii-chat/common.h>
19#include <ascii-chat/log/logging.h>
20#include <ascii-chat/util/endian.h>
21#include <ascii-chat/util/time.h>
22#include <ascii-chat/network/packet.h>
23#include <string.h>
24
32static asciichat_error_t consensus_send_via_discovery(void *context, const uint8_t next_participant_id[16],
33 const uint8_t *packet, size_t packet_size) {
34 // context would be a discovery_session_t in real usage
35 // This is a placeholder showing the pattern
36
37 if (!context || !next_participant_id || !packet) {
38 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters");
39 }
40
41 // In real code:
42 // 1. Serialize the packet with proper headers
43 // 2. Send to ACDS with next_participant_id as recipient
44 // 3. ACDS will relay to that participant
45
46 log_debug("Consensus would send %zu bytes to participant %.*s via ACDS", packet_size, 16, next_participant_id);
47
48 return ASCIICHAT_OK;
49}
50
57static asciichat_error_t consensus_on_election_result(void *context, const uint8_t host_id[16],
58 const char host_address[64], uint16_t host_port,
59 const uint8_t backup_id[16], const char backup_address[64],
60 uint16_t backup_port) {
61 (void)backup_address; // unused in placeholder
62 (void)backup_port; // unused in placeholder
63
64 // context would be a discovery_session_t in real usage
65 if (!context || !host_id || !backup_id) {
66 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters");
67 }
68
69 // In real code:
70 // 1. Store host_id, backup_id, addresses, ports
71 // 2. If elected as host: Start hosting
72 // 3. If not elected: Connect to host or schedule reconnection
73
74 log_info("Consensus election result: host=%.*s backup=%.*s (addr=%s:%u)", 16, host_id, 16, backup_id, host_address,
75 host_port);
76
77 return ASCIICHAT_OK;
78}
79
86static asciichat_error_t consensus_get_metrics(void *context, const uint8_t my_id[16],
87 participant_metrics_t *out_metrics) {
88 // context would be a discovery_session_t in real usage
89 if (!context || !my_id || !out_metrics) {
90 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters");
91 }
92
93 // In real code:
94 // 1. Measure NAT tier via UPnP probe
95 // 2. Estimate upload bandwidth
96 // 3. Measure RTT to current host (or ACDS)
97 // 4. Send STUN probes and count success rate
98 // 5. Get public address from detected NAT result
99
100 // Placeholder with dummy metrics
101 memcpy(out_metrics->participant_id, my_id, 16);
102 out_metrics->nat_tier = 1; // Public NAT
103 out_metrics->upload_kbps = htonl(50000); // 50 Mbps
104 out_metrics->rtt_ns = htonl(25000000); // 25ms
105 out_metrics->stun_probe_success_pct = 95;
106 SAFE_STRNCPY(out_metrics->public_address, "203.0.113.42", sizeof(out_metrics->public_address));
107 out_metrics->public_port = htons(54321);
108 out_metrics->connection_type = 0; // Direct connection
109 out_metrics->measurement_time_ns = htonll(time_get_ns());
110 out_metrics->measurement_window_ns = htonll(5000000000ULL); // 5 second measurement window
111
112 log_debug("Consensus measured metrics: NAT tier=%d, upload=%u Kbps, RTT=%u ns", out_metrics->nat_tier,
113 ntohl(out_metrics->upload_kbps), ntohl(out_metrics->rtt_ns));
114
115 return ASCIICHAT_OK;
116}
117
129asciichat_error_t consensus_get_discovery_callbacks(void *context, session_consensus_callbacks_t *out_callbacks) {
130 if (!context || !out_callbacks) {
131 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters: context=%p, out_callbacks=%p", context, out_callbacks);
132 }
133
134 // Configure callbacks for discovery mode
135 out_callbacks->send_packet = consensus_send_via_discovery;
136 out_callbacks->on_election = consensus_on_election_result;
137 out_callbacks->get_metrics = consensus_get_metrics;
138 out_callbacks->election = NULL; // Use default election algorithm
139 out_callbacks->context = context;
140
141 return ASCIICHAT_OK;
142}
143
159asciichat_error_t consensus_create_for_discovery(const uint8_t session_id[16], const uint8_t my_id[16],
160 const uint8_t participant_ids[64][16], int num_participants,
161 void *discovery_context, session_consensus_t **out_consensus) {
162 (void)session_id; // Informational only, not needed by consensus itself
163
164 if (!my_id || !participant_ids || !discovery_context || !out_consensus) {
165 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters");
166 }
167
168 if (num_participants < 1 || num_participants > 64) {
169 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid participant count: %d", num_participants);
170 }
171
172 // Determine if we're the ring leader (for now, assume not - ACDS would manage this)
173 // In a real implementation, ACDS would tell us our position in the ring
174 bool is_leader = false; // This would be determined by ACDS
175
176 // Get callbacks configured for our mode
177 session_consensus_callbacks_t callbacks = {0};
178 asciichat_error_t err = consensus_get_discovery_callbacks(discovery_context, &callbacks);
179 if (err != ASCIICHAT_OK) {
180 return err;
181 }
182
183 // Create consensus with the callbacks
184 return session_consensus_create(my_id, is_leader, participant_ids, num_participants, &callbacks, out_consensus);
185}
186
196uint32_t consensus_suggest_timeout_ms(session_consensus_t *consensus, uint32_t current_timeout_ms) {
197 if (!consensus) {
198 return current_timeout_ms;
199 }
200
201 // Get time until next round in nanoseconds
202 uint64_t time_to_next_ns = session_consensus_time_until_next_round(consensus);
203
204 // Convert to milliseconds
205 uint64_t time_to_next_ms = time_ns_to_ms(time_to_next_ns);
206
207 // Return minimum of consensus deadline or current timeout
208 if (time_to_next_ms == 0) {
209 return 0; // Consensus needs immediate attention
210 }
211
212 if (time_to_next_ms < current_timeout_ms) {
213 return (uint32_t)time_to_next_ms;
214 }
215
216 return current_timeout_ms;
217}
asciichat_error_t session_consensus_create(const uint8_t my_id[16], bool is_leader, const uint8_t participant_ids[64][16], int num_participants, const session_consensus_callbacks_t *callbacks, session_consensus_t **out_consensus)
Definition consensus.c:108
uint64_t session_consensus_time_until_next_round(session_consensus_t *consensus)
Definition consensus.c:306
asciichat_error_t consensus_get_discovery_callbacks(void *context, session_consensus_callbacks_t *out_callbacks)
Get callbacks configured for discovery mode integration.
uint32_t consensus_suggest_timeout_ms(session_consensus_t *consensus, uint32_t current_timeout_ms)
Calculate how long to wait until next consensus processing.
asciichat_error_t consensus_create_for_discovery(const uint8_t session_id[16], const uint8_t my_id[16], const uint8_t participant_ids[64][16], int num_participants, void *discovery_context, session_consensus_t **out_consensus)
Example: Create session consensus for discovery mode.
uint8_t session_id[16]
Session consensus handle - wraps all consensus modules.
Definition consensus.c:21
uint64_t time_get_ns(void)
Definition util/time.c:48