sip: add sip contact, needed for GRUU

- in sipsess and sipevent, the cuser parameter can now be
  a contact-username or a uri (e.g. GRUU)

- Tested by Juha Heinanen (with baresip+gruu)
This commit is contained in:
Alfred E. Heggestad 2014-09-25 07:51:19 +00:00
parent 502a4e63d6
commit 9ff9a24c48
10 changed files with 118 additions and 26 deletions

View file

@ -214,6 +214,13 @@ struct sip_loopstate {
uint16_t last_scode;
};
/** SIP Contact */
struct sip_contact {
const char *uri;
const struct sa *addr;
enum sip_transp tp;
};
struct sip;
struct sip_lsnr;
struct sip_request;
@ -303,6 +310,13 @@ int sip_auth_alloc(struct sip_auth **authp, sip_auth_h *authh,
void sip_auth_reset(struct sip_auth *auth);
/* contact */
void sip_contact_set(struct sip_contact *contact, const char *uri,
const struct sa *addr, enum sip_transp tp);
int sip_contact_print(struct re_printf *pf,
const struct sip_contact *contact);
/* dialog */
int sip_dialog_alloc(struct sip_dialog **dlgp,
const char *uri, const char *to_uri,

57
src/sip/contact.c Normal file
View file

@ -0,0 +1,57 @@
/**
* @file sip/contact.c SIP contact functions
*
* Copyright (C) 2010 Creytiv.com
*/
#include <string.h>
#include <re_types.h>
#include <re_fmt.h>
#include <re_mbuf.h>
#include <re_uri.h>
#include <re_list.h>
#include <re_sa.h>
#include <re_msg.h>
#include <re_sip.h>
/**
* Set contact parameters
*
* @param contact SIP Contact object
* @param uri Username or URI
* @param addr IP-address and port
* @param tp SIP Transport
*/
void sip_contact_set(struct sip_contact *contact, const char *uri,
const struct sa *addr, enum sip_transp tp)
{
if (!contact)
return;
contact->uri = uri;
contact->addr = addr;
contact->tp = tp;
}
/**
* Print contact header
*
* @param pf Print function
* @param contact SIP Contact object
*
* @return 0 for success, otherwise errorcode
*/
int sip_contact_print(struct re_printf *pf, const struct sip_contact *contact)
{
if (!contact)
return 0;
if (contact->uri && strchr(contact->uri, ':'))
return re_hprintf(pf, "Contact: <%s>\r\n", contact->uri);
else
return re_hprintf(pf, "Contact: <sip:%s@%J%s>\r\n",
contact->uri,
contact->addr,
sip_transp_param(contact->tp));
}

View file

@ -6,6 +6,7 @@
SRCS += sip/addr.c
SRCS += sip/auth.c
SRCS += sip/contact.c
SRCS += sip/cseq.c
SRCS += sip/ctrans.c
SRCS += sip/dialog.c

View file

@ -177,11 +177,13 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
static int send_handler(enum sip_transp tp, const struct sa *src,
const struct sa *dst, struct mbuf *mb, void *arg)
{
struct sip_contact contact;
struct sipnot *not = arg;
(void)dst;
return mbuf_printf(mb, "Contact: <sip:%s@%J%s>\r\n",
not->cuser, src, sip_transp_param(tp));
sip_contact_set(&contact, not->cuser, src, tp);
return mbuf_printf(mb, "%H", sip_contact_print, &contact);
}
@ -282,16 +284,19 @@ int sipnot_notify(struct sipnot *not)
int sipnot_reply(struct sipnot *not, const struct sip_msg *msg,
uint16_t scode, const char *reason)
{
struct sip_contact contact;
uint32_t expires;
expires = (uint32_t)(tmr_get_expire(&not->tmr) / 1000);
sip_contact_set(&contact, not->cuser, &msg->dst, msg->tp);
return sip_treplyf(NULL, NULL, not->sip, msg, true, scode, reason,
"Contact: <sip:%s@%J%s>\r\n"
"%H"
"Expires: %u\r\n"
"Content-Length: 0\r\n"
"\r\n",
not->cuser, &msg->dst, sip_transp_param(msg->tp),
sip_contact_print, &contact,
expires);
}

View file

@ -298,11 +298,13 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
static int send_handler(enum sip_transp tp, const struct sa *src,
const struct sa *dst, struct mbuf *mb, void *arg)
{
struct sip_contact contact;
struct sipsub *sub = arg;
(void)dst;
return mbuf_printf(mb, "Contact: <sip:%s@%J%s>\r\n",
sub->cuser, src, sip_transp_param(tp));
sip_contact_set(&contact, sub->cuser, src, tp);
return mbuf_printf(mb, "%H", sip_contact_print, &contact);
}
@ -449,7 +451,7 @@ static int sipsub_alloc(struct sipsub **subp, struct sipevent_sock *sock,
* @param event SIP Event to subscribe to
* @param id SIP Event ID (optional)
* @param expires Subscription expires value
* @param cuser Contact username
* @param cuser Contact username or URI
* @param routev Optional route vector
* @param routec Number of routes
* @param authh Authentication handler
@ -496,7 +498,7 @@ int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
* @param event SIP Event to subscribe to
* @param id SIP Event ID (optional)
* @param expires Subscription expires value
* @param cuser Contact username
* @param cuser Contact username or URI
* @param authh Authentication handler
* @param aarg Authentication handler argument
* @param aref True to ref argument
@ -536,7 +538,7 @@ int sipevent_dsubscribe(struct sipsub **subp, struct sipevent_sock *sock,
* @param uri SIP Request URI
* @param from_name SIP From-header Name (optional)
* @param from_uri SIP From-header URI
* @param cuser Contact username
* @param cuser Contact username or URI
* @param routev Optional route vector
* @param routec Number of routes
* @param authh Authentication handler
@ -579,7 +581,7 @@ int sipevent_refer(struct sipsub **subp, struct sipevent_sock *sock,
* @param subp Pointer to allocated SIP subscriber client
* @param sock SIP Event socket
* @param dlg Established SIP Dialog
* @param cuser Contact username
* @param cuser Contact username or URI
* @param authh Authentication handler
* @param aarg Authentication handler argument
* @param aref True to ref argument

View file

@ -293,7 +293,7 @@ static int request(struct sipreg *reg, bool reset_ls)
"Content-Length: 0\r\n"
"\r\n",
reg->regid > 0
? "Supported: outbound, path\r\n" : "",
? "Supported: gruu, outbound, path\r\n" : "",
reg->hdrs ? mbuf_buf(reg->hdrs) : NULL,
reg->hdrs ? mbuf_get_left(reg->hdrs) : (size_t)0);
}

View file

@ -42,7 +42,7 @@ static void cancel_handler(void *arg)
* @param msg Incoming SIP message
* @param scode Response status code
* @param reason Response reason phrase
* @param cuser Contact username
* @param cuser Contact username or URI
* @param ctype Session content-type
* @param desc Content description (e.g. SDP)
* @param authh SIP Authentication handler
@ -103,17 +103,20 @@ int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
if (scode >= 200)
err = sipsess_reply_2xx(sess, msg, scode, reason, desc,
fmt, &ap);
else
else {
struct sip_contact contact;
sip_contact_set(&contact, sess->cuser, &msg->dst, msg->tp);
err = sip_treplyf(&sess->st, NULL, sess->sip,
msg, true, scode, reason,
"Contact: <sip:%s@%J%s>\r\n"
"%H"
"%v"
"%s%s%s"
"Content-Length: %zu\r\n"
"\r\n"
"%b",
sess->cuser, &msg->dst,
sip_transp_param(msg->tp),
sip_contact_print, &contact,
fmt, &ap,
desc ? "Content-Type: " : "",
desc ? sess->ctype : "",
@ -121,6 +124,7 @@ int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
desc ? mbuf_get_left(desc) : (size_t)0,
desc ? mbuf_buf(desc) : NULL,
desc ? mbuf_get_left(desc) : (size_t)0);
}
va_end(ap);
@ -151,6 +155,7 @@ int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
int sipsess_progress(struct sipsess *sess, uint16_t scode, const char *reason,
struct mbuf *desc, const char *fmt, ...)
{
struct sip_contact contact;
va_list ap;
int err;
@ -159,16 +164,17 @@ int sipsess_progress(struct sipsess *sess, uint16_t scode, const char *reason,
va_start(ap, fmt);
sip_contact_set(&contact, sess->cuser, &sess->msg->dst, sess->msg->tp);
err = sip_treplyf(&sess->st, NULL, sess->sip, sess->msg, true,
scode, reason,
"Contact: <sip:%s@%J%s>\r\n"
"%H"
"%v"
"%s%s%s"
"Content-Length: %zu\r\n"
"\r\n"
"%b",
sess->cuser, &sess->msg->dst,
sip_transp_param(sess->msg->tp),
sip_contact_print, &contact,
fmt, &ap,
desc ? "Content-Type: " : "",
desc ? sess->ctype : "",

View file

@ -25,11 +25,13 @@ static int invite(struct sipsess *sess);
static int send_handler(enum sip_transp tp, const struct sa *src,
const struct sa *dst, struct mbuf *mb, void *arg)
{
struct sip_contact contact;
struct sipsess *sess = arg;
(void)dst;
return mbuf_printf(mb, "Contact: <sip:%s@%J%s>\r\n",
sess->cuser, src, sip_transp_param(tp));
sip_contact_set(&contact, sess->cuser, src, tp);
return mbuf_printf(mb, "%H", sip_contact_print, &contact);
}
@ -156,7 +158,7 @@ static int invite(struct sipsess *sess)
* @param to_uri To SIP uri
* @param from_name From display name
* @param from_uri From SIP uri
* @param cuser Contact username
* @param cuser Contact username or URI
* @param routev Outbound route vector
* @param routec Outbound route vector count
* @param ctype Session content-type

View file

@ -109,11 +109,13 @@ static void reinvite_resp_handler(int err, const struct sip_msg *msg,
static int send_handler(enum sip_transp tp, const struct sa *src,
const struct sa *dst, struct mbuf *mb, void *arg)
{
struct sip_contact contact;
struct sipsess *sess = arg;
(void)dst;
return mbuf_printf(mb, "Contact: <sip:%s@%J%s>\r\n",
sess->cuser, src, sip_transp_param(tp));
sip_contact_set(&contact, sess->cuser, src, tp);
return mbuf_printf(mb, "%H", sip_contact_print, &contact);
}

View file

@ -82,6 +82,7 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg,
const char *fmt, va_list *ap)
{
struct sipsess_reply *reply;
struct sip_contact contact;
int err = ENOMEM;
reply = mem_zalloc(sizeof(*reply), destructor);
@ -93,15 +94,17 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg,
reply->msg = mem_ref((void *)msg);
reply->sess = sess;
sip_contact_set(&contact, sess->cuser, &msg->dst, msg->tp);
err = sip_treplyf(&sess->st, &reply->mb, sess->sip,
msg, true, scode, reason,
"Contact: <sip:%s@%J%s>\r\n"
"%H"
"%v"
"%s%s%s"
"Content-Length: %zu\r\n"
"\r\n"
"%b",
sess->cuser, &msg->dst, sip_transp_param(msg->tp),
sip_contact_print, &contact,
fmt, ap,
desc ? "Content-Type: " : "",
desc ? sess->ctype : "",