static void close_handler(int err, const struct sip_msg *msg, const struct sipevent_substate *substate, void *arg) { struct presence *pres = arg; uint32_t wait; pres->sub = mem_deref(pres->sub); info("presence: subscriber closed <%r>: ", &contact_addr(pres->contact)->auri); if (substate) { info("%s", sipevent_reason_name(substate->reason)); wait = wait_term(substate); } else if (msg) { info("%u %r", msg->scode, &msg->reason); wait = wait_fail(++pres->failc); } else { info("%m", err); wait = wait_fail(++pres->failc); } info("; will retry in %u secs (failc=%u)\n", wait, pres->failc); tmr_start(&pres->tmr, wait * 1000, tmr_handler, pres); contact_set_presence(pres->contact, PRESENCE_UNKNOWN); }
static void notify_handler(struct sip *sip, const struct sip_msg *msg, void *arg) { enum presence_status status = PRESENCE_CLOSED; struct presence *pres = arg; const struct sip_hdr *hdr; struct pl pl; pres->failc = 0; hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_TYPE); if (!hdr || 0 != pl_strcasecmp(&hdr->val, "application/pidf+xml")) { if (hdr) (void)re_printf("presence: unsupported" " content-type: '%r'\n", &hdr->val); sip_treplyf(NULL, NULL, sip, msg, false, 415, "Unsupported Media Type", "Accept: application/pidf+xml\r\n" "Content-Length: 0\r\n" "\r\n"); return; } if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<status>[^<]*<basic>[^<]*</basic>[^<]*</status>", NULL, &pl, NULL)) { if (!pl_strcasecmp(&pl, "open")) status = PRESENCE_OPEN; } if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<rpid:away/>")) { status = PRESENCE_CLOSED; } else if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<rpid:busy/>")) { status = PRESENCE_BUSY; } else if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<rpid:on-the-phone/>")) { status = PRESENCE_BUSY; } (void)sip_treply(NULL, sip, msg, 200, "OK"); contact_set_presence(pres->contact, status); }
static void notify_handler(struct sip *sip, const struct sip_msg *msg, void *arg) { enum presence_status status = PRESENCE_CLOSED; struct presence *pres = arg; const struct sip_hdr *type_hdr, *length_hdr; struct pl pl; pres->failc = 0; type_hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_TYPE); if (!type_hdr) { length_hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_LENGTH); if (0 == pl_strcmp(&length_hdr->val, "0")) { status = PRESENCE_UNKNOWN; goto done; } } if (!type_hdr || 0 != pl_strcasecmp(&type_hdr->val, "application/pidf+xml")) { if (type_hdr) warning("presence: unsupported content-type: '%r'\n", &type_hdr->val); sip_treplyf(NULL, NULL, sip, msg, false, 415, "Unsupported Media Type", "Accept: application/pidf+xml\r\n" "Content-Length: 0\r\n" "\r\n"); return; } if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<basic>[^<]+</basic>", &pl)) { if (!pl_strcasecmp(&pl, "open")) status = PRESENCE_OPEN; } if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<rpid:away/>")) { status = PRESENCE_CLOSED; } else if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<rpid:busy/>")) { status = PRESENCE_BUSY; } else if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb), "<rpid:on-the-phone/>")) { status = PRESENCE_BUSY; } done: (void)sip_treply(NULL, sip, msg, 200, "OK"); contact_set_presence(pres->contact, status); }