15#if PC_ENABLE_UDP_TELEMETRY
27static void line_append(pc_line *l,
const char *s)
33 size_t n = strnlen(s, l->cap + 1);
34 if (l->pos + n >= l->cap)
39 memcpy(l->buf + l->pos, s, n);
41 l->buf[l->pos] =
'\0';
45static void line_sep(pc_line *l)
47 line_append(l, l->have_fields ?
"," :
" ");
48 l->have_fields =
true;
51void pc_line_init(pc_line *l,
char *buf,
size_t cap,
const char *measurement)
57 l->have_fields =
false;
62 line_append(l, measurement ? measurement :
"");
67static void line_append_escaped(pc_line *l,
const char *s)
73 for (
const char *p = s; *p; p++)
75 if (*p ==
',' || *p ==
'=' || *p ==
' ')
77 char esc[3] = {
'\\', *p,
'\0'};
82 char one[2] = {*p,
'\0'};
88void pc_line_add_tag(pc_line *l,
const char *key,
const char *val)
99 line_append_escaped(l, key);
101 line_append_escaped(l, val);
104void pc_line_set_timestamp(pc_line *l, int64_t timestamp)
112 pc_sb sb_num = {num,
sizeof(num), 0,
true};
114 pc_sb_i64(&sb_num, (int64_t)((
long long)timestamp));
122void pc_line_add_int(pc_line *l,
const char *field, int64_t v)
125 pc_sb sb_num2 = {num,
sizeof(num), 0,
true};
126 pc_sb_i64(&sb_num2, (int64_t)((
long long)v));
133 line_append(l, field);
138void pc_line_add_uint(pc_line *l,
const char *field, uint64_t v)
141 pc_sb sb_num3 = {num,
sizeof(num), 0,
true};
142 pc_sb_u64(&sb_num3, (uint64_t)((
unsigned long long)v));
149 line_append(l, field);
154void pc_line_add_float(pc_line *l,
const char *field,
float v, uint8_t decimals)
157 pc_sb sb_num4 = {num,
sizeof(num), 0,
true};
158 pc_sb_fixed(&sb_num4, (
double)((
double)v), (
unsigned)((
int)decimals));
164 line_append(l, field);
169size_t pc_line_len(
const pc_line *l)
174bool pc_line_ok(
const pc_line *l)
176 return !l->overflow && l->have_fields;
189struct UdpTelemetryCtx
198void pc_udp_telemetry_begin(
const char *collector_ip, uint16_t port)
200 strncpy(s_ut.ip, collector_ip ? collector_ip :
"", sizeof(s_ut.ip) - 1);
201 s_ut.ip[
sizeof(s_ut.ip) - 1] =
'\0';
206bool pc_udp_telemetry_send(
const char *data,
size_t len)
208 if (!s_ut.begun || !data)
212 return pc_udp_sendto(s_ut.ip, s_ut.port, (
const uint8_t *)data, len);
217void pc_udp_telemetry_begin(
const char *, uint16_t)
221bool pc_udp_telemetry_send(
const char *,
size_t)
228bool pc_udp_telemetry_cast(
const pc_line *l)
234 return pc_udp_telemetry_send(l->buf, l->pos);
Bounded no-heap string builder that fails closed on overflow (one shared copy).
void pc_sb_fixed(pc_sb *b, double v, unsigned decimals)
Append v with exactly decimals digits after the point (printf "%.<decimals>f").
size_t pc_sb_finish(pc_sb *b)
NUL-terminate and return the built length, or 0 if the build overflowed.
void pc_sb_u64(pc_sb *b, uint64_t v)
Append v as decimal (64-bit).
void pc_sb_i64(pc_sb *b, int64_t v)
Append v as signed decimal (64-bit), with a leading '-' when negative.
void pc_sb_put(pc_sb *b, const char *s)
Append NUL-terminated s; leaves the buffer untouched and clears ok if it would not fit.
Bump-append target; ok latches false once an append would overflow cap.
bool pc_udp_sendto(const char *dst_ip, uint16_t dst_port, const uint8_t *data, size_t len)
Send a UDP datagram to an arbitrary destination (outbound client).
Layer 4 (Transport) - connectionless UDP datagram service.
Fire-and-forget UDP telemetry cast (PC_ENABLE_UDP_TELEMETRY).