added sipevent_refer()

This commit is contained in:
Richard Aas 2011-11-30 13:59:29 +00:00
parent aa42bc518f
commit 12f862d036
5 changed files with 155 additions and 55 deletions

View file

@ -5,20 +5,29 @@
*/
struct sipevent_sock;
struct sipsub;
int sipevent_listen(struct sipevent_sock **sockp, struct sip *sip,
uint32_t htsize_not, uint32_t htsize_sub,
sip_msg_h *subh, void *arg);
struct sipsub;
int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
const char *uri, const char *from_name,
bool retry, const char *uri, const char *from_name,
const char *from_uri, const char *event,
uint32_t expires, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, sip_msg_h *noth, void *arg,
const char *fmt, ...);
int sipevent_refer(struct sipsub **subp, struct sipevent_sock *sock,
const char *uri, const char *from_name,
const char *from_uri, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, sip_msg_h *noth, void *arg,
const char *fmt, ...);
struct sipevent_event {

View file

@ -84,16 +84,19 @@ static void notify_handler(struct sipevent_sock *sock,
const struct sip_hdr *hdr;
struct sipevent_event se;
struct sipsub *sub;
bool indialog;
sub = sipsub_find(sock, msg, true);
if (!sub) {
sub = sipsub_find(sock, msg, false);
if (!sub || sub->subscribed) {
if (!sub) {
(void)sip_reply(sip, msg,
481, "Subsctiption Does Not Exist");
return;
}
indialog = false;
}
else {
if (!sip_dialog_rseq_valid(sub->dlg, msg)) {
@ -102,6 +105,8 @@ static void notify_handler(struct sipevent_sock *sock,
}
(void)sip_dialog_update(sub->dlg, msg);
indialog = true;
}
hdr = sip_msg_hdr(msg, SIP_HDR_EVENT);
@ -114,10 +119,9 @@ static void notify_handler(struct sipevent_sock *sock,
hdr = sip_msg_hdr(msg, SIP_HDR_SUBSCRIPTION_STATE);
if (sub->subscribed && hdr &&
!sipevent_substate_decode(&ss, &hdr->val)) {
if (indialog && hdr && !sipevent_substate_decode(&ss, &hdr->val)) {
re_printf("substate: %s (%u secs) [%r]\n",
re_printf("dialog substate: %s (%u secs) [%r]\n",
sipevent_substate_name(ss.state),
ss.expires, &ss.params);
@ -142,7 +146,10 @@ static void notify_handler(struct sipevent_sock *sock,
sub->dlg = mem_deref(sub->dlg);
hash_unlink(&sub->he);
sipevent_resubscribe(sub, 0);
if (sub->retry)
sipevent_resubscribe(sub, 0);
else
tmr_cancel(&sub->tmr);
break;
}
}

View file

@ -46,6 +46,8 @@ struct sipsub {
uint32_t routec;
bool subscribed;
bool terminated;
bool refer;
bool retry;
};

View file

@ -173,6 +173,7 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
(void)sip_dialog_update(sub->dlg, msg);
}
sub->refer = false;
sub->failc = 0;
if (pl_isset(&msg->expires))
@ -238,8 +239,10 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
mem_deref(sub);
}
else {
re_printf("will re-subscribe in %u ms...\n", wait);
tmr_start(&sub->tmr, wait, tmr_handler, sub);
if (sub->retry || sub->subscribed) {
re_printf("will re-subscribe in %u ms...\n", wait);
tmr_start(&sub->tmr, wait, tmr_handler, sub);
}
sub->resph(err, msg, sub->arg);
}
}
@ -264,50 +267,40 @@ static int request(struct sipsub *sub, bool reset_ls)
if (reset_ls)
sip_loopstate_reset(&sub->ls);
return sip_drequestf(&sub->req, sub->sip, true, "SUBSCRIBE", sub->dlg,
0, sub->auth, send_handler, response_handler, sub,
"Event: %s\r\n"
"Expires: %u\r\n"
"%s"
"Content-Length: 0\r\n"
"\r\n",
sub->event,
sub->expires,
sub->hdrs);
if (sub->refer) {
return sip_drequestf(&sub->req, sub->sip, true, "REFER",
sub->dlg, 0, sub->auth,
send_handler, response_handler, sub,
"%s"
"Content-Length: 0\r\n"
"\r\n",
sub->hdrs);
}
else {
return sip_drequestf(&sub->req, sub->sip, true, "SUBSCRIBE",
sub->dlg, 0, sub->auth,
send_handler, response_handler, sub,
"Event: %s\r\n"
"Expires: %u\r\n"
"%s"
"Content-Length: 0\r\n"
"\r\n",
sub->event,
sub->expires,
sub->hdrs);
}
}
/**
* Allocate a SIP subscriber client
*
* @param subp Pointer to allocated SIP subscriber client
* @param sock SIP Event socket
* @param uri SIP Request URI
* @param from_name SIP From-header Name (optional)
* @param from_uri SIP From-header URI
* @param event SIP Event to subscribe to
* @param expires Subscription expires value
* @param cuser Contact username
* @param routev Optional route vector
* @param routec Number of routes
* @param authh Authentication handler
* @param aarg Authentication handler argument
* @param aref True to ref argument
* @param resph SUBSCRIBE response handler
* @param noth Notify handler
* @param arg Response handler argument
* @param fmt Formatted strings with extra SIP Headers
*
* @return 0 if success, otherwise errorcode
*/
int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
const char *uri, const char *from_name,
const char *from_uri, const char *event,
uint32_t expires, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, sip_msg_h *noth, void *arg,
const char *fmt, ...)
static int sipsub_alloc(struct sipsub **subp, struct sipevent_sock *sock,
bool refer, bool retry, const char *uri,
const char *from_name, const char *from_uri,
const char *event, uint32_t expires, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, sip_msg_h *noth, void *arg,
const char *fmt, va_list ap)
{
struct sipsub *sub;
int err;
@ -377,16 +370,13 @@ int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
/* Custom SIP headers */
if (fmt) {
va_list ap;
va_start(ap, fmt);
err = re_vsdprintf(&sub->hdrs, fmt, ap);
va_end(ap);
if (err)
goto out;
}
sub->refer = refer;
sub->retry = retry;
sub->sock = mem_ref(sock);
sub->sip = mem_ref(sock->sip);
sub->expires = expires;
@ -406,3 +396,91 @@ int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
return err;
}
/**
* Allocate a SIP subscriber client
*
* @param subp Pointer to allocated SIP subscriber client
* @param sock SIP Event socket
* @param retry Re-subscribe if subscription terminates
* @param uri SIP Request URI
* @param from_name SIP From-header Name (optional)
* @param from_uri SIP From-header URI
* @param event SIP Event to subscribe to
* @param expires Subscription expires value
* @param cuser Contact username
* @param routev Optional route vector
* @param routec Number of routes
* @param authh Authentication handler
* @param aarg Authentication handler argument
* @param aref True to ref argument
* @param resph SUBSCRIBE response handler
* @param noth Notify handler
* @param arg Response handler argument
* @param fmt Formatted strings with extra SIP Headers
*
* @return 0 if success, otherwise errorcode
*/
int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
bool retry, const char *uri, const char *from_name,
const char *from_uri, const char *event,
uint32_t expires, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, sip_msg_h *noth, void *arg,
const char *fmt, ...)
{
va_list ap;
int err;
va_start(ap, fmt);
err = sipsub_alloc(subp, sock, false, retry, uri, from_name, from_uri,
event, expires, cuser, routev, routec, authh, aarg,
aref, resph, noth, arg, fmt, ap);
va_end(ap);
return err;
}
/**
* Allocate a SIP refer client
*
* @param subp Pointer to allocated SIP subscriber client
* @param sock SIP Event socket
* @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 routev Optional route vector
* @param routec Number of routes
* @param authh Authentication handler
* @param aarg Authentication handler argument
* @param aref True to ref argument
* @param resph SUBSCRIBE response handler
* @param noth Notify handler
* @param arg Response handler argument
* @param fmt Formatted strings with extra SIP Headers
*
* @return 0 if success, otherwise errorcode
*/
int sipevent_refer(struct sipsub **subp, struct sipevent_sock *sock,
const char *uri, const char *from_name,
const char *from_uri, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, sip_msg_h *noth, void *arg,
const char *fmt, ...)
{
va_list ap;
int err;
va_start(ap, fmt);
err = sipsub_alloc(subp, sock, true, false, uri, from_name, from_uri,
"refer", DEFAULT_EXPIRES, cuser, routev, routec,
authh, aarg, aref, resph, noth, arg, fmt, ap);
va_end(ap);
return err;
}

View file

@ -266,6 +266,10 @@ static bool request_handler(const struct sip_msg *msg, void *arg)
return true;
}
else if (!pl_strcmp(&msg->met, "REFER")) {
if (!pl_isset(&msg->to.tag))
return false;
refer_handler(sock, msg);
return true;
}