summaryrefslogtreecommitdiff
path: root/test/mock/sipsrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/mock/sipsrv.c')
-rw-r--r--test/mock/sipsrv.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/test/mock/sipsrv.c b/test/mock/sipsrv.c
new file mode 100644
index 0000000..0707962
--- /dev/null
+++ b/test/mock/sipsrv.c
@@ -0,0 +1,145 @@
+/**
+ * @file mock/sipsrv.c Mock SIP server
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+#include <string.h>
+#include <re.h>
+#include "../test.h"
+
+
+#define DEBUG_MODULE "mock/sipsrv"
+#define DEBUG_LEVEL 5
+#include <re_dbg.h>
+
+
+#define LOCAL_PORT 0
+#define LOCAL_SECURE_PORT 0
+
+
+static bool sip_msg_handler(const struct sip_msg *msg, void *arg)
+{
+ struct sip_server *srv = arg;
+ int err;
+
+#if 0
+ DEBUG_NOTICE("recv %r via %s\n", &msg->met, sip_transp_name(msg->tp));
+#endif
+
+ if (0 == pl_strcmp(&msg->met, "REGISTER")) {
+ ++srv->n_register_req;
+ }
+ else {
+ DEBUG_NOTICE("method not handled (%r)\n", &msg->met);
+ return false;
+ }
+
+ srv->tp_last = msg->tp;
+
+ if (srv->terminate)
+ err = sip_reply(srv->sip, msg, 503, "Server Error");
+ else
+ err = sip_reply(srv->sip, msg, 200, "OK");
+
+ if (err) {
+ DEBUG_WARNING("could not reply: %m\n", err);
+ }
+
+#if 1
+ if (srv->terminate)
+ re_cancel();
+#endif
+
+ return true;
+}
+
+
+static void destructor(void *arg)
+{
+ struct sip_server *srv = arg;
+
+ srv->terminate = true;
+
+ sip_close(srv->sip, false);
+ mem_deref(srv->sip);
+}
+
+
+int sip_server_alloc(struct sip_server **srvp)
+{
+ struct sip_server *srv;
+ struct sa laddr, laddrs;
+ struct tls *tls = NULL;
+ int err;
+
+ if (!srvp)
+ return EINVAL;
+
+ srv = mem_zalloc(sizeof *srv, destructor);
+ if (!srv)
+ return ENOMEM;
+
+ err = sa_set_str(&laddr, "127.0.0.1", LOCAL_PORT);
+ err |= sa_set_str(&laddrs, "127.0.0.1", LOCAL_SECURE_PORT);
+ if (err)
+ goto out;
+
+ err = sip_alloc(&srv->sip, NULL, 16, 16, 16,
+ "mock SIP server", NULL, NULL);
+ if (err)
+ goto out;
+
+ err |= sip_transp_add(srv->sip, SIP_TRANSP_UDP, &laddr);
+ err |= sip_transp_add(srv->sip, SIP_TRANSP_TCP, &laddr);
+ if (err)
+ goto out;
+
+#ifdef USE_TLS
+ err = tls_alloc(&tls, TLS_METHOD_SSLV23, NULL, NULL);
+ if (err)
+ goto out;
+
+ err = tls_set_certificate(tls, test_certificate,
+ strlen(test_certificate));
+ if (err)
+ goto out;
+
+ err |= sip_transp_add(srv->sip, SIP_TRANSP_TLS, &laddrs, tls);
+#endif
+ if (err)
+ goto out;
+
+ err = sip_listen(&srv->lsnr, srv->sip, true, sip_msg_handler, srv);
+ if (err)
+ goto out;
+
+ out:
+ mem_deref(tls);
+ if (err)
+ mem_deref(srv);
+ else
+ *srvp = srv;
+
+ return err;
+}
+
+
+int sip_server_uri(struct sip_server *srv, char *uri, size_t sz,
+ enum sip_transp tp)
+{
+ struct sa laddr;
+ int err;
+
+ if (!srv || !uri || !sz)
+ return EINVAL;
+
+ err = sip_transp_laddr(srv->sip, &laddr, tp, NULL);
+ if (err)
+ return err;
+
+ if (re_snprintf(uri, sz, "sip:x:x@%J%s",
+ &laddr, sip_transp_param(tp)) < 0)
+ return ENOMEM;
+
+ return 0;
+}