+/*
+ * Perform some sanity checks on an udp audio file header.
+ *
+ * return: negative on error, 0: discard data, 1: use data
+ */
+static int examine_audio_header(struct private_udp_recv_data *purd,
+ struct udp_audio_header *uah, size_t packet_size)
+{
+ /* payload_len includes header */
+ if (uah->payload_len < uah->header_len)
+ return -E_UDP_BAD_HEADER;
+ switch (uah->packet_type) {
+ case UDP_EOF_PACKET:
+ return -E_RECV_EOF;
+ case UDP_BOF_PACKET:
+ purd->have_header = 1;
+ /* fall through */
+ case UDP_DATA_PACKET:
+ if (uah->header_len) /* header in no-header packet */
+ return -E_UDP_BAD_HEADER;
+ break;
+ case UDP_HEADER_PACKET:
+ if (!uah->header_len) /** no header in header packet */
+ return -E_UDP_BAD_HEADER;
+ break;
+ default: /* bad packet type */
+ return -E_UDP_BAD_HEADER;
+ }
+ /* check stream type */
+ if (uah->stream_type != UDP_PLAIN_STREAM &&
+ uah->stream_type != UDP_HEADER_STREAM)
+ return -E_UDP_BAD_STREAM_TYPE;
+ if (purd->stream_type == UDP_UNKNOWN_STREAM)
+ purd->stream_type = uah->stream_type;
+ /* stream type must not change */
+ if (uah->stream_type != purd->stream_type)
+ return -E_UDP_BAD_STREAM_TYPE;
+ if (!purd->have_header && uah->stream_type == UDP_HEADER_STREAM)
+ /* can't use the data, wait for header packet */
+ return 0;
+ if (packet_size < uah->payload_len + UDP_AUDIO_HEADER_LEN)
+ /* we read only a part of the package */
+ purd->need_more = uah->payload_len
+ + UDP_AUDIO_HEADER_LEN - packet_size;
+ return 1;
+}
+
+static int add_rn_output(struct receiver_node *rn, char *buf, size_t len)
+{
+ if (!len)
+ return 1;
+ if (!enough_space(len, rn->loaded))
+ return -E_UDP_OVERRUN;
+ memcpy(rn->buf + rn->loaded, buf, len);
+ rn->loaded += len;
+ return 1;
+}
+