|
OpenPgm5CReferencePgmRecv
OpenPGM 5 : C Reference : Socket : pgm_recv()
Phase-Implementation Function Declaration#include <pgm/pgm.h> PurposeReceive an Application Protocol Domain Unit (APDU) from the transport and drive the PGM receive and send state machines. RemarksThe PGM protocol is bi-directional, even send-only applications need to process incoming requests for retransmission (NAKs) and other packet types. The synchronous API suite provides low level access to the raw events driving the protocol in order to accelerate performance in high message rate environments. pgm_recv() and pgm_recvfrom() fill the provided buffer location with up to len contiguous APDU bytes therefore the buffer should be large enough to store the largest APDU expected. If from is not NULL, the source TSI is filled in. The pgm_recv() is identical to pgm_recvfrom() with a NULL from parameter. pgm_recvmsg() fills a pgm_msgv_t structure with a scatter/gather vector of buffers directly from the receive window. The vector size is governed by IOV_MAX, on Linux is 1024. Using the maximum size is not always recommended as time processing the received messages might cause an incoming buffer overrun. Memory is returned to the receive window on the next call or transport destruction. If you want buffers that remain the property of the application consider the zero-copy API pgm_recvmsgv() instead. Unrecoverable data loss will cause the function to immediately return with PGM_IO_STATUS_RESET, setting flags to MSG_ERR_QUEUE will return a populated msgv with an error skbuff detailing the error. If PGM_ABORT_ON_RESET is set with false (the default mode) processing can continue with subsequent calls to pgm_recv(), if true then the transport will continue to return PGM_IO_STATUS_RESET until destroyed. It is valid to send and receive zero length PGM packets. The pgm_recv() API and other versions are the entry into the core PGM state machine. Frequent calls must be made for send-only sockets in order to process incoming NAKs, send NCFs, send repair data (RDATA), in addition to sending broadcast SPMs to define the PGM tree. Frequent calls must be made to pgm_recv() for receive-only sockets to generate and re-generate NAKs for missing data, and to send SPM-Request messages to new senders to expedite learning of their NLAs. Parameters
Return ValueOn success, returns PGM_IO_STATUS_NORMAL, on error returns PGM_IO_STATUS_ERROR, on reset due to unrecoverable data loss, returns PGM_IO_STATUS_RESET. If the transport is marked non-blocking and no senders have been discovered then PGM_IO_STATUS_WOULD_BLOCK is returned if the operation would block. If no data is available but a pending state timer is running PGM_IO_STATUS_TIMER_PENDING is returned. If the state engine is trying to transmit repair data but is subject to the rate limiting engine then PGM_IO_STATUS_RATE_LIMITED is returned instead. ExampleReceive an APDU up to 4096 bytes in length. char buf[4096]; size_t bytes_read; pgm_recv (transport, buf, sizeof(buf), 0, &bytes_read, NULL); Receive an APDU with source TSI. char buf[4096];
struct pgm_sockaddr_t from;
size_t bytes_read;
pgm_recvfrom (transport, buf, sizeof(buf), 0, &from, &bytes_read, NULL);
printf ("%zu bytes received from %s\n", pgm_tsi_print (&from.sa_addr));Receive a scatter/gather vector APDU message. pgm_msgv_t msgv;
size_t bytes_read;
pgm_recvmsg (transport, &msgv, 0, &bytes_read, NULL);
printf ("received %zu bytes: ", bytes_read);
struct iovec* msgv_iov = msgv.msgv_iov;
while (bytes_read > 0) {
printf ((char*)msgv_iov->iov_base);
bytes_read -= msgv_iov->iov_len;
msgv_iov++;
}
putchar('\n');Display error details on unrecoverable error. char buf[4096];
size_t bytes_read;
pgm_error_t *err = NULL;
if (PGM_IO_STATUS_RESET == pgm_recv (transport, buf, sizeof(buf), &bytes_read, &err)) {
fprintf (stderr, "pgm_recv() error %s\n", (err && err->message) ? err->message : "(null)");
pgm_error_free (err);
return EXIT_FAILURE;
}Display details from error skbuff. pgm_msgv_t msgv;
size_t bytes_read;
if (PGM_IO_STATUS_RESET == pgm_recvmsg (transport, &msgv, MSG_ERR_QUEUE, &bytes_read, NULL)) {
fprintf (stderr, "pgm socket lost %" PRIu32 " packets detected from %s\n",
msgv.msgv_skb[0]->seq,
pgm_print_tsi(&msgv.msgv_skb[0]->tsi));
return EXIT_FAILURE;
}See Also
| |||||||||||||||||