From 45b0b0132fb1659dd65d47e99f820f49782c4c9f Mon Sep 17 00:00:00 2001 From: Richard Aas Date: Thu, 8 Dec 2011 11:41:49 +0000 Subject: [PATCH] event id parameter handling --- include/re_sipevent.h | 3 ++- src/sipevent/listen.c | 56 ++++++++++++++++++++++++++++++---------- src/sipevent/msg.c | 6 +++++ src/sipevent/sipevent.h | 4 ++- src/sipevent/subscribe.c | 32 ++++++++++++++++++----- 5 files changed, 78 insertions(+), 23 deletions(-) diff --git a/include/re_sipevent.h b/include/re_sipevent.h index 0b17882..494bc8c 100644 --- a/include/re_sipevent.h +++ b/include/re_sipevent.h @@ -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 { diff --git a/src/sipevent/listen.c b/src/sipevent/listen.c index b2fa906..02254a5 100644 --- a/src/sipevent/listen.c +++ b/src/sipevent/listen.c @@ -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); diff --git a/src/sipevent/msg.c b/src/sipevent/msg.c index 38f4124..6a29d72 100644 --- a/src/sipevent/msg.c +++ b/src/sipevent/msg.c @@ -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; } diff --git a/src/sipevent/sipevent.h b/src/sipevent/sipevent.h index 9ac1350..1f581ca 100644 --- a/src/sipevent/sipevent.h +++ b/src/sipevent/sipevent.h @@ -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); diff --git a/src/sipevent/subscribe.c b/src/sipevent/subscribe.c index 81e74c8..7ee472c 100644 --- a/src/sipevent/subscribe.c +++ b/src/sipevent/subscribe.c @@ -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;