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;
}
Example #2
0
static
int nua_refer_server_report(nua_server_request_t *sr, tagi_t const *tags)
{
  nua_handle_t *nh = sr->sr_owner;
  struct notifier_usage *nu = nua_dialog_usage_private(sr->sr_usage);
  sip_t const *sip = sr->sr_request.sip;
  sip_referred_by_t *by = sip->sip_referred_by, default_by[1];
  sip_event_t const *o = sr->sr_usage->du_event;
  enum nua_substate substate = nua_substate_terminated;
  int initial = sr->sr_initial, retval;

  if (nu) {
    if (!sr->sr_terminating)
      substate = nu->nu_substate;
  }

  if (by == NULL) {
     by = sip_referred_by_init(default_by);

    by->b_display = sip->sip_from->a_display;
    *by->b_url = *sip->sip_from->a_url;
  }

  retval = nua_base_server_treport(sr,
				   NUTAG_SUBSTATE(substate),
				   NUTAG_REFER_EVENT(o),
				   TAG_IF(by, SIPTAG_REFERRED_BY(by)),
				   TAG_END());

  if (retval >= 2 || nu == NULL)
    return retval;

  if (initial)
    nua_stack_post_signal(nh,
			  nua_r_notify,
			  SIPTAG_EVENT(o),
			  SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
			  SIPTAG_PAYLOAD_STR("SIP/2.0 100 Trying\r\n"),
			  TAG_END());

  return retval;
}