static void send_kmsg()

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;
	}
}