summaryrefslogtreecommitdiff
path: root/modules/mwi
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mwi')
-rw-r--r--modules/mwi/module.mk10
-rw-r--r--modules/mwi/mwi.c141
2 files changed, 151 insertions, 0 deletions
diff --git a/modules/mwi/module.mk b/modules/mwi/module.mk
new file mode 100644
index 0000000..f6d1bde
--- /dev/null
+++ b/modules/mwi/module.mk
@@ -0,0 +1,10 @@
+#
+# module.mk
+#
+# Copyright (C) 2010 Creytiv.com
+#
+
+MOD := mwi
+$(MOD)_SRCS += mwi.c
+
+include mk/mod.mk
diff --git a/modules/mwi/mwi.c b/modules/mwi/mwi.c
new file mode 100644
index 0000000..21aca08
--- /dev/null
+++ b/modules/mwi/mwi.c
@@ -0,0 +1,141 @@
+/**
+ * @file mwi.c Message Waiting Indication (RFC 3842)
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <string.h>
+#include <re.h>
+#include <baresip.h>
+
+
+struct mwi {
+ struct le le;
+ struct sipsub *sub;
+ struct ua *ua;
+};
+
+static struct tmr tmr;
+static struct list mwil;
+
+
+static void destructor(void *arg)
+{
+ struct mwi *mwi = arg;
+
+ list_unlink(&mwi->le);
+ mem_deref(mwi->sub);
+}
+
+
+static int auth_handler(char **username, char **password,
+ const char *realm, void *arg)
+{
+ struct account *acc = arg;
+ return account_auth(acc, username, password, realm);
+}
+
+
+static void notify_handler(struct sip *sip, const struct sip_msg *msg,
+ void *arg)
+{
+ struct mwi *mwi = arg;
+
+ if (mbuf_get_left(msg->mb)) {
+ re_printf("----- MWI for %s -----\n", ua_aor(mwi->ua));
+ re_printf("%b\n", mbuf_buf(msg->mb), mbuf_get_left(msg->mb));
+ }
+
+ (void)sip_treply(NULL, sip, msg, 200, "OK");
+}
+
+
+static void close_handler(int err, const struct sip_msg *msg,
+ const struct sipevent_substate *substate,
+ void *arg)
+{
+ struct mwi *mwi = arg;
+ (void)substate;
+
+ info("mwi: subscription for %s closed: %s (%u %r)\n",
+ ua_aor(mwi->ua),
+ err ? strerror(err) : "",
+ err ? 0 : msg->scode,
+ err ? 0 : &msg->reason);
+
+ mem_deref(mwi);
+}
+
+
+static int mwi_subscribe(struct ua *ua)
+{
+ const char *routev[1];
+ struct mwi *mwi;
+ int err;
+
+ mwi = mem_zalloc(sizeof(*mwi), destructor);
+ if (!mwi)
+ return ENOMEM;
+
+ list_append(&mwil, &mwi->le, mwi);
+ mwi->ua = ua;
+
+ routev[0] = ua_outbound(ua);
+
+ info("mwi: subscribing to messages for %s\n", ua_aor(ua));
+
+ err = sipevent_subscribe(&mwi->sub, uag_sipevent_sock(), ua_aor(ua),
+ NULL, ua_aor(ua), "message-summary", NULL,
+ 600, ua_cuser(ua),
+ routev, routev[0] ? 1 : 0,
+ auth_handler, ua_prm(ua), true, NULL,
+ notify_handler, close_handler, mwi,
+ "Accept:"
+ " application/simple-message-summary\r\n");
+ if (err) {
+ warning("mwi: subscribe ERROR: %m\n", err);
+ }
+
+ if (err)
+ mem_deref(mwi);
+
+ return err;
+}
+
+
+static void tmr_handler(void *arg)
+{
+ struct le *le;
+
+ (void)arg;
+
+ for (le = list_head(uag_list()); le; le = le->next) {
+ struct ua *ua = le->data;
+ mwi_subscribe(ua);
+ }
+}
+
+
+static int module_init(void)
+{
+ list_init(&mwil);
+ tmr_start(&tmr, 10, tmr_handler, 0);
+
+ return 0;
+}
+
+
+static int module_close(void)
+{
+ tmr_cancel(&tmr);
+ list_flush(&mwil);
+
+ return 0;
+}
+
+
+EXPORT_SYM const struct mod_export DECL_EXPORTS(mwi) = {
+ "mwi",
+ "application",
+ module_init,
+ module_close,
+};