Ejemplo n.º 1
0
/** Resend the request message.
 *
 * A resent request has completed once successfully - restarted has not.
 *
 * @retval 0 if request is pending
 * @retval >=1 if error event has been sent
 */
int nua_client_resend_request(nua_client_request_t *cr,
			      int terminating)
{
  if (cr) {
    cr->cr_retry_count = 0;
    cr->cr_challenged = 0;

    if (nua_client_is_queued(cr)) {
      if (terminating)
	cr->cr_graceful = 1;
      return 0;
    }

    if (terminating)
      nua_client_set_terminating(cr, terminating);

    if (nua_client_request_queue(cr))
      return 0;

    if (nua_dialog_is_reporting(cr->cr_owner->nh_ds))
      return 0;

    return nua_client_request_try(cr);
  }
  return 0;
}
Ejemplo n.º 2
0
static int nua_subscribe_client_request(nua_client_request_t *cr,
					msg_t *msg, sip_t *sip,
					tagi_t const *tags)
{
  nua_dialog_usage_t *du = cr->cr_usage;
  sip_time_t expires = 0;

  if (cr->cr_event == nua_r_destroy || !du || du->du_shutdown)
    nua_client_set_terminating(cr, 1);

  if (du) {
    struct event_usage *eu = nua_dialog_usage_private(du);
    sip_event_t *o = sip->sip_event;

    if (nua_client_bind(cr, du) < 0)
      return -1;

    if (eu->eu_no_id && o && o->o_id) {
      /* Notifier does not handle id properly, remove it */
      msg_header_remove_param(o->o_common, "id");
    }

#if 0
    if (cr->cr_terminating) {
      /* Already terminated subscription? */
      if (eu->eu_substate == nua_substate_terminated ||
	  eu->eu_substate == nua_substate_embryonic) {
	return nua_client_return(cr, SIP_200_OK, msg);
      }
    }
#endif

    nua_dialog_usage_reset_refresh(du); /* during SUBSCRIBE transaction */

    if (cr->cr_terminating || cr->cr_event != nua_r_subscribe)
      expires = eu->eu_delta = 0;
    else if (sip->sip_expires)
      /* Use value specified by application or negotiated with Min-Expires */
      expires = eu->eu_delta = sip->sip_expires->ex_delta;
    else
    /* We just use common default value, but the default is actually
       package-specific according to the RFC 3265 section 4.4.4:
       [Event] packages MUST also define a
       default "Expires" value to be used if none is specified. */
      expires = eu->eu_delta = 3600;

    eu->eu_final_wait = 0;

    if (eu->eu_substate == nua_substate_terminated)
      eu->eu_substate = nua_substate_embryonic;
  }

  if (!sip->sip_expires || sip->sip_expires->ex_delta != expires) {
    sip_expires_t ex[1];
    sip_expires_init(ex)->ex_delta = expires;
    sip_add_dup(msg, sip, (sip_header_t *)ex);
  }

  return nua_base_client_request(cr, msg, sip, tags);
}
Ejemplo n.º 3
0
static
int nua_publish_client_request(nua_client_request_t *cr,
			       msg_t *msg, sip_t *sip,
			       tagi_t const *tags)
{
  nua_dialog_usage_t *du = cr->cr_usage;
  int un, done;
  sip_etag_t const *etag = NULL;

  un = cr->cr_terminating ||
    cr->cr_event != nua_r_publish ||
    (du && du->du_shutdown) ||
    (sip->sip_expires && sip->sip_expires->ex_delta == 0);
  nua_client_set_terminating(cr, un);
  done = un;

  if (du) {
    struct publish_usage *pu = nua_dialog_usage_private(du);

    if (nua_client_bind(cr, du) < 0)
      return -1;
    if (pu->pu_published)
      done = 1;
    etag = pu->pu_etag;
  }

  return nua_base_client_trequest(cr, msg, sip,
				  SIPTAG_IF_MATCH(etag),
				  TAG_IF(done, SIPTAG_PAYLOAD(NONE)),
				  TAG_IF(done, SIPTAG_CONTENT_TYPE(NONE)),
				  TAG_IF(un, SIPTAG_EXPIRES_STR("0")),
				  TAG_NEXT(tags));
}
Ejemplo n.º 4
0
/** Restart the request message.
 *
 * A restarted request has not been completed successfully.
 *
 * @retval 0 if request is pending
 * @retval >=1 if error event has been sent
 */
int nua_client_restart_request(nua_client_request_t *cr,
			      int terminating,
			      tagi_t const *tags)
{
  if (cr) {
    assert(nua_client_is_queued(cr));

    if (tags && cr->cr_msg)
      if (sip_add_tagis(cr->cr_msg, NULL, &tags) < 0)
	/* XXX */;

    nua_client_set_terminating(cr, terminating);

    return nua_client_request_try(cr);
  }

  return 0;
}
Ejemplo n.º 5
0
static
int nua_notify_client_request(nua_client_request_t *cr,
			      msg_t *msg, sip_t *sip,
			      tagi_t const *tags)
{
  nua_dialog_usage_t *du = cr->cr_usage;
  struct notifier_usage *nu = nua_dialog_usage_private(du);
  su_home_t *home = msg_home(msg);
  sip_time_t now = sip_now();
  sip_subscription_state_t *ss = sip->sip_subscription_state;
  char const *expires;

  if (du == NULL)		/* Subscription has been terminated */
    return nua_client_return(cr, SIP_481_NO_TRANSACTION, msg);

  assert(du && nu);

  if (du && nua_client_bind(cr, du) < 0)
    return -1;

  if (nu->nu_requested)
    nu->nu_expires = nu->nu_requested;
  nu->nu_requested = 0;

  if (nu->nu_expires <= now || du->du_shutdown) {
    nu->nu_substate = nua_substate_terminated;
    expires = "expires=0";
  }
  else {
    expires = su_sprintf(home, "expires=%lu", nu->nu_expires - now);
  }

  if (ss == NULL || nua_substate_make(ss->ss_substate) != nu->nu_substate) {
    if (nu->nu_substate == nua_substate_terminated)
      expires = nu->nu_expires > now ? "reason=noresource" : "reason=timeout";

    ss = sip_subscription_state_format(home, "%s;%s",
				       nua_substate_name(nu->nu_substate),
				       expires);

    msg_header_insert(msg, (void *)sip, (void *)ss);
  }
  else if (nu->nu_substate != nua_substate_terminated) {
    msg_header_replace_param(home, ss->ss_common, expires);
  }

#if SU_HAVE_EXPERIMENTAL
  if (nu->nu_tag && !sip->sip_etag)
    msg_header_add_make(msg, (void *)sip, sip_etag_class, nu->nu_tag);

  if (nu->nu_no_body) {
    nu->nu_no_body = 0;
    msg_header_remove(msg, (void *)sip, (void *)sip->sip_payload);
    msg_header_remove(msg, (void *)sip, (void *)sip->sip_content_length);
  }
#endif

  if (nu->nu_substate == nua_substate_terminated)
    nua_client_set_terminating(cr, 1);

  if (cr->cr_terminating) {
    nua_server_request_t *sr;
    for (sr = du->du_dialog->ds_sr; sr; sr = sr->sr_next) {
      if (sr->sr_usage == du) {
	/* If subscribe has not been responded, don't terminate usage by NOTIFY */
	sr->sr_terminating = 1;
	nua_client_set_terminating(cr, 0);
	break;
      }
    }
  }

  if (du->du_event && !sip->sip_event)
    sip_add_dup(cr->cr_msg, sip, (sip_header_t *)du->du_event);

  return nua_base_client_request(cr, msg, sip, tags);
}