static int nua_refer_server_preprocess(nua_server_request_t *sr) { nua_handle_t *nh = sr->sr_owner; sip_t const *sip = sr->sr_request.sip; struct notifier_usage *nu; sip_event_t *o; if (nh->nh_ds->ds_got_referrals || NH_PGET(nh, refer_with_id)) o = sip_event_format(nh->nh_home, "refer;id=%u", sip->sip_cseq->cs_seq); else o = sip_event_make(nh->nh_home, "refer"); if (o) { sr->sr_usage = nua_dialog_usage_add(nh, nh->nh_ds, nua_notify_usage, o); msg_header_free(nh->nh_home, (msg_header_t *)o); } if (!sr->sr_usage) return SR_STATUS1(sr, SIP_500_INTERNAL_SERVER_ERROR); nu = nua_dialog_usage_private(sr->sr_usage); nu->nu_requested = sip_now() + NH_PGET(nh, refer_expires); return 0; }
static int nua_refer_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip, tagi_t const *tags) { nua_handle_t *nh = cr->cr_owner; nua_dialog_usage_t *du, *du0 = cr->cr_usage; struct event_usage *eu; sip_event_t *event; int error; cr->cr_usage = NULL; event = sip_event_format(nh->nh_home, "refer;id=%u", sip->sip_cseq->cs_seq); if (!event) return -1; if (du0 == NULL || du0->du_event == NULL || du0->du_event->o_id == NULL || strcmp(du0->du_event->o_id, event->o_id)) { du = nua_dialog_usage_add(nh, nh->nh_ds, nua_subscribe_usage, event); if (!du) return -1; } else { du = du0, du0 = NULL; } if (du0) nua_dialog_usage_remove(nh, nh->nh_ds, du0, NULL, NULL); eu = nua_dialog_usage_private(cr->cr_usage = du); eu ->eu_refer = 1; error = nua_base_client_request(cr, msg, sip, tags); if (!error) { /* Give application an Event header for matching NOTIFYs with REFER */ nua_stack_tevent(nh->nh_nua, nh, NULL, (enum nua_event_e)cr->cr_event, SIP_100_TRYING, NUTAG_REFER_EVENT(event), SIPTAG_EVENT(event), TAG_END()); su_free(nh->nh_home, event); } return error; }