6#include <ascii-chat/network/consensus/metrics.h>
7#include <ascii-chat/common.h>
8#include <ascii-chat/util/endian.h>
9#include <ascii-chat/util/time.h>
10#include <ascii-chat/asciichat_errno.h>
29#define DEFAULT_BANDWIDTH_KBPS 50000
34#define DEFAULT_RTT_MS 25
39#define NUM_STUN_PROBES 10
49static uint8_t measure_stun_probe_success(
void) {
80 if (nat_type < 0 || nat_type > 4) {
83 return (uint8_t)nat_type;
87 if (!my_id || !out_metrics) {
88 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters to consensus_metrics_measure");
92 memset(out_metrics, 0,
sizeof(*out_metrics));
95 memcpy(out_metrics->participant_id, my_id, 16);
99 out_metrics->nat_tier = 1;
108 out_metrics->stun_probe_success_pct = measure_stun_probe_success();
111 snprintf(out_metrics->public_address,
sizeof(out_metrics->public_address),
"127.0.0.1");
112 out_metrics->public_port = 27224;
115 out_metrics->connection_type = 0;
121 out_metrics->measurement_window_ns = 1 * NS_PER_SEC;
127 if (!metrics || !out_wire) {
128 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters to consensus_metrics_to_wire");
132 memcpy(out_wire, metrics,
sizeof(*out_wire));
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);
145 participant_metrics_t *out_metrics) {
146 if (!wire_metrics || !out_metrics) {
147 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters to consensus_metrics_from_wire");
151 memcpy(out_metrics, wire_metrics,
sizeof(*out_metrics));
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);
164 if (!out_collection) {
165 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid output parameter");
169 memset(collection, 0,
sizeof(*collection));
172 collection->
metrics = SAFE_MALLOC(collection->
capacity *
sizeof(participant_metrics_t), participant_metrics_t *);
173 collection->
count = 0;
175 *out_collection = collection;
180 const participant_metrics_t *metrics) {
181 if (!collection || !metrics) {
182 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters to collection_add");
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 *);
192 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate metrics array");
197 memcpy(new_metrics, collection->
metrics, collection->
count *
sizeof(participant_metrics_t));
198 SAFE_FREE(collection->
metrics);
201 collection->
metrics = new_metrics;
202 collection->
capacity = new_capacity;
207 return SET_ERRNO(ERROR_MEMORY,
"Collection metrics array is NULL");
210 memcpy(&collection->
metrics[collection->
count], metrics,
sizeof(*metrics));
217 const participant_metrics_t **out_metrics,
int *out_count) {
218 if (!collection || !out_metrics || !out_count) {
219 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters to collection_get");
222 *out_metrics = collection->
metrics;
223 *out_count = collection->
count;
234 SAFE_FREE(collection->
metrics);
237 SAFE_FREE(collection);
asciichat_error_t consensus_metrics_from_wire(const participant_metrics_t *wire_metrics, participant_metrics_t *out_metrics)
asciichat_error_t consensus_metrics_to_wire(const participant_metrics_t *metrics, participant_metrics_t *out_wire)
asciichat_error_t consensus_metrics_measure(const uint8_t my_id[16], participant_metrics_t *out_metrics)
void consensus_metrics_collection_destroy(consensus_metrics_collection_t *collection)
asciichat_error_t consensus_metrics_collection_add(consensus_metrics_collection_t *collection, const participant_metrics_t *metrics)
struct consensus_metrics_collection consensus_metrics_collection_t
Metrics collection structure for participant quality measurements.
#define DEFAULT_BANDWIDTH_KBPS
asciichat_error_t consensus_metrics_collection_get(const consensus_metrics_collection_t *collection, const participant_metrics_t **out_metrics, int *out_count)
asciichat_error_t consensus_metrics_collection_create(consensus_metrics_collection_t **out_collection)
Metrics collection structure for participant quality measurements.
participant_metrics_t * metrics
Array of participant metrics.
int count
Number of participants.
int capacity
Allocated capacity.
uint64_t time_get_realtime_ns(void)