diff options
author | Alfred E. Heggestad <aeh@db.org> | 2014-02-09 11:50:07 +0100 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2014-02-09 11:50:07 +0100 |
commit | 98bf08bdcf2edd9d397f32650a8bfe62186fbecf (patch) | |
tree | ebc6ec71f44bff8c42e4eefced61948623df02fc /src/contact.c | |
parent | e6ad5cf4401b860ba402d4b7b3c7c254bc87a019 (diff) |
baresip 0.4.10
Diffstat (limited to 'src/contact.c')
-rw-r--r-- | src/contact.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/contact.c b/src/contact.c new file mode 100644 index 0000000..5161a1c --- /dev/null +++ b/src/contact.c @@ -0,0 +1,161 @@ +/** + * @file src/contact.c Contacts handling + * + * Copyright (C) 2010 Creytiv.com + */ +#include <re.h> +#include <baresip.h> + + +struct contact { + struct le le; + struct sip_addr addr; + char *buf; + enum presence_status status; +}; + +static struct list cl; + + +static void destructor(void *arg) +{ + struct contact *c = arg; + + list_unlink(&c->le); + mem_deref(c->buf); +} + + +/** + * Add a contact + * + * @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) +{ + struct contact *c; + struct pl pl; + int err; + + c = mem_zalloc(sizeof(*c), destructor); + if (!c) + return ENOMEM; + + err = pl_strdup(&c->buf, addr); + if (err) + goto out; + + pl_set_str(&pl, c->buf); + + err = sip_addr_decode(&c->addr, &pl); + if (err) { + warning("contact: decode error '%r'\n", addr); + goto out; + } + + c->status = PRESENCE_UNKNOWN; + + list_append(&cl, &c->le, c); + + out: + if (err) + mem_deref(c); + else if (contactp) + *contactp = c; + + return err; +} + + +/** + * Get the SIP address of a contact + * + * @param c Contact + * + * @return SIP Address + */ +struct sip_addr *contact_addr(const struct contact *c) +{ + return c ? (struct sip_addr *)&c->addr : NULL; +} + + +/** + * Get the contact string + * + * @param c Contact + * + * @return Contact string + */ +const char *contact_str(const struct contact *c) +{ + return c ? c->buf : NULL; +} + + +/** + * Get the list of contacts + * + * @return List of contacts + */ +struct list *contact_list(void) +{ + return &cl; +} + + +void contact_set_presence(struct contact *c, enum presence_status status) +{ + if (!c) + return; + + if (c->status != PRESENCE_UNKNOWN && c->status != status) { + + info("<%r> changed status from %s to %s\n", &c->addr.auri, + contact_presence_str(c->status), + contact_presence_str(status)); + } + + c->status = status; +} + + +const char *contact_presence_str(enum presence_status status) +{ + switch (status) { + + default: + case PRESENCE_UNKNOWN: return "\x1b[32m\x1b[;m"; + case PRESENCE_OPEN: return "\x1b[32mOnline\x1b[;m"; + case PRESENCE_CLOSED: return "\x1b[31mOffline\x1b[;m"; + case PRESENCE_BUSY: return "\x1b[31mBusy\x1b[;m"; + } +} + + +int contacts_print(struct re_printf *pf, void *unused) +{ + struct le *le; + int err; + + (void)unused; + + err = re_hprintf(pf, "\n--- Contacts: (%u) ---\n", + list_count(contact_list())); + + for (le = list_head(contact_list()); le && !err; le = le->next) { + const struct contact *c = le->data; + const struct sip_addr *addr = &c->addr; + + err = re_hprintf(pf, "%20s %r <%r>\n", + contact_presence_str(c->status), + &addr->dname, &addr->auri); + } + + err |= re_hprintf(pf, "\n"); + + return err; +} |