From 31baf6937aee6f449a6675e102d6f0831bfb1fbe Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Sun, 3 Apr 2016 17:35:05 +0200 Subject: test: added test-case for authenticated register --- test/sip/location.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 test/sip/location.c (limited to 'test/sip/location.c') diff --git a/test/sip/location.c b/test/sip/location.c new file mode 100644 index 0000000..be2bd66 --- /dev/null +++ b/test/sip/location.c @@ -0,0 +1,188 @@ +/** + * @file sip/location.c Mock SIP server -- location handling + * + * Copyright (C) 2010 - 2016 Creytiv.com + */ +#include +#include +#include "sipsrv.h" + + +struct loctmp { + struct sa src; + struct uri duri; + char *uri; + char *callid; + uint32_t expires; + uint32_t cseq; + double q; +}; + + +static void destructor_loctmp(void *arg) +{ + struct loctmp *tmp = arg; + + mem_deref(tmp->uri); + mem_deref(tmp->callid); +} + + +static void destructor_location(void *arg) +{ + struct location *loc = arg; + + list_unlink(&loc->le); + mem_deref(loc->uri); + mem_deref(loc->callid); + mem_deref(loc->tmp); +} + + +static bool cmp_handler(struct le *le, void *arg) +{ + struct location *loc = le->data; + + return uri_cmp(&loc->duri, arg); +} + + +int location_update(struct list *locl, const struct sip_msg *msg, + const struct sip_addr *contact, uint32_t expires) +{ + struct location *loc, *loc_new = NULL; + struct loctmp *tmp; + struct pl pl; + int err; + + if (!locl || !msg || !contact) + return EINVAL; + + loc = list_ledata(list_apply(locl, true, cmp_handler, + (void *)&contact->uri)); + if (!loc) { + if (expires == 0) + return 0; + + loc = loc_new = mem_zalloc(sizeof(*loc), destructor_location); + if (!loc) + return ENOMEM; + + list_append(locl, &loc->le, loc); + } + else { + if (!pl_strcmp(&msg->callid, loc->callid) && + msg->cseq.num <= loc->cseq) + return EPROTO; + + if (expires == 0) { + loc->rm = true; + return 0; + } + } + + tmp = mem_zalloc(sizeof(*tmp), destructor_loctmp); + if (!tmp) { + err = ENOMEM; + goto out; + } + + err = pl_strdup(&tmp->uri, &contact->auri); + if (err) + goto out; + + pl_set_str(&pl, tmp->uri); + + if (uri_decode(&tmp->duri, &pl)) { + err = EBADMSG; + goto out; + } + + err = pl_strdup(&tmp->callid, &msg->callid); + if (err) + goto out; + + + if (!msg_param_decode(&contact->params, "q", &pl)) + tmp->q = pl_float(&pl); + else + tmp->q = 1; + + tmp->cseq = msg->cseq.num; + tmp->expires = expires; + tmp->src = msg->src; + + out: + if (err) { + mem_deref(loc_new); + mem_deref(tmp); + } + else { + mem_deref(loc->tmp); + loc->tmp = tmp; + } + + return err; +} + + +void location_commit(struct list *locl) +{ + time_t now = time(NULL); + struct le *le; + + if (!locl) + return; + + for (le=locl->head; le; ) { + + struct location *loc = le->data; + + le = le->next; + + if (loc->rm) { + list_unlink(&loc->le); + mem_deref(loc); + } + else if (loc->tmp) { + + mem_deref(loc->uri); + mem_deref(loc->callid); + + loc->uri = mem_ref(loc->tmp->uri); + loc->callid = mem_ref(loc->tmp->callid); + loc->duri = loc->tmp->duri; + loc->cseq = loc->tmp->cseq; + loc->expires = loc->tmp->expires + now; + loc->src = loc->tmp->src; + loc->q = loc->tmp->q; + + loc->tmp = mem_deref(loc->tmp); + } + } +} + + +void location_rollback(struct list *locl) +{ + struct le *le; + + if (!locl) + return; + + for (le=locl->head; le; ) { + + struct location *loc = le->data; + + le = le->next; + + if (!loc->uri) { + list_unlink(&loc->le); + mem_deref(loc); + } + else { + loc->tmp = mem_deref(loc->tmp); + loc->rm = false; + } + } +} -- cgit v1.2.3