summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-10-20 19:33:37 +0200
committerAlfred E. Heggestad <aeh@db.org>2014-10-20 19:33:37 +0200
commit0c0f21b0543b44d9243e4215ace9ce2cd2fc278b (patch)
tree90eee9dda89a0aa71f29a05d537d242fe63ac25e /src
parent76db3b6d9fabb4c9460c917bfc4405a50897658e (diff)
parent35212dfd41c16706affa9ec648d2a4aab4cc9267 (diff)
Merge pull request #25 from alfredh/gruu
gruu: preliminary support for SIP GRUU
Diffstat (limited to 'src')
-rw-r--r--src/reg.c14
-rw-r--r--src/ua.c47
2 files changed, 57 insertions, 4 deletions
diff --git a/src/reg.c b/src/reg.c
index 2588873..1f8f840 100644
--- a/src/reg.c
+++ b/src/reg.c
@@ -138,6 +138,18 @@ static void register_handler(int err, const struct sip_msg *msg, void *arg)
reg->scode = msg->scode;
+ hdr = sip_msg_hdr(msg, SIP_HDR_CONTACT);
+ if (hdr) {
+ struct sip_addr addr;
+ struct pl pval;
+
+ if (0 == sip_addr_decode(&addr, &hdr->val) &&
+ 0 == msg_param_decode(&addr.params, "pub-gruu",
+ &pval)) {
+ ua_pub_gruu_set(reg->ua, &pval);
+ }
+ }
+
ua_event(reg->ua, UA_EVENT_REGISTER_OK, NULL, "%u %r",
msg->scode, &msg->reason);
}
@@ -191,7 +203,7 @@ int reg_register(struct reg *reg, const char *reg_uri, const char *params,
reg->sipreg = mem_deref(reg->sipreg);
err = sipreg_register(&reg->sipreg, uag_sip(), reg_uri,
ua_aor(reg->ua), ua_aor(reg->ua),
- regint, ua_cuser(reg->ua),
+ regint, ua_local_cuser(reg->ua),
routev[0] ? routev : NULL,
routev[0] ? 1 : 0,
reg->id,
diff --git a/src/ua.c b/src/ua.c
index 5759b5f..be4c425 100644
--- a/src/ua.c
+++ b/src/ua.c
@@ -31,6 +31,7 @@ struct ua {
struct pl extensionv[8]; /**< Vector of SIP extensions */
size_t extensionc; /**< Number of SIP extensions */
char *cuser; /**< SIP Contact username */
+ char *pub_gruu; /**< SIP Public GRUU */
int af; /**< Preferred Address Family */
};
@@ -374,6 +375,7 @@ static int ua_call_alloc(struct call **callp, struct ua *ua,
static void handle_options(struct ua *ua, const struct sip_msg *msg)
{
+ struct sip_contact contact;
struct call *call = NULL;
struct mbuf *desc = NULL;
int err;
@@ -388,17 +390,20 @@ static void handle_options(struct ua *ua, const struct sip_msg *msg)
if (err)
goto out;
+ sip_contact_set(&contact, ua_cuser(ua), &msg->dst, msg->tp);
+
err = sip_treplyf(NULL, NULL, uag.sip,
msg, true, 200, "OK",
- "Contact: <sip:%s@%J%s>\r\n"
+ "%H"
"Content-Type: application/sdp\r\n"
"Content-Length: %zu\r\n"
"\r\n"
"%b",
- ua->cuser, &msg->dst, sip_transp_param(msg->tp),
+ sip_contact_print, &contact,
mbuf_get_left(desc),
mbuf_buf(desc),
mbuf_get_left(desc));
+
if (err) {
warning("ua: options: sip_treplyf: %m\n", err);
}
@@ -426,6 +431,7 @@ static void ua_destructor(void *arg)
list_flush(&ua->regl);
mem_deref(ua->play);
mem_deref(ua->cuser);
+ mem_deref(ua->pub_gruu);
mem_deref(ua->acc);
}
@@ -526,6 +532,9 @@ int ua_alloc(struct ua **uap, const char *aor)
}
/* Register clients */
+ if (str_isset(uag.cfg->uuid))
+ add_extension(ua, "gruu");
+
if (0 == str_casecmp(ua->acc->sipnat, "outbound")) {
size_t i;
@@ -849,6 +858,7 @@ int ua_debug(struct re_printf *pf, const struct ua *ua)
err = re_hprintf(pf, "--- %s ---\n", ua->acc->aor);
err |= re_hprintf(pf, " cuser: %s\n", ua->cuser);
+ err |= re_hprintf(pf, " pub-gruu: %s\n", ua->pub_gruu);
err |= re_hprintf(pf, " af: %s\n", net_af2name(ua->af));
err |= re_hprintf(pf, " %H", ua_print_supported, ua);
@@ -1463,7 +1473,10 @@ struct ua *uag_find_param(const char *name, const char *value)
/**
- * Get the contact user of a User-Agent (UA)
+ * Get the contact user/uri of a User-Agent (UA)
+ *
+ * If the Public GRUU is set, it will be returned.
+ * Otherwise the local contact-user (cuser) will be returned.
*
* @param ua User-Agent
*
@@ -1471,6 +1484,18 @@ struct ua *uag_find_param(const char *name, const char *value)
*/
const char *ua_cuser(const struct ua *ua)
{
+ if (!ua)
+ return NULL;
+
+ if (str_isset(ua->pub_gruu))
+ return ua->pub_gruu;
+
+ return ua->cuser;
+}
+
+
+const char *ua_local_cuser(const struct ua *ua)
+{
return ua ? ua->cuser : NULL;
}
@@ -1488,6 +1513,22 @@ struct account *ua_account(const struct ua *ua)
}
+/**
+ * Set Public GRUU of a User-Agent (UA)
+ *
+ * @param ua User-Agent
+ * @param pval Public GRUU
+ */
+void ua_pub_gruu_set(struct ua *ua, const struct pl *pval)
+{
+ if (!ua)
+ return;
+
+ ua->pub_gruu = mem_deref(ua->pub_gruu);
+ (void)pl_strdup(&ua->pub_gruu, pval);
+}
+
+
struct list *uag_list(void)
{
return &uag.ual;