From 35212dfd41c16706affa9ec648d2a4aab4cc9267 Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Tue, 23 Sep 2014 20:48:31 +0200 Subject: gruu: preliminary support for SIP GRUU - the original patch was written by Juha Heinanen - this patch needs a new version of libre --- include/baresip.h | 2 ++ src/reg.c | 14 +++++++++++++- src/ua.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/include/baresip.h b/include/baresip.h index 5325bc2..8a83ad3 100644 --- a/include/baresip.h +++ b/include/baresip.h @@ -500,8 +500,10 @@ int ua_print_supported(struct re_printf *pf, const struct ua *ua); int ua_register(struct ua *ua); void ua_unregister(struct ua *ua); bool ua_isregistered(const struct ua *ua); +void ua_pub_gruu_set(struct ua *ua, const struct pl *pval); const char *ua_aor(const struct ua *ua); const char *ua_cuser(const struct ua *ua); +const char *ua_local_cuser(const struct ua *ua); struct account *ua_account(const struct ua *ua); const char *ua_outbound(const struct ua *ua); struct call *ua_call(const struct ua *ua); 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(®->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 b7cf132..bb85867 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: \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,13 +1473,28 @@ 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 * * @return Contact user */ 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; -- cgit v1.2.3