Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b
Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/bfcp/conn.c b/src/bfcp/conn.c
new file mode 100644
index 0000000..6e4051d
--- /dev/null
+++ b/src/bfcp/conn.c
@@ -0,0 +1,156 @@
+/**
+ * @file bfcp/conn.c BFCP Connection
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <string.h>
+#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_tmr.h>
+#include <re_bfcp.h>
+#include "bfcp.h"
+
+
+static void destructor(void *arg)
+{
+ struct bfcp_conn *bc = arg;
+
+ list_flush(&bc->ctransl);
+ tmr_cancel(&bc->tmr1);
+ tmr_cancel(&bc->tmr2);
+ mem_deref(bc->us);
+ mem_deref(bc->mb);
+}
+
+
+static bool strans_cmp(const struct bfcp_strans *st,
+ const struct bfcp_msg *msg)
+{
+ if (st->tid != msg->tid)
+ return false;
+
+ if (st->prim != msg->prim)
+ return false;
+
+ if (st->confid != msg->confid)
+ return false;
+
+ if (st->userid != msg->userid)
+ return false;
+
+ return true;
+}
+
+
+static void udp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg)
+{
+ struct bfcp_conn *bc = arg;
+ struct bfcp_msg *msg;
+ int err;
+
+ err = bfcp_msg_decode(&msg, mb);
+ if (err)
+ return;
+
+ msg->src = *src;
+
+ if (bfcp_handle_response(bc, msg))
+ goto out;
+
+ if (bc->mb && strans_cmp(&bc->st, msg)) {
+ (void)bfcp_send(bc, &msg->src, bc->mb);
+ goto out;
+ }
+
+ if (bc->recvh)
+ bc->recvh(msg, bc->arg);
+
+out:
+ mem_deref(msg);
+}
+
+
+/**
+ * Create BFCP connection
+ *
+ * @param bcp Pointer to BFCP connection
+ * @param tp BFCP Transport type
+ * @param laddr Optional listening address/port
+ * @param tls TLS Context (optional)
+ * @param recvh Receive handler
+ * @param arg Receive handler argument
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int bfcp_listen(struct bfcp_conn **bcp, enum bfcp_transp tp, struct sa *laddr,
+ struct tls *tls, bfcp_recv_h *recvh, void *arg)
+{
+ struct bfcp_conn *bc;
+ int err;
+ (void)tls;
+
+ if (!bcp)
+ return EINVAL;
+
+ bc = mem_zalloc(sizeof(*bc), destructor);
+ if (!bc)
+ return ENOMEM;
+
+ bc->tp = tp;
+ bc->recvh = recvh;
+ bc->arg = arg;
+
+ switch (bc->tp) {
+
+ case BFCP_UDP:
+ err = udp_listen(&bc->us, laddr, udp_recv_handler, bc);
+ if (err)
+ goto out;
+
+ if (laddr) {
+ err = udp_local_get(bc->us, laddr);
+ if (err)
+ goto out;
+ }
+ break;
+
+ default:
+ err = ENOSYS;
+ goto out;
+ }
+
+ out:
+ if (err)
+ mem_deref(bc);
+ else
+ *bcp = bc;
+
+ return err;
+}
+
+
+int bfcp_send(struct bfcp_conn *bc, const struct sa *dst, struct mbuf *mb)
+{
+ if (!bc || !dst || !mb)
+ return EINVAL;
+
+ switch (bc->tp) {
+
+ case BFCP_UDP:
+ return udp_send(bc->us, dst, mb);
+
+ default:
+ return ENOSYS;
+ }
+}
+
+
+void *bfcp_sock(const struct bfcp_conn *bc)
+{
+ return bc ? bc->us : NULL;
+}