static struct sipsess *sipsess_find(struct sipsess_sock *sock, const struct sip_msg *msg) { return list_ledata(hash_lookup(sock->ht_sess, hash_joaat_pl(&msg->callid), cmp_handler, (void *)msg)); }
/** * Add a contact * * @param contacts Contacts container * @param contactp Pointer to allocated contact (optional) * @param addr Contact in SIP address format * * @return 0 if success, otherwise errorcode */ int contact_add(struct contacts *contacts, struct contact **contactp, const struct pl *addr) { struct contact *c; struct pl pl; int err; if (!contacts) return EINVAL; c = mem_zalloc(sizeof(*c), destructor); if (!c) return ENOMEM; err = pl_strdup(&c->buf, addr); if (err) goto out; pl_set_str(&pl, c->buf); err = sip_addr_decode(&c->addr, &pl); if (err) { warning("contact: decode error '%r'\n", addr); goto out; } if (0 == msg_param_decode(&c->addr.params, "access", &pl)) { if (0 == pl_strcasecmp(&pl, "block")) { c->access = ACCESS_BLOCK; } else if (0 == pl_strcasecmp(&pl, "allow")) { c->access = ACCESS_ALLOW; } else { warning("contact: unknown 'access=%r' for '%r'\n", &pl, addr); err = EINVAL; goto out; } } else c->access = ACCESS_UNKNOWN; c->status = PRESENCE_UNKNOWN; list_append(&contacts->cl, &c->le, c); hash_append(contacts->cht, hash_joaat_pl(&c->addr.auri), &c->he, c); out: if (err) mem_deref(c); else if (contactp) *contactp = c; return err; }
static bool response_handler(const struct sip_msg *msg, void *arg) { struct sip_ctrans *ct; struct sip *sip = arg; ct = list_ledata(hash_lookup(sip->ht_ctrans, hash_joaat_pl(&msg->via.branch), cmp_handler, (void *)msg)); if (!ct) return false; if (ct->invite) { invite_response(ct, msg); return true; } switch (ct->state) { case TRYING: case PROCEEDING: if (msg->scode < 200) { ct->state = PROCEEDING; ct->resph(0, msg, ct->arg); } else { ct->state = COMPLETED; ct->resph(0, msg, ct->arg); if (sip_transp_reliable(ct->tp)) { mem_deref(ct); break; } tmr_start(&ct->tmr, SIP_T4, tmr_handler, ct); tmr_cancel(&ct->tmre); } break; default: break; } return true; }