static void message_handler(const struct pl *peer, const struct pl *ctype, struct mbuf *body, void *arg) { (void)ctype; (void)arg; char message[256] = {0}; char s_peer[50] = {0}; struct contacts *contacts = baresip_contacts(); (void)re_snprintf(message, sizeof(message), "%b", mbuf_buf(body), mbuf_get_left(body)); (void)re_snprintf(s_peer, sizeof(s_peer), "%r", peer); warning("message from %s: %s\n", s_peer, message); struct contact *c = contact_find(contacts, s_peer); if (c) { const struct sip_addr *addr = contact_addr(c); (void)re_snprintf(s_peer, sizeof(s_peer), "%r", &addr->dname); (void)webapp_chat_add(s_peer, message, false); ws_send_json(WS_CHAT, webapp_messages_get()); } }
static int subscribe(struct presence *pres) { const char *routev[1]; struct ua *ua; char uri[256]; int err; /* We use the first UA */ ua = uag_find_aor(NULL); if (!ua) { warning("presence: no UA found\n"); return ENOENT; } pl_strcpy(&contact_addr(pres->contact)->auri, uri, sizeof(uri)); routev[0] = ua_outbound(ua); err = sipevent_subscribe(&pres->sub, uag_sipevent_sock(), uri, NULL, ua_aor(ua), "presence", NULL, 600, ua_cuser(ua), routev, routev[0] ? 1 : 0, auth_handler, ua_prm(ua), true, NULL, notify_handler, close_handler, pres, "%H", ua_print_supported, ua); if (err) { warning("presence: sipevent_subscribe failed: %m\n", err); } return err; }
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); }
int subscriber_init(void) { struct le *le; int err = 0; for (le = list_head(contact_list()); le; le = le->next) { struct contact *c = le->data; struct sip_addr *addr = contact_addr(c); struct pl val; if (0 == msg_param_decode(&addr->params, "presence", &val) && 0 == pl_strcasecmp(&val, "p2p")) { err |= presence_alloc(le->data); } } info("Subscribing to %u contacts\n", list_count(&presencel)); return err; }
static int cmd_contact(struct re_printf *pf, void *arg) { const struct cmd_arg *carg = arg; struct contacts *contacts = baresip_contacts(); struct contact *cnt = NULL; struct pl dname, user, pl; struct le *le; int err = 0; pl_set_str(&pl, carg->prm); dname.l = user.l = pl.l; err |= re_hprintf(pf, "\n"); for (le = list_head(contact_list(contacts)); le; le = le->next) { struct contact *c = le->data; dname.p = contact_addr(c)->dname.p; user.p = contact_addr(c)->uri.user.p; /* if displayname is set, try to match the displayname * otherwise we try to match the username only */ if (dname.p) { if (0 == pl_casecmp(&dname, &pl)) { err |= re_hprintf(pf, "%s\n", contact_str(c)); cnt = c; } } else if (user.p) { if (0 == pl_casecmp(&user, &pl)) { err |= re_hprintf(pf, "%s\n", contact_str(c)); cnt = c; } } } if (!cnt) err |= re_hprintf(pf, "(no matches)\n"); if (carg->complete && cnt) { switch (carg->key) { case '|': err = ua_connect(uag_current(), NULL, NULL, contact_str(cnt), NULL, VIDMODE_ON); if (err) { warning("contact: ua_connect failed: %m\n", err); } break; case '=': chat_peer = contact_str(cnt); (void)re_hprintf(pf, "Selected chat peer: %s\n", chat_peer); re_snprintf(cmd_desc, sizeof(cmd_desc), "Send MESSAGE to %s", chat_peer); break; default: break; } } return err; }