Exemplo n.º 1
0
/** @internal Add dialog usage */
nua_dialog_usage_t *nua_dialog_usage_add(nua_owner_t *own,
					 struct nua_dialog_state *ds,
					 nua_usage_class const *uclass,
					 sip_event_t const *event)
{
  if (ds) {
    sip_event_t *o;
    nua_dialog_usage_t *du, **prev_du;

    prev_du = nua_dialog_usage_at(ds, uclass, event);
    du = *prev_du;
    if (du) {		/* Already exists */
      SU_DEBUG_5(("nua(%p): adding already existing %s usage%s%s\n",
		  (void *)own, nua_dialog_usage_name(du),
		  event ? "  with event " : "", event ? event->o_type : ""));

      if (prev_du != &ds->ds_usage) {
	/* Move as a first usage in the list */
	*prev_du = du->du_next;
	du->du_next = ds->ds_usage;
	ds->ds_usage = du;
      }
      return du;
    }

    o = event ? sip_event_dup(own, event) : NULL;

    if (o != NULL || event == NULL)
      du = su_zalloc(own, sizeof *du + uclass->usage_size);

    if (du) {
      su_home_ref(own);

      du->du_dialog = ds;
      du->du_class = uclass;
      du->du_event = o;

      if (uclass->usage_add(own, ds, du) < 0) {
	su_home_unref(own);
	su_free(own, o);
	su_free(own, du);
	return NULL;
      }

      SU_DEBUG_5(("nua(%p): adding %s usage%s%s\n",
		  (void *)own, nua_dialog_usage_name(du),
		  o ? " with event " : "", o ? o->o_type :""));

      du->du_next = ds->ds_usage, ds->ds_usage = du;

      return du;
    }

    su_free(own, o);
  }

  return NULL;
}
Exemplo n.º 2
0
/** Set absolute refresh time */
void nua_dialog_usage_set_refresh_at(nua_dialog_usage_t *du,
				     sip_time_t target)
{
  SU_DEBUG_7(("nua(): refresh %s after %lu seconds\n",
	      nua_dialog_usage_name(du), target - sip_now()));
  du->du_refresh = target;
}
Exemplo n.º 3
0
/**@internal Set refresh in range min..max seconds in the future. */
void nua_dialog_usage_set_refresh_range(nua_dialog_usage_t *du,
					unsigned min, unsigned max)
{
  sip_time_t now = sip_now(), target;
  unsigned delta;

  if (max < min)
    max = min;

  if (min != max)
    delta = su_randint(min, max);
  else
    delta = min;

  if (now + delta >= now)
    target = now + delta;
  else
    target = SIP_TIME_MAX;

  SU_DEBUG_7(("nua(): refresh %s after %lu seconds (in [%u..%u])\n",
	      nua_dialog_usage_name(du), target - now, min, max));

  du->du_refquested = now;

  du->du_refresh = target;
}
Exemplo n.º 4
0
/**@internal Set refresh in range min..max seconds in the future. */
void nua_dialog_usage_set_refresh_range(nua_dialog_usage_t *du,
					unsigned min, unsigned max)
{
  su_duration_t max_defer = nua_dialog_usage_get_max_defer(du);
  unsigned delta;
  int make_deferrable = 0;

  if (max <= min) {
    max = min;
    delta = min * 1000;
  }
  else if (max_defer > 0 && (int)(max - min) >= max_defer / 1000) {
    delta = su_randint(min * 1000, max * 1000 - (max_defer + 999));
    make_deferrable = 1;
  }
  else
    delta = su_randint(min * 1000, max * 1000);

  SU_DEBUG_7(("nua(): refresh %s in %.3f seconds (in [%u..%u]%s)\n",
	      nua_dialog_usage_name(du), 1e-3 * delta, min, max,
	      make_deferrable? ", deferrable" : ""));

  delta += delta == 0;

  nua_dialog_usage_set_refresh_timer(du, delta, make_deferrable);
}
Exemplo n.º 5
0
/** @internal Remove dialog usage.
 *
 * Zap dialog state (leg, tag and route) if no usages remain.
*/
static void
nua_dialog_usage_remove_at(nua_owner_t *own,
			   nua_dialog_state_t *ds,
			   nua_dialog_usage_t **at,
			   nua_client_request_t *cr0,
			   nua_server_request_t *sr0)
{
  if (*at) {
    nua_dialog_usage_t *du = *at;
    sip_event_t const *o = NULL;
    nua_client_request_t *cr, *cr_next;
    nua_server_request_t *sr, *sr_next;

    *at = du->du_next;

    o = du->du_event;

    SU_DEBUG_5(("nua(%p): removing %s usage%s%s\n",
		(void *)own, nua_dialog_usage_name(du),
		o ? " with event " : "", o ? o->o_type :""));
    du->du_class->usage_remove(own, ds, du, cr0, sr0);

    /* Clean reference to saved client request */
    if (du->du_cr)
      nua_client_bind(du->du_cr, NULL);

    /* Clean references from queued client requests */
    for (cr = ds->ds_cr; cr; cr = cr_next) {
      cr_next = cr->cr_next;
      if (cr->cr_usage == du)
	cr->cr_usage = NULL;
    }

    /* Clean references from queued server requests */
    for (sr = ds->ds_sr; sr; sr = sr_next) {
      sr_next = sr->sr_next;
      if (sr->sr_usage == du) {
	sr->sr_usage = NULL;
	if (sr != sr0)
	  nua_server_request_destroy(sr);
      }
    }

    su_home_unref(own);
    su_free(own, du);
  }

  /* Zap dialog if there are no more usages */
  if (ds->ds_terminating)
    ;
  else if (ds->ds_usage == NULL) {
    nua_dialog_remove(own, ds, NULL);
    ds->ds_has_events = 0;
    return;
  }
  else {
    nua_dialog_log_usage(own, ds);
  }
}
Exemplo n.º 6
0
/**@internal Set refresh before delta seconds elapse */
void nua_dialog_usage_set_refresh_in(nua_dialog_usage_t *du,
                                     unsigned delta)
{
  su_duration_t max_defer = nua_dialog_usage_get_max_defer(du);
  su_duration_t timeout = delta * 1000L;
  int make_deferrable = 0;

  if (max_defer > 0 && timeout >= max_defer) {
    timeout -= max_defer;
    make_deferrable = 1;
  }

  SU_DEBUG_7(("nua(): refresh %s in %u seconds%s\n",
              nua_dialog_usage_name(du), delta,
              make_deferrable? " (deferrable)" : ""));

  nua_dialog_usage_set_refresh_timer(du, timeout, make_deferrable);
}