ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
metrics.h File Reference

Ring consensus metrics collection and wire protocol. More...

Go to the source code of this file.

Data Structures

struct  __attribute__
 Network quality metrics for a single participant. More...
 

Typedefs

typedef struct consensus_metrics_collection consensus_metrics_collection_t
 Opaque metrics collection handle.
 

Functions

asciichat_error_t consensus_metrics_measure (const uint8_t my_id[16], participant_metrics_t *out_metrics)
 Measure participant network quality metrics.
 
asciichat_error_t consensus_metrics_to_wire (const participant_metrics_t *metrics, participant_metrics_t *out_wire)
 Serialize metrics to wire format with network byte order.
 
asciichat_error_t consensus_metrics_from_wire (const participant_metrics_t *wire_metrics, participant_metrics_t *out_metrics)
 Deserialize metrics from wire format.
 
asciichat_error_t consensus_metrics_collection_create (consensus_metrics_collection_t **out_collection)
 Create empty metrics collection.
 
asciichat_error_t consensus_metrics_collection_add (consensus_metrics_collection_t *collection, const participant_metrics_t *metrics)
 Add metrics to collection.
 
asciichat_error_t consensus_metrics_collection_get (const consensus_metrics_collection_t *collection, const participant_metrics_t **out_metrics, int *out_count)
 Get all accumulated metrics.
 
void consensus_metrics_collection_destroy (consensus_metrics_collection_t *collection)
 Destroy metrics collection.
 

Detailed Description

Ring consensus metrics collection and wire protocol.

Handles measurement, serialization, and deserialization of network quality metrics for transmission around the consensus ring. Metrics include:

  • NAT tier classification (0=LAN, 1=Public, 2=UPnP, 3=STUN, 4=TURN)
  • Upload bandwidth (Kbps)
  • Round-trip time (milliseconds)
  • STUN probe success rate (0-100%)
  • Public address and port information

Wire format uses network byte order (big-endian) for all multi-byte values.

Definition in file metrics.h.

Typedef Documentation

◆ consensus_metrics_collection_t

Opaque metrics collection handle.

Definition at line 57 of file metrics.h.

Function Documentation

◆ consensus_metrics_collection_add()

asciichat_error_t consensus_metrics_collection_add ( consensus_metrics_collection_t *  collection,
const participant_metrics_t *  metrics 
)

Add metrics to collection.

Accumulates metrics from a participant into the collection. Metrics are stored in dynamically-allocated array.

Parameters
collectionCollection to add to
metricsMetrics to add
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 179 of file metrics.c.

180 {
181 if (!collection || !metrics) {
182 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters to collection_add");
183 }
184
185 // Resize if needed
186 if (collection->count >= collection->capacity) {
187 int new_capacity = collection->capacity * 2;
188 participant_metrics_t *new_metrics =
189 SAFE_MALLOC(new_capacity * sizeof(participant_metrics_t), participant_metrics_t *);
190
191 if (!new_metrics) {
192 return SET_ERRNO(ERROR_MEMORY, "Failed to allocate metrics array");
193 }
194
195 // Copy existing metrics
196 if (collection->count > 0 && collection->metrics) {
197 memcpy(new_metrics, collection->metrics, collection->count * sizeof(participant_metrics_t));
198 SAFE_FREE(collection->metrics);
199 }
200
201 collection->metrics = new_metrics;
202 collection->capacity = new_capacity;
203 }
204
205 // Add new metrics
206 if (!collection->metrics) {
207 return SET_ERRNO(ERROR_MEMORY, "Collection metrics array is NULL");
208 }
209
210 memcpy(&collection->metrics[collection->count], metrics, sizeof(*metrics));
211 collection->count++;
212
213 return ASCIICHAT_OK;
214}
#define SAFE_FREE(ptr)
Definition common.h:376
#define SAFE_MALLOC(size, cast)
Definition common.h:264
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
@ ERROR_MEMORY
Definition error_codes.h:56
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_INVALID_PARAM
participant_metrics_t * metrics
Array of participant metrics.
Definition metrics.c:21
int count
Number of participants.
Definition metrics.c:22
int capacity
Allocated capacity.
Definition metrics.c:23

References ASCIICHAT_OK, consensus_metrics_collection::capacity, consensus_metrics_collection::count, ERROR_INVALID_PARAM, ERROR_MEMORY, consensus_metrics_collection::metrics, SAFE_FREE, SAFE_MALLOC, and SET_ERRNO.

◆ consensus_metrics_collection_create()

asciichat_error_t consensus_metrics_collection_create ( consensus_metrics_collection_t **  out_collection)

Create empty metrics collection.

Allocates a collection structure for accumulating metrics from multiple participants during a collection round.

Parameters
out_collectionOutput collection handle
Returns
ASCIICHAT_OK on success, error code on failure
Note
Must be freed with consensus_metrics_destroy()

Definition at line 163 of file metrics.c.

163 {
164 if (!out_collection) {
165 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid output parameter");
166 }
167
169 memset(collection, 0, sizeof(*collection));
170
171 collection->capacity = 10; // Start with capacity for 10 participants
172 collection->metrics = SAFE_MALLOC(collection->capacity * sizeof(participant_metrics_t), participant_metrics_t *);
173 collection->count = 0;
174
175 *out_collection = collection;
176 return ASCIICHAT_OK;
177}
Metrics collection structure for participant quality measurements.
Definition metrics.c:20

References ASCIICHAT_OK, consensus_metrics_collection::capacity, consensus_metrics_collection::count, ERROR_INVALID_PARAM, consensus_metrics_collection::metrics, SAFE_MALLOC, and SET_ERRNO.

◆ consensus_metrics_collection_destroy()

void consensus_metrics_collection_destroy ( consensus_metrics_collection_t *  collection)

Destroy metrics collection.

Frees all allocated memory in the collection, including the metrics array.

Parameters
collectionCollection to destroy (can be NULL)

Definition at line 228 of file metrics.c.

228 {
229 if (!collection) {
230 return;
231 }
232
233 if (collection->metrics) {
234 SAFE_FREE(collection->metrics);
235 }
236
237 SAFE_FREE(collection);
238}

References consensus_metrics_collection::metrics, and SAFE_FREE.

◆ consensus_metrics_collection_get()

asciichat_error_t consensus_metrics_collection_get ( const consensus_metrics_collection_t *  collection,
const participant_metrics_t **  out_metrics,
int *  out_count 
)

Get all accumulated metrics.

Retrieves the accumulated metrics array from collection.

Parameters
collectionCollection to query
out_metricsPointer to receive metrics array (not copied, owned by collection)
out_countPointer to receive number of metrics
Returns
ASCIICHAT_OK on success, error code on failure
Note
out_metrics points to internal collection storage - do not modify or free
Valid only until collection is destroyed

Definition at line 216 of file metrics.c.

217 {
218 if (!collection || !out_metrics || !out_count) {
219 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters to collection_get");
220 }
221
222 *out_metrics = collection->metrics;
223 *out_count = collection->count;
224
225 return ASCIICHAT_OK;
226}

References ASCIICHAT_OK, consensus_metrics_collection::count, ERROR_INVALID_PARAM, consensus_metrics_collection::metrics, and SET_ERRNO.

◆ consensus_metrics_from_wire()

asciichat_error_t consensus_metrics_from_wire ( const participant_metrics_t *  wire_metrics,
participant_metrics_t *  out_metrics 
)

Deserialize metrics from wire format.

Converts network byte order values back to host byte order. Inverse operation of consensus_metrics_to_wire().

Parameters
wire_metricsInput metrics in network byte order
out_metricsOutput metrics in host byte order
Returns
ASCIICHAT_OK on success, error code on failure
Note
out_metrics must point to valid participant_metrics_t allocated by caller

Definition at line 144 of file metrics.c.

145 {
146 if (!wire_metrics || !out_metrics) {
147 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters to consensus_metrics_from_wire");
148 }
149
150 // Copy entire structure first
151 memcpy(out_metrics, wire_metrics, sizeof(*out_metrics));
152
153 // Convert multi-byte fields from network byte order
154 out_metrics->upload_kbps = endian_unpack_u32(wire_metrics->upload_kbps);
155 out_metrics->rtt_ns = endian_unpack_u32(wire_metrics->rtt_ns);
156 out_metrics->public_port = endian_unpack_u16(wire_metrics->public_port);
157 out_metrics->measurement_time_ns = endian_unpack_u64(wire_metrics->measurement_time_ns);
158 out_metrics->measurement_window_ns = endian_unpack_u64(wire_metrics->measurement_window_ns);
159
160 return ASCIICHAT_OK;
161}

References ASCIICHAT_OK, ERROR_INVALID_PARAM, and SET_ERRNO.

◆ consensus_metrics_measure()

asciichat_error_t consensus_metrics_measure ( const uint8_t  my_id[16],
participant_metrics_t *  out_metrics 
)

Measure participant network quality metrics.

Collects all metrics needed for host selection:

  • NAT tier from detected NAT type (0-4)
  • Bandwidth estimate (default 50 Mbps if not available)
  • RTT from keepalive pings (default 25ms if not available)
  • STUN probe success rate by sending 10 probes

The measurement includes the participant's UUID and timestamps.

Parameters
my_idParticipant UUID (16 bytes)
out_metricsOutput metrics structure (caller-allocated)
Returns
ASCIICHAT_OK on success, error code on failure
Note
out_metrics must point to valid participant_metrics_t allocated by caller
Measurement window and timestamp are set automatically

Definition at line 86 of file metrics.c.

86 {
87 if (!my_id || !out_metrics) {
88 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters to consensus_metrics_measure");
89 }
90
91 // Initialize metrics structure
92 memset(out_metrics, 0, sizeof(*out_metrics));
93
94 // Copy participant ID
95 memcpy(out_metrics->participant_id, my_id, 16);
96
97 // NAT tier: Default to 1 (Public IP, no NAT needed)
98 // TODO: In production, query NAT detection module
99 out_metrics->nat_tier = 1;
100
101 // Upload bandwidth: Default 50 Mbps
102 out_metrics->upload_kbps = DEFAULT_BANDWIDTH_KBPS;
103
104 // RTT: Default 25ms (25,000,000 nanoseconds)
105 out_metrics->rtt_ns = DEFAULT_RTT_MS * NS_PER_MS;
106
107 // STUN probe success rate: Measure by sending probes
108 out_metrics->stun_probe_success_pct = measure_stun_probe_success();
109
110 // Public address and port: Placeholder values
111 snprintf(out_metrics->public_address, sizeof(out_metrics->public_address), "127.0.0.1");
112 out_metrics->public_port = 27224;
113
114 // Connection type: Default to direct
115 out_metrics->connection_type = 0; // Direct connection
116
117 // Measurement time: Current time in nanoseconds
118 out_metrics->measurement_time_ns = time_get_realtime_ns();
119
120 // Measurement window: 1 second in nanoseconds
121 out_metrics->measurement_window_ns = 1 * NS_PER_SEC;
122
123 return ASCIICHAT_OK;
124}
uint64_t time_get_realtime_ns(void)
Get current wall-clock (real) time in nanoseconds.
Definition util/time.c:119
#define NS_PER_MS
Definition time.h:147
#define NS_PER_SEC
Definition time.h:148
#define DEFAULT_RTT_MS
Definition metrics.c:34
#define DEFAULT_BANDWIDTH_KBPS
Definition metrics.c:29

References ASCIICHAT_OK, DEFAULT_BANDWIDTH_KBPS, DEFAULT_RTT_MS, ERROR_INVALID_PARAM, NS_PER_MS, NS_PER_SEC, SET_ERRNO, and time_get_realtime_ns().

◆ consensus_metrics_to_wire()

asciichat_error_t consensus_metrics_to_wire ( const participant_metrics_t *  metrics,
participant_metrics_t *  out_wire 
)

Serialize metrics to wire format with network byte order.

Converts host-order values to network byte order (big-endian) for transmission over the network. Multi-byte fields are converted:

  • upload_kbps (uint32_t)
  • rtt_ms (uint16_t)
  • public_port (uint16_t)
  • measurement_time_ms (uint64_t)
  • measurement_window_ms (uint32_t)
Parameters
metricsInput metrics in host byte order
out_wireOutput metrics in network byte order
Returns
ASCIICHAT_OK on success, error code on failure
Note
out_wire must point to valid participant_metrics_t allocated by caller

Definition at line 126 of file metrics.c.

126 {
127 if (!metrics || !out_wire) {
128 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters to consensus_metrics_to_wire");
129 }
130
131 // Copy entire structure first
132 memcpy(out_wire, metrics, sizeof(*out_wire));
133
134 // Convert multi-byte fields to network byte order
135 out_wire->upload_kbps = endian_pack_u32(metrics->upload_kbps);
136 out_wire->rtt_ns = endian_pack_u32(metrics->rtt_ns);
137 out_wire->public_port = endian_pack_u16(metrics->public_port);
138 out_wire->measurement_time_ns = endian_pack_u64(metrics->measurement_time_ns);
139 out_wire->measurement_window_ns = endian_pack_u64(metrics->measurement_window_ns);
140
141 return ASCIICHAT_OK;
142}

References ASCIICHAT_OK, ERROR_INVALID_PARAM, and SET_ERRNO.