summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2016-07-24 18:00:40 +0200
committerAlfred E. Heggestad <aeh@db.org>2016-07-24 18:00:40 +0200
commit713f55a1f9958222f85238bde40482b566cf040e (patch)
tree7ca0800a14cec6f9cbe6794a3bdcea9b42001db7
parent0a987e0a95b3473f8bc5e70455c92232d9990114 (diff)
contact: make contacts re-entrant
-rw-r--r--include/baresip.h22
-rw-r--r--modules/contact/contact.c19
-rw-r--r--modules/gtk/gtk_mod.c3
-rw-r--r--modules/gtk/uri_entry.c3
-rw-r--r--modules/presence/subscriber.c3
-rw-r--r--src/baresip.c13
-rw-r--r--src/contact.c81
-rw-r--r--src/ua.c8
-rw-r--r--test/contact.c55
-rw-r--r--test/main.c1
-rw-r--r--test/srcs.mk1
-rw-r--r--test/test.h1
12 files changed, 162 insertions, 48 deletions
diff --git a/include/baresip.h b/include/baresip.h
index 26ddf4b..c6d8ae8 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -262,17 +262,24 @@ enum presence_status {
PRESENCE_BUSY
};
+struct contacts {
+ struct list cl;
+ struct hash *cht;
+};
+
struct contact;
-int contact_init(void);
-void contact_close(void);
-int contact_add(struct contact **contactp, const struct pl *addr);
-int contacts_print(struct re_printf *pf, void *unused);
+int contact_init(struct contacts *contacts);
+void contact_close(struct contacts *contacts);
+int contact_add(struct contacts *contacts,
+ struct contact **contactp, const struct pl *addr);
+int contacts_print(struct re_printf *pf, const struct contacts *contacts);
void contact_set_presence(struct contact *c, enum presence_status status);
-bool contact_block_access(const char *uri);
-struct contact *contact_find(const char *uri);
+bool contact_block_access(const struct contacts *contacts, const char *uri);
+struct contact *contact_find(const struct contacts *contacts,
+ const char *uri);
struct sip_addr *contact_addr(const struct contact *c);
-struct list *contact_list(void);
+struct list *contact_list(const struct contacts *contacts);
const char *contact_str(const struct contact *c);
const char *contact_presence_str(enum presence_status status);
@@ -1076,6 +1083,7 @@ double mos_calculate(double *r_factor, double rtt,
int baresip_init(struct config *cfg, bool prefer_ipv6);
void baresip_close(void);
struct network *baresip_network(void);
+struct contacts *baresip_contacts(void);
#ifdef __cplusplus
diff --git a/modules/contact/contact.c b/modules/contact/contact.c
index 42ff614..2a566eb 100644
--- a/modules/contact/contact.c
+++ b/modules/contact/contact.c
@@ -24,13 +24,14 @@ static char cmd_desc[128] = "Send MESSAGE to peer";
static int confline_handler(const struct pl *addr)
{
- return contact_add(NULL, addr);
+ return contact_add(baresip_contacts(), NULL, addr);
}
static int cmd_contact(struct re_printf *pf, void *arg)
{
const struct cmd_arg *carg = arg;
+ struct contacts *contacts = baresip_contacts();
struct contact *cnt = NULL;
struct pl dname, user, pl;
struct le *le;
@@ -42,7 +43,7 @@ static int cmd_contact(struct re_printf *pf, void *arg)
err |= re_hprintf(pf, "\n");
- for (le = list_head(contact_list()); le; le = le->next) {
+ for (le = list_head(contact_list(contacts)); le; le = le->next) {
struct contact *c = le->data;
@@ -101,6 +102,13 @@ static int cmd_contact(struct re_printf *pf, void *arg)
}
+static int print_contacts(struct re_printf *pf, void *unused)
+{
+ (void)unused;
+ return contacts_print(pf, baresip_contacts());
+}
+
+
static int cmd_message(struct re_printf *pf, void *arg)
{
const struct cmd_arg *carg = arg;
@@ -120,7 +128,7 @@ static int cmd_message(struct re_printf *pf, void *arg)
static const struct cmd cmdv[] = {
{'/', CMD_IPRM, "Dial from contacts", cmd_contact },
{'=', CMD_IPRM, "Select chat peer", cmd_contact },
- {'C', 0, "List contacts", contacts_print },
+ {'C', 0, "List contacts", print_contacts },
{'-', CMD_PRM, cmd_desc, cmd_message },
};
@@ -201,7 +209,8 @@ static int module_init(void)
if (err)
return err;
- info("Populated %u contacts\n", list_count(contact_list()));
+ info("Populated %u contacts\n",
+ list_count(contact_list(baresip_contacts())));
return err;
}
@@ -210,7 +219,7 @@ static int module_init(void)
static int module_close(void)
{
cmd_unregister(cmdv);
- list_flush(contact_list());
+ list_flush(contact_list(baresip_contacts()));
return 0;
}
diff --git a/modules/gtk/gtk_mod.c b/modules/gtk/gtk_mod.c
index 5e01882..55559d8 100644
--- a/modules/gtk/gtk_mod.c
+++ b/modules/gtk/gtk_mod.c
@@ -142,12 +142,13 @@ static void menu_on_dial_contact(GtkMenuItem *menuItem, gpointer arg)
static void init_contacts_menu(struct gtk_mod *mod)
{
+ struct contacts *contacts = baresip_contacts();
struct le *le;
GtkWidget *item;
GtkMenuShell *contacts_menu = GTK_MENU_SHELL(mod->contacts_menu);
/* Add contacts to submenu */
- for (le = list_head(contact_list()); le; le = le->next) {
+ for (le = list_head(contact_list(contacts)); le; le = le->next) {
struct contact *c = le->data;
item = gtk_menu_item_new_with_label(contact_str(c));
gtk_menu_shell_append(contacts_menu, item);
diff --git a/modules/gtk/uri_entry.c b/modules/gtk/uri_entry.c
index 601bf83..0ca1a3d 100644
--- a/modules/gtk/uri_entry.c
+++ b/modules/gtk/uri_entry.c
@@ -18,6 +18,7 @@
*/
GtkWidget *uri_combo_box_new(void)
{
+ struct contacts *contacts = baresip_contacts();
struct le *le;
GtkEntry *uri_entry;
GtkWidget *uri_combobox;
@@ -26,7 +27,7 @@ GtkWidget *uri_combo_box_new(void)
uri_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(uri_combobox)));
gtk_entry_set_activates_default(uri_entry, TRUE);
- for (le = list_head(contact_list()); le; le = le->next) {
+ for (le = list_head(contact_list(contacts)); le; le = le->next) {
struct contact *c = le->data;
gtk_combo_box_text_append_text(
GTK_COMBO_BOX_TEXT(uri_combobox),
diff --git a/modules/presence/subscriber.c b/modules/presence/subscriber.c
index baf0b0c..b61e454 100644
--- a/modules/presence/subscriber.c
+++ b/modules/presence/subscriber.c
@@ -282,10 +282,11 @@ static int presence_alloc(struct contact *contact)
int subscriber_init(void)
{
+ struct contacts *contacts = baresip_contacts();
struct le *le;
int err = 0;
- for (le = list_head(contact_list()); le; le = le->next) {
+ for (le = list_head(contact_list(contacts)); le; le = le->next) {
struct contact *c = le->data;
struct sip_addr *addr = contact_addr(c);
diff --git a/src/baresip.c b/src/baresip.c
index f70824c..72d13f1 100644
--- a/src/baresip.c
+++ b/src/baresip.c
@@ -14,6 +14,7 @@
*/
static struct baresip {
struct network *net;
+ struct contacts contacts;
} baresip;
@@ -35,12 +36,18 @@ int baresip_init(struct config *cfg, bool prefer_ipv6)
return err;
}
+ err = contact_init(&baresip.contacts);
+ if (err)
+ return err;
+
return 0;
}
void baresip_close(void)
{
+ contact_close(&baresip.contacts);
+
baresip.net = mem_deref(baresip.net);
}
@@ -49,3 +56,9 @@ struct network *baresip_network(void)
{
return baresip.net;
}
+
+
+struct contacts *baresip_contacts(void)
+{
+ return &baresip.contacts;
+}
diff --git a/src/contact.c b/src/contact.c
index e8e6df6..1fe308b 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2010 Creytiv.com
*/
+#include <string.h>
#include <re.h>
#include <baresip.h>
@@ -22,9 +23,6 @@ struct contact {
enum access access;
};
-static struct list cl;
-static struct hash *cht;
-
static void destructor(void *arg)
{
@@ -39,18 +37,20 @@ static void destructor(void *arg)
/**
* Add a contact
*
+ * @param contacts Contacts container
* @param contactp Pointer to allocated contact (optional)
* @param addr Contact in SIP address format
*
* @return 0 if success, otherwise errorcode
*/
-int contact_add(struct contact **contactp, const struct pl *addr)
+int contact_add(struct contacts *contacts,
+ struct contact **contactp, const struct pl *addr)
{
struct contact *c;
struct pl pl;
int err;
- if (!cht)
+ if (!contacts)
return EINVAL;
c = mem_zalloc(sizeof(*c), destructor);
@@ -89,8 +89,8 @@ int contact_add(struct contact **contactp, const struct pl *addr)
c->status = PRESENCE_UNKNOWN;
- list_append(&cl, &c->le, c);
- hash_append(cht, hash_joaat_pl(&c->addr.auri), &c->he, c);
+ list_append(&contacts->cl, &c->le, c);
+ hash_append(contacts->cht, hash_joaat_pl(&c->addr.auri), &c->he, c);
out:
if (err)
@@ -131,11 +131,16 @@ const char *contact_str(const struct contact *c)
/**
* Get the list of contacts
*
+ * @param contacts Contacts container
+ *
* @return List of contacts
*/
-struct list *contact_list(void)
+struct list *contact_list(const struct contacts *contacts)
{
- return &cl;
+ if (!contacts)
+ return NULL;
+
+ return (struct list *)&contacts->cl;
}
@@ -168,17 +173,21 @@ const char *contact_presence_str(enum presence_status status)
}
-int contacts_print(struct re_printf *pf, void *unused)
+int contacts_print(struct re_printf *pf, const struct contacts *contacts)
{
+ const struct list *lst;
struct le *le;
int err;
- (void)unused;
+ if (!contacts)
+ return 0;
+
+ lst = contact_list(contacts);
err = re_hprintf(pf, "\n--- Contacts: (%u) ---\n",
- list_count(contact_list()));
+ list_count(lst));
- for (le = list_head(contact_list()); le && !err; le = le->next) {
+ for (le = list_head(lst); le && !err; le = le->next) {
const struct contact *c = le->data;
const struct sip_addr *addr = &c->addr;
@@ -196,27 +205,40 @@ int contacts_print(struct re_printf *pf, void *unused)
/**
* Initialise the contacts sub-system
*
+ * @param contacts Contacts container
+ *
* @return 0 if success, otherwise errorcode
*/
-int contact_init(void)
+int contact_init(struct contacts *contacts)
{
int err = 0;
- if (!cht)
- err = hash_alloc(&cht, 32);
+ if (!contacts)
+ return EINVAL;
+
+ memset(contacts, 0, sizeof(*contacts));
+
+ list_init(&contacts->cl);
+
+ err = hash_alloc(&contacts->cht, 32);
return err;
}
/**
+ * @param contacts Contacts container
+ *
* Close the contacts sub-system
*/
-void contact_close(void)
+void contact_close(struct contacts *contacts)
{
- hash_clear(cht);
- cht = mem_deref(cht);
- list_flush(&cl);
+ if (!contacts)
+ return;
+
+ hash_clear(contacts->cht);
+ contacts->cht = mem_deref(contacts->cht);
+ list_flush(&contacts->cl);
}
@@ -231,13 +253,17 @@ static bool find_handler(struct le *le, void *arg)
/**
* Lookup a SIP uri in all registered contacts
*
- * @param uri SIP uri to lookup
+ * @param contacts Contacts container
+ * @param uri SIP uri to lookup
*
* @return Matching contact if found, otherwise NULL
*/
-struct contact *contact_find(const char *uri)
+struct contact *contact_find(const struct contacts *contacts, const char *uri)
{
- return list_ledata(hash_lookup(cht, hash_joaat_str(uri),
+ if (!contacts)
+ return NULL;
+
+ return list_ledata(hash_lookup(contacts->cht, hash_joaat_str(uri),
find_handler, (void *)uri));
}
@@ -248,19 +274,20 @@ struct contact *contact_find(const char *uri)
* - Matching uri has first presedence
* - Global <sip:*@*> uri has second presedence
*
- * @param uri SIP uri to check for access
+ * @param contacts Contacts container
+ * @param uri SIP uri to check for access
*
* @return True if blocked, false if allowed
*/
-bool contact_block_access(const char *uri)
+bool contact_block_access(const struct contacts *contacts, const char *uri)
{
struct contact *c;
- c = contact_find(uri);
+ c = contact_find(contacts, uri);
if (c && c->access != ACCESS_UNKNOWN)
return c->access == ACCESS_BLOCK;
- c = contact_find("sip:*@*");
+ c = contact_find(contacts, "sip:*@*");
if (c && c->access != ACCESS_UNKNOWN)
return c->access == ACCESS_BLOCK;
diff --git a/src/ua.c b/src/ua.c
index 3d0e935..35626f7 100644
--- a/src/ua.c
+++ b/src/ua.c
@@ -302,7 +302,8 @@ static void call_event_handler(struct call *call, enum call_event ev,
case CALL_EVENT_INCOMING:
- if (contact_block_access(peeruri)) {
+ if (contact_block_access(baresip_contacts(),
+ peeruri)) {
info("ua: blocked access: \"%s\"\n", peeruri);
@@ -1336,10 +1337,6 @@ int ua_init(const char *software, bool udp, bool tcp, bool tls,
play_init();
- err = contact_init();
- if (err)
- return err;
-
uag.use_udp = udp;
uag.use_tcp = tcp;
uag.use_tls = tls;
@@ -1395,7 +1392,6 @@ void ua_close(void)
cmd_unregister(cmdv);
play_close();
ui_reset();
- contact_close();
uag.evsock = mem_deref(uag.evsock);
uag.sock = mem_deref(uag.sock);
diff --git a/test/contact.c b/test/contact.c
new file mode 100644
index 0000000..5b357ff
--- /dev/null
+++ b/test/contact.c
@@ -0,0 +1,55 @@
+/**
+ * @file test/contact.c Baresip selftest -- contacts
+ *
+ * Copyright (C) 2010 - 2016 Creytiv.com
+ */
+#include <string.h>
+#include <re.h>
+#include <baresip.h>
+#include "test.h"
+
+
+int test_contact(void)
+{
+ struct contacts contacts;
+ struct contact *c;
+ const char *addr = "sip:neil@young.com";
+ struct pl pl_addr;
+ int err;
+
+ err = contact_init(&contacts);
+ ASSERT_EQ(0, err);
+
+ /* Verify that we have no contacts */
+
+ ASSERT_EQ(0, list_count(contact_list(&contacts)));
+
+ c = contact_find(&contacts, "sip:null@void.com");
+ ASSERT_TRUE(c == NULL);
+
+ /* Add one contact, list should have one entry and
+ find should return the added contact */
+
+ pl_set_str(&pl_addr, addr);
+ err = contact_add(&contacts, &c, &pl_addr);
+ ASSERT_EQ(0, err);
+ ASSERT_TRUE(c != NULL);
+
+ ASSERT_EQ(1, list_count(contact_list(&contacts)));
+
+ c = contact_find(&contacts, addr);
+ ASSERT_TRUE(c != NULL);
+
+ ASSERT_STREQ(addr, contact_str(c));
+
+ /* Delete 1 contact, verify that list is empty */
+
+ mem_deref(c);
+
+ ASSERT_EQ(0, list_count(contact_list(&contacts)));
+
+ out:
+ contact_close(&contacts);
+
+ return err;
+}
diff --git a/test/main.c b/test/main.c
index c9f1964..c0bc1c1 100644
--- a/test/main.c
+++ b/test/main.c
@@ -28,6 +28,7 @@ static const struct test tests[] = {
TEST(test_call_multiple),
TEST(test_call_max),
TEST(test_cmd),
+ TEST(test_contact),
TEST(test_cplusplus),
TEST(test_mos),
TEST(test_network),
diff --git a/test/srcs.mk b/test/srcs.mk
index 06b4482..2158ca8 100644
--- a/test/srcs.mk
+++ b/test/srcs.mk
@@ -9,6 +9,7 @@
# Test-cases:
#
TEST_SRCS += cmd.c
+TEST_SRCS += contact.c
TEST_SRCS += ua.c
TEST_SRCS += cplusplus.c
TEST_SRCS += call.c
diff --git a/test/test.h b/test/test.h
index e8217c9..489f8e0 100644
--- a/test/test.h
+++ b/test/test.h
@@ -87,6 +87,7 @@ int dns_server_add_srv(struct dns_server *srv, const char *name,
/* test cases */
int test_cmd(void);
+int test_contact(void);
int test_ua_alloc(void);
int test_uag_find_param(void);
int test_ua_register(void);