Example #1
0
void nh_destroy(nua_t *nua, nua_handle_t *nh)
{
  assert(nh); assert(nh != nua->nua_dhandle);

  if (nh->nh_notifier)
    nea_server_destroy(nh->nh_notifier), nh->nh_notifier = NULL;

  while (nh->nh_ds->ds_cr)
    nua_client_request_complete(nh->nh_ds->ds_cr);

  while (nh->nh_ds->ds_sr)
    nua_server_request_destroy(nh->nh_ds->ds_sr);

  nua_dialog_deinit(nh, nh->nh_ds);

  if (nh_is_inserted(nh))
    nh_remove(nua, nh);

  nua_handle_unref(nh);		/* Remove stack reference */
}
Example #2
0
/**@internal
 * Relay response event to the application.
 *
 * @todo
 * If handle has already been marked as destroyed by nua_handle_destroy(),
 * release the handle with nh_destroy().
 *
 * @retval 0 if event was preliminary
 * @retval 1 if event was final
 * @retval 2 if event destroyed the handle, too.
 */
int nua_base_client_response(nua_client_request_t *cr,
			     int status, char const *phrase,
			     sip_t const *sip,
			     tagi_t const *tags)
{
  nua_handle_t *nh = cr->cr_owner;
  sip_method_t method = cr->cr_method;
  nua_dialog_usage_t *du;

  cr->cr_reporting = 1, nh->nh_ds->ds_reporting = 1;

  if (nh->nh_auth && sip &&
      (sip->sip_authentication_info || sip->sip_proxy_authentication_info)) {
    /* Collect nextnonce */
    if (sip->sip_authentication_info)
      auc_info(&nh->nh_auth,
	       sip->sip_authentication_info,
	       sip_authorization_class);
    if (sip->sip_proxy_authentication_info)
      auc_info(&nh->nh_auth,
	       sip->sip_proxy_authentication_info,
	       sip_proxy_authorization_class);
  }

  if ((method != sip_method_invite && status >= 200) || status >= 300)
    nua_client_request_remove(cr);

  nua_client_report(cr, status, phrase, sip, cr->cr_orq, tags);

  if (status < 200 ||
      /* Un-ACKed 2XX response to INVITE */
      (method == sip_method_invite && status < 300 && !cr->cr_acked)) {
    cr->cr_reporting = 0, nh->nh_ds->ds_reporting = 0;
    return 1;
  }

  nua_client_request_clean(cr);

  du = cr->cr_usage;

  if (cr->cr_terminated < 0) {
    /* XXX - dialog has been terminated */;
    nua_dialog_deinit(nh, nh->nh_ds), cr->cr_usage = NULL;
  }
  else if (du) {
    if (cr->cr_terminated ||
	(!du->du_ready && status >= 300 && nua_client_is_bound(cr))) {
      /* Usage has been destroyed */
      nua_dialog_usage_remove(nh, nh->nh_ds, du, cr, NULL), cr->cr_usage = NULL;
    }
    else if (cr->cr_graceful) {
      /* Terminate usage gracefully */
      if (nua_dialog_usage_shutdown(nh, nh->nh_ds, du) > 0)
	cr->cr_usage = NULL;
    }
  }
  else if (cr->cr_terminated) {
    if (nh->nh_ds->ds_usage == NULL)
      nua_dialog_remove(nh, nh->nh_ds, NULL), cr->cr_usage = NULL;
  }

  cr->cr_phrase = NULL;
  cr->cr_reporting = 0, nh->nh_ds->ds_reporting = 0;

  if (method == sip_method_cancel)
    return 1;

  return nua_client_next_request(nh->nh_ds->ds_cr, method == sip_method_invite);
}