in ncrx/nctx.c [203:279]
static void send_kmsg(int sock, char *msg, int is_emg_tx,
struct sockaddr *addr, int addr_len)
{
char buf[NCRX_PKT_MAX + 1];
const int max_extra_len = sizeof(",ncemg=1,ncfrag=0000/0000");
const char *header, *body;
int msg_len = strlen(msg);
int header_len = msg_len, body_len = 0;
int chunk_len, nr_chunks, i;
if (!is_emg_tx && msg_len <= NCRX_PKT_MAX) {
sendto(sock, msg, msg_len, 0, addr, addr_len);
return;
}
/* need to insert extra header fields, detect header and body */
header = msg;
body = memchr(msg, ';', msg_len);
if (body) {
header_len = body - header;
body_len = msg_len - header_len - 1;
body++;
}
chunk_len = NCRX_PKT_MAX - header_len - max_extra_len;
if (chunk_len <= 0) {
fprintf(stderr, "Error: invalid chunk_len %d in send_kmsg()\n",
chunk_len);
return;
}
/*
* Transfer possibly multiple chunks with extra header fields.
*
* For emergency transfers due to missing acks, add "emg=1".
*
* If @msg needs to be split to fit NCRX_PKT_MAX, add
* "ncfrag=<byte-offset>/<total-bytes>" to identify each chunk.
*/
memcpy(buf, header, header_len);
nr_chunks = (body_len + chunk_len - 1) / chunk_len;
for (i = 0; i < nr_chunks; i++) {
int offset = i * chunk_len;
int this_header = header_len;
int this_chunk;
this_chunk = body_len - offset;
if (this_chunk > chunk_len)
this_chunk = chunk_len;
if (is_emg_tx && this_header < sizeof(buf))
this_header += snprintf(buf + this_header,
sizeof(buf) - this_header,
",ncemg=1");
if (nr_chunks > 1 && this_header < sizeof(buf))
this_header += snprintf(buf + this_header,
sizeof(buf) - this_header,
",ncfrag=%d/%d",
offset, body_len);
if (this_header < sizeof(buf))
this_header += snprintf(buf + this_header,
sizeof(buf) - this_header, ";");
if (this_header + chunk_len > NCRX_PKT_MAX) {
fprintf(stderr, "Error: this_header %d is too large for chunk_len %d in send_kmsg()\n",
this_header, chunk_len);
return;
}
memcpy(buf + this_header, body, this_chunk);
sendto(sock, buf, this_header + this_chunk, 0, addr, addr_len);
body += this_chunk;
}
}