added sipevent_refer()
This commit is contained in:
parent
aa42bc518f
commit
12f862d036
5 changed files with 155 additions and 55 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ struct sipsub {
|
|||
uint32_t routec;
|
||||
bool subscribed;
|
||||
bool terminated;
|
||||
bool refer;
|
||||
bool retry;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue