Squashed 'third_party/rawrtc/rew/' content from commit 24c91fd83
Change-Id: Ica2fcc790472ecd5b195d20da982c4e84139cbdd
git-subtree-dir: third_party/rawrtc/rew
git-subtree-split: 24c91fd839b40b11f727c902fa46d20874da33fb
diff --git a/src/pcp/reply.c b/src/pcp/reply.c
new file mode 100644
index 0000000..264dcbb
--- /dev/null
+++ b/src/pcp/reply.c
@@ -0,0 +1,93 @@
+/**
+ * @file pcp/reply.c PCP reply
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_mem.h>
+#include <re_mbuf.h>
+#include <re_list.h>
+#include <re_sa.h>
+#include <re_udp.h>
+#include <re_pcp.h>
+#include "pcp.h"
+
+
+static int pcp_header_encode_response(struct mbuf *mb, enum pcp_opcode opcode,
+ enum pcp_result result,
+ uint32_t lifetime, uint32_t epoch_time)
+{
+ int err = 0;
+
+ if (!mb)
+ return EINVAL;
+
+ err |= mbuf_write_u8(mb, PCP_VERSION);
+ err |= mbuf_write_u8(mb, 1<<7 | opcode);
+ err |= mbuf_write_u8(mb, 0x00);
+ err |= mbuf_write_u8(mb, result);
+ err |= mbuf_write_u32(mb, htonl(lifetime));
+ err |= mbuf_write_u32(mb, htonl(epoch_time));
+ err |= mbuf_fill(mb, 0x00, 12);
+
+ return err;
+}
+
+
+/**
+ * Send a PCP response message
+ *
+ * @param us UDP Socket
+ * @param dst Destination network address
+ * @param req Buffer containing original PCP request (optional)
+ * @param opcode PCP opcode
+ * @param result PCP result for the response
+ * @param lifetime Lifetime in [seconds]
+ * @param epoch_time Server Epoch-time
+ * @param payload PCP payload, e.g. struct pcp_map (optional)
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int pcp_reply(struct udp_sock *us, const struct sa *dst, struct mbuf *req,
+ enum pcp_opcode opcode, enum pcp_result result,
+ uint32_t lifetime, uint32_t epoch_time, const void *payload)
+{
+ struct mbuf *mb;
+ size_t start;
+ int err;
+
+ if (!us || !dst)
+ return EINVAL;
+
+ if (req) {
+ /* the complete Request must be included in the Response */
+ mb = mem_ref(req);
+ }
+ else {
+ mb = mbuf_alloc(128);
+ if (!mb)
+ return ENOMEM;
+ }
+
+ start = mb->pos;
+
+ /* encode the response packet */
+ err = pcp_header_encode_response(mb, opcode, result,
+ lifetime, epoch_time);
+ if (err)
+ goto out;
+
+ if (payload) {
+ err = pcp_payload_encode(mb, opcode, payload);
+ if (err)
+ goto out;
+ }
+
+ mb->pos = start;
+ err = udp_send(us, dst, mb);
+
+ out:
+ mem_deref(mb);
+ return err;
+}