summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlfred E. Heggestad <alfred.heggestad@gmail.com>2017-02-23 19:21:50 +0100
committerGitHub <noreply@github.com>2017-02-23 19:21:50 +0100
commitfb6bf93a7816516247523bd004737b2d1f3bba86 (patch)
tree334abf16f49890e6825c815a5b889f675c2033fb /src
parent39ff942fa874ff0d698d3ac938a6c8c741afb107 (diff)
Message reentrant (#214)
* message: make it re-entrant * clean up message test-code
Diffstat (limited to 'src')
-rw-r--r--src/baresip.c14
-rw-r--r--src/message.c125
2 files changed, 104 insertions, 35 deletions
diff --git a/src/baresip.c b/src/baresip.c
index 07dfbca..809f106 100644
--- a/src/baresip.c
+++ b/src/baresip.c
@@ -17,6 +17,7 @@ static struct baresip {
struct contacts contacts;
struct commands *commands;
struct player *player;
+ struct message *message;
struct list mnatl;
struct list mencl;
} baresip;
@@ -54,12 +55,19 @@ int baresip_init(struct config *cfg, bool prefer_ipv6)
if (err)
return err;
+ err = message_init(&baresip.message);
+ if (err) {
+ warning("baresip: message init failed: %m\n", err);
+ return err;
+ }
+
return 0;
}
void baresip_close(void)
{
+ baresip.message = mem_deref(baresip.message);
baresip.player = mem_deref(baresip.player);
baresip.commands = mem_deref(baresip.commands);
contact_close(&baresip.contacts);
@@ -102,3 +110,9 @@ struct list *baresip_mencl(void)
{
return &baresip.mencl;
}
+
+
+struct message *baresip_message(void)
+{
+ return baresip.message;
+}
diff --git a/src/message.c b/src/message.c
index 9d3662b..98eb963 100644
--- a/src/message.c
+++ b/src/message.c
@@ -8,19 +8,47 @@
#include "core.h"
-static struct sip_lsnr *lsnr;
-static message_recv_h *recvh;
-static void *recvarg;
+struct message {
+ struct list lsnrl;
+ struct sip_lsnr *sip_lsnr;
+};
+struct message_lsnr {
+ struct le le;
+ message_recv_h *recvh;
+ void *arg;
+};
-static void handle_message(struct ua *ua, const struct sip_msg *msg)
+
+static void destructor(void *data)
+{
+ struct message *message = data;
+
+ list_flush(&message->lsnrl);
+ mem_deref(message->sip_lsnr);
+}
+
+
+static void listener_destructor(void *data)
+{
+ struct message_lsnr *lsnr = data;
+
+ list_unlink(&lsnr->le);
+}
+
+
+static void handle_message(struct message_lsnr *lsnr, struct ua *ua,
+ const struct sip_msg *msg)
{
static const char ctype_text[] = "text/plain";
struct pl ctype_pl = {ctype_text, sizeof(ctype_text)-1};
(void)ua;
- if (msg_ctype_cmp(&msg->ctyp, "text", "plain") && recvh) {
- recvh(&msg->from.auri, &ctype_pl, msg->mb, recvarg);
+ if (msg_ctype_cmp(&msg->ctyp, "text", "plain") && lsnr->recvh) {
+
+ lsnr->recvh(&msg->from.auri, &ctype_pl,
+ msg->mb, lsnr->arg);
+
(void)sip_reply(uag_sip(), msg, 200, "OK");
}
else {
@@ -35,9 +63,10 @@ static void handle_message(struct ua *ua, const struct sip_msg *msg)
static bool request_handler(const struct sip_msg *msg, void *arg)
{
+ struct message *message = arg;
struct ua *ua;
-
- (void)arg;
+ struct le *le = message->lsnrl.head;
+ bool hdld = false;
if (pl_strcmp(&msg->met, "MESSAGE"))
return false;
@@ -48,48 +77,73 @@ static bool request_handler(const struct sip_msg *msg, void *arg)
return true;
}
- handle_message(ua, msg);
+ while (le) {
+ struct message_lsnr *lsnr = le->data;
+
+ le = le->next;
- return true;
+ handle_message(lsnr, ua, msg);
+
+ hdld = true;
+ }
+
+ return hdld;
}
-static void resp_handler(int err, const struct sip_msg *msg, void *arg)
+int message_init(struct message **messagep)
{
- struct ua *ua = arg;
+ struct message *message;
+ int err = 0;
- (void)ua;
+ if (!messagep)
+ return EINVAL;
- if (err) {
- (void)re_fprintf(stderr, " \x1b[31m%m\x1b[;m\n", err);
- return;
- }
+ message = mem_zalloc(sizeof(*message), destructor);
+ if (!message)
+ return ENOMEM;
- if (msg->scode >= 300) {
- (void)re_fprintf(stderr, " \x1b[31m%u %r\x1b[;m\n",
- msg->scode, &msg->reason);
- }
+ /* note: cannot create sip listener here, there is not UAs yet */
+
+ if (err)
+ mem_deref(message);
+ else
+ *messagep = message;
+
+ return err;
}
-int message_init(message_recv_h *h, void *arg)
+int message_listen(struct message_lsnr **lsnrp, struct message *message,
+ message_recv_h *recvh, void *arg)
{
- int err;
+ struct message_lsnr *lsnr;
+ int err = 0;
- err = sip_listen(&lsnr, uag_sip(), true, request_handler, NULL);
- if (err)
- return err;
+ if (!message || !recvh)
+ return EINVAL;
- recvh = h;
- recvarg = arg;
+ /* create the SIP listener if it does not exist */
+ if (!message->sip_lsnr) {
- return 0;
-}
+ err = sip_listen(&message->sip_lsnr, uag_sip(), true,
+ request_handler, message);
+ if (err)
+ goto out;
+ }
+ lsnr = mem_zalloc(sizeof(*lsnr), listener_destructor);
-void message_close(void)
-{
- lsnr = mem_deref(lsnr);
+ lsnr->recvh = recvh;
+ lsnr->arg = arg;
+
+ list_append(&message->lsnrl, &lsnr->le, lsnr);
+
+ if (lsnrp)
+ *lsnrp = lsnr;
+
+ out:
+ return err;
}
@@ -102,7 +156,8 @@ void message_close(void)
*
* @return 0 if success, otherwise errorcode
*/
-int message_send(struct ua *ua, const char *peer, const char *msg)
+int message_send(struct ua *ua, const char *peer, const char *msg,
+ sip_resp_h *resph, void *arg)
{
struct sip_addr addr;
struct pl pl;
@@ -122,7 +177,7 @@ int message_send(struct ua *ua, const char *peer, const char *msg)
if (err)
return err;
- err = sip_req_send(ua, "MESSAGE", uri, resp_handler, ua,
+ err = sip_req_send(ua, "MESSAGE", uri, resph, arg,
"Accept: text/plain\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %zu\r\n"