event id parameter handling
This commit is contained in:
parent
2f8a580fc3
commit
45b0b0132f
5 changed files with 78 additions and 23 deletions
|
@ -27,7 +27,7 @@ typedef void (sipevent_close_h)(int err, const struct sip_msg *msg, void *arg);
|
|||
|
||||
int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
|
||||
const char *uri, const char *from_name,
|
||||
const char *from_uri, const char *event,
|
||||
const char *from_uri, const char *event, const char *id,
|
||||
uint32_t expires, const char *cuser,
|
||||
const char *routev[], uint32_t routec,
|
||||
sip_auth_h *authh, void *aarg, bool aref,
|
||||
|
@ -54,6 +54,7 @@ int sipevent_fork(struct sipsub **subp, struct sipsub *osub,
|
|||
struct sipevent_event {
|
||||
struct pl event;
|
||||
struct pl params;
|
||||
struct pl id;
|
||||
};
|
||||
|
||||
enum sipevent_subst {
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
#include "sipevent.h"
|
||||
|
||||
|
||||
struct subcmp {
|
||||
const struct sipevent_event *evt;
|
||||
const struct sip_msg *msg;
|
||||
};
|
||||
|
||||
|
||||
static void destructor(void *arg)
|
||||
{
|
||||
struct sipevent_sock *sock = arg;
|
||||
|
@ -30,6 +36,25 @@ static void destructor(void *arg)
|
|||
}
|
||||
|
||||
|
||||
static bool event_cmp(const struct sipevent_event *evt,
|
||||
const char *event, const char *id)
|
||||
{
|
||||
if (pl_strcmp(&evt->event, event))
|
||||
return false;
|
||||
|
||||
if (!pl_isset(&evt->id) && !id)
|
||||
return true;
|
||||
|
||||
if (!pl_isset(&evt->id) || !id)
|
||||
return false;
|
||||
|
||||
if (pl_strcmp(&evt->id, id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool not_cmp_handler(struct le *le, void *arg)
|
||||
{
|
||||
const struct sip_msg *msg = arg;
|
||||
|
@ -41,20 +66,22 @@ static bool not_cmp_handler(struct le *le, void *arg)
|
|||
|
||||
static bool sub_cmp_handler(struct le *le, void *arg)
|
||||
{
|
||||
const struct sip_msg *msg = arg;
|
||||
const struct subcmp *cmp = arg;
|
||||
struct sipsub *sub = le->data;
|
||||
|
||||
return sip_dialog_cmp(sub->dlg, msg);
|
||||
return sip_dialog_cmp(sub->dlg, cmp->msg) &&
|
||||
(!cmp->evt || event_cmp(cmp->evt, sub->event, sub->id));
|
||||
}
|
||||
|
||||
|
||||
static bool sub_cmp_half_handler(struct le *le, void *arg)
|
||||
{
|
||||
const struct sip_msg *msg = arg;
|
||||
const struct subcmp *cmp = arg;
|
||||
struct sipsub *sub = le->data;
|
||||
|
||||
return sip_dialog_cmp_half(sub->dlg, msg) &&
|
||||
!sip_dialog_established(sub->dlg);
|
||||
return sip_dialog_cmp_half(sub->dlg, cmp->msg) &&
|
||||
!sip_dialog_established(sub->dlg) &&
|
||||
(!cmp->evt || event_cmp(cmp->evt, sub->event, sub->id));
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,12 +95,18 @@ static struct sipnot *sipnot_find(struct sipevent_sock *sock,
|
|||
|
||||
|
||||
struct sipsub *sipsub_find(struct sipevent_sock *sock,
|
||||
const struct sip_msg *msg, bool full)
|
||||
const struct sip_msg *msg,
|
||||
const struct sipevent_event *evt, bool full)
|
||||
{
|
||||
struct subcmp cmp;
|
||||
|
||||
cmp.msg = msg;
|
||||
cmp.evt = evt;
|
||||
|
||||
return list_ledata(hash_lookup(sock->ht_sub,
|
||||
hash_joaat_pl(&msg->callid), full ?
|
||||
sub_cmp_handler : sub_cmp_half_handler,
|
||||
(void *)msg));
|
||||
&cmp));
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,9 +133,9 @@ static void notify_handler(struct sipevent_sock *sock,
|
|||
return;
|
||||
}
|
||||
|
||||
sub = sipsub_find(sock, msg, true);
|
||||
sub = sipsub_find(sock, msg, &event, true);
|
||||
if (!sub) {
|
||||
sub = sipsub_find(sock, msg, false);
|
||||
sub = sipsub_find(sock, msg, &event, false);
|
||||
if (!sub) {
|
||||
(void)sip_reply(sip, msg,
|
||||
481, "Subscription Does Not Exist");
|
||||
|
@ -142,11 +175,6 @@ static void notify_handler(struct sipevent_sock *sock,
|
|||
(void)sip_dialog_update(sub->dlg, msg);
|
||||
}
|
||||
|
||||
if (pl_strcasecmp(&event.event, sub->event)) {
|
||||
(void)sip_reply(sip, msg, 489, "Bad Event");
|
||||
return;
|
||||
}
|
||||
|
||||
re_printf("notify: %s (%r)\n", sipevent_substate_name(state.state),
|
||||
&state.params);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
int sipevent_event_decode(struct sipevent_event *se, const struct pl *pl)
|
||||
{
|
||||
struct pl param;
|
||||
int err;
|
||||
|
||||
if (!se || !pl)
|
||||
|
@ -25,6 +26,11 @@ int sipevent_event_decode(struct sipevent_event *se, const struct pl *pl)
|
|||
if (err)
|
||||
return EBADMSG;
|
||||
|
||||
if (!sip_param_decode(&se->params, "id", ¶m))
|
||||
se->id = param;
|
||||
else
|
||||
se->id = pl_null;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ struct sipsub {
|
|||
struct sip_auth *auth;
|
||||
struct sip *sip;
|
||||
char *event;
|
||||
char *id;
|
||||
char *refer_to;
|
||||
char *cuser;
|
||||
char *hdrs;
|
||||
|
@ -53,6 +54,7 @@ struct sipsub {
|
|||
};
|
||||
|
||||
struct sipsub *sipsub_find(struct sipevent_sock *sock,
|
||||
const struct sip_msg *msg, bool full);
|
||||
const struct sip_msg *msg,
|
||||
const struct sipevent_event *evt, bool full);
|
||||
void sipsub_reschedule(struct sipsub *sub, uint64_t wait);
|
||||
void sipsub_terminate(struct sipsub *sub, int err, const struct sip_msg *msg);
|
||||
|
|
|
@ -85,6 +85,7 @@ static void destructor(void *arg)
|
|||
mem_deref(sub->dlg);
|
||||
mem_deref(sub->auth);
|
||||
mem_deref(sub->event);
|
||||
mem_deref(sub->id);
|
||||
mem_deref(sub->refer_to);
|
||||
mem_deref(sub->cuser);
|
||||
mem_deref(sub->hdrs);
|
||||
|
@ -160,7 +161,7 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
|
|||
|
||||
struct sipsub *fsub;
|
||||
|
||||
fsub = sipsub_find(sub->sock, msg, true);
|
||||
fsub = sipsub_find(sub->sock, msg, NULL, true);
|
||||
if (!fsub) {
|
||||
|
||||
err = sub->forkh(&fsub, sub, msg, sub->arg);
|
||||
|
@ -286,6 +287,15 @@ static int send_handler(enum sip_transp tp, const struct sa *src,
|
|||
}
|
||||
|
||||
|
||||
static int print_event(struct re_printf *pf, const struct sipsub *sub)
|
||||
{
|
||||
if (sub->id)
|
||||
return re_hprintf(pf, "%s;id=%s", sub->event, sub->id);
|
||||
else
|
||||
return re_hprintf(pf, "%s", sub->event);
|
||||
}
|
||||
|
||||
|
||||
static int request(struct sipsub *sub, bool reset_ls)
|
||||
{
|
||||
if (sub->terminated)
|
||||
|
@ -310,12 +320,12 @@ static int request(struct sipsub *sub, bool reset_ls)
|
|||
return sip_drequestf(&sub->req, sub->sip, true, "SUBSCRIBE",
|
||||
sub->dlg, 0, sub->auth,
|
||||
send_handler, response_handler, sub,
|
||||
"Event: %s\r\n"
|
||||
"Event: %H\r\n"
|
||||
"Expires: %u\r\n"
|
||||
"%s"
|
||||
"Content-Length: 0\r\n"
|
||||
"\r\n",
|
||||
sub->event,
|
||||
print_event, sub,
|
||||
sub->expires,
|
||||
sub->hdrs);
|
||||
}
|
||||
|
@ -325,7 +335,7 @@ static int request(struct sipsub *sub, bool reset_ls)
|
|||
static int sipsub_alloc(struct sipsub **subp, struct sipevent_sock *sock,
|
||||
bool refer, const char *uri,
|
||||
const char *from_name, const char *from_uri,
|
||||
const char *event, uint32_t expires,
|
||||
const char *event, const char *id, uint32_t expires,
|
||||
const char *refer_to, const char *cuser,
|
||||
const char *routev[], uint32_t routec,
|
||||
sip_auth_h *authh, void *aarg, bool aref,
|
||||
|
@ -363,6 +373,12 @@ static int sipsub_alloc(struct sipsub **subp, struct sipevent_sock *sock,
|
|||
if (err)
|
||||
goto out;
|
||||
|
||||
if (id) {
|
||||
err = str_dup(&sub->id, id);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (refer_to) {
|
||||
err = str_dup(&sub->refer_to, refer_to);
|
||||
if (err)
|
||||
|
@ -412,6 +428,7 @@ static int sipsub_alloc(struct sipsub **subp, struct sipevent_sock *sock,
|
|||
* @param from_name SIP From-header Name (optional)
|
||||
* @param from_uri SIP From-header URI
|
||||
* @param event SIP Event to subscribe to
|
||||
* @param id SIP Event ID
|
||||
* @param expires Subscription expires value
|
||||
* @param cuser Contact username
|
||||
* @param routev Optional route vector
|
||||
|
@ -428,7 +445,7 @@ static int sipsub_alloc(struct sipsub **subp, struct sipevent_sock *sock,
|
|||
*/
|
||||
int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
|
||||
const char *uri, const char *from_name,
|
||||
const char *from_uri, const char *event,
|
||||
const char *from_uri, const char *event, const char *id,
|
||||
uint32_t expires, const char *cuser,
|
||||
const char *routev[], uint32_t routec,
|
||||
sip_auth_h *authh, void *aarg, bool aref,
|
||||
|
@ -441,7 +458,7 @@ int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
|
|||
|
||||
va_start(ap, fmt);
|
||||
err = sipsub_alloc(subp, sock, false, uri, from_name, from_uri,
|
||||
event, expires, NULL, cuser,
|
||||
event, id, expires, NULL, cuser,
|
||||
routev, routec, authh, aarg, aref, forkh, notifyh,
|
||||
closeh, arg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
@ -485,7 +502,7 @@ int sipevent_refer(struct sipsub **subp, struct sipevent_sock *sock,
|
|||
|
||||
va_start(ap, fmt);
|
||||
err = sipsub_alloc(subp, sock, true, uri, from_name, from_uri,
|
||||
"refer", DEFAULT_EXPIRES, refer_to, cuser,
|
||||
"refer", NULL, DEFAULT_EXPIRES, refer_to, cuser,
|
||||
routev, routec, authh, aarg, aref, forkh, notifyh,
|
||||
closeh, arg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
@ -523,6 +540,7 @@ int sipevent_fork(struct sipsub **subp, struct sipsub *osub,
|
|||
goto out;
|
||||
|
||||
sub->event = mem_ref(osub->event);
|
||||
sub->id = mem_ref(osub->id);
|
||||
sub->cuser = mem_ref(osub->cuser);
|
||||
sub->hdrs = mem_ref(osub->hdrs);
|
||||
sub->refer = osub->refer;
|
||||
|
|
Loading…
Add table
Reference in a new issue