.TH LC_CHANNEL_NACK_HANDLER 3 2022-10-29 "LIBRECAST" "Librecast Programmer's Manual" .SH NAME lc_channel_nack_handler, lc_channel_nack_handler_thr, lc_channel_nack_add_log \- outgoing message logging to handle NACK and replay requests .SH LIBRARY Librecast library .RI ( liblibrecast ", " \-llibrecast ) .SH SYNOPSIS .nf .B #include .PP .BI "int lc_channel_nack_handler(lc_channel_t *chan, int n_seconds);" .BI "int lc_channel_nack_handler_thr(lc_channel_t *chan, int n_seconds, void *(*nack_thread)(void *));" .BI "int lc_channel_nack_add_log(lc_channel_t *chan, const void *buf, size_t len, lc_seq_t seq);" .fi .PP Compile and link with \fI\-llibrecast\fP. .SH DESCRIPTION .BR lc_channel_nack_handler () sets up a per-channel buffer to keep a copy of outgoing messages sent via .BR lc_msg_send () and also starts a new thread (called "nack thread") to handle any retransmission requests; the outgoing messages are kept for at least .I n_seconds seconds if there is sufficient free memory to do so. The nack thread listens for messages on a related channel, interprets them as NACK messages, and arranges for retransmission of the corresponding messages. The normal case is that these NACK messages are generated as a result of calling .BR lc_channel_detect_gaps () on the receiver side. A call to .BR lc_channel_free (3) will stop the nack thread if it's running. .PP .BR lc_channel_nack_handler_thr () is similar to .BR lc_channel_nack_handler () except that it specifies a different function to use for the nack thread; it will be called in a new thread with an opened channel and socket where it can receive NACK messages, and another channel it can use to resend packets; currently, there is no alternative thread to use, and this function is only used by the library's tests; however a different nack thread could be provided in future for example to deal with the special case of messages sent from static data, which can be resent without storing recent messages in a memory buffer. .PP .BR lc_channel_nack_add_log () adds a message to the internal memory buffer, making it available for retransmission as a result of a NACK; it is not normally necessary to call this function if all messages are sent using .BR lc_msg_send () however an application which defines its own message format will need to call .BR lc_channel_nack_add_log () with a copy of each message as it goes on the wire, as well as the sequence number it contains, as the library will have no way to find this information in the applicatin's own message format. The application needs to call .BR lc_channel_nack_handler () before using .BR lc_channel_nack_add_log () otherwise the call will not log anything: this could be useful if message logging and NACK request handling is optional, so the application can conditionally call .BR lc_channel_nack_handler () during initialisation, but then unconditionally call .BR lc_channel_nack_add_log () for each message it sends. .SH RETURN VALUE .BR lc_channel_nack_handler () and .BR lc_channel_nack_handler_thr () return 0 on success, and -1 to indicate an error, setting the global variable .I errno to an appropriate code, most likely .BR ENOMEM to indicate that there was insufficient memory to set up the required data structures. .PP The .BR lc_channel_nack_add_log () function returns 0 on success and -1 to indicate that there was no memory to store the message in its internal buffers, setting .I errno to the value .BR ENOMEM .SH ERRORS .BR lc_channel_nack_handler () and .BR lc_channel_nack_handler_thr () can fail with any of the errors the .BR malloc () library function can produce, as well as any errors produces by the .BR lc_channel_sidehash () or .BR lc_socket_new () functions. .PP .BR lc_channel_nack_add_log () can fail with any of the errors the .BR malloc () library function can produce. .SH EXAMPLE .SS Program source \& .EX lc_ctx_t *lctx; lc_channel_t *chan; lctx = lc_ctx_new(); chan = lc_channel_new(lctx, "channel name"); if (lc_channel_nack_handler(chan, 10) == -1) { /* handle this error */ } /* your program goes here, likely calling lc_msg_send(chan, ...) */ lc_channel_free(chan); lc_ctx_free(lctx); .EE .SH SEE ALSO .BR lc_channel_detect_gaps (3), .BR lc_channel_free (3), .BR lc_msg_send (3)