Example #1
0
/*# Send a request to the protocol thread */
int nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg,
	       nua_event_t event,
	       int status, char const *phrase,
	       tag_type_t tag, tag_value_t value, ...)
{
  su_msg_r sumsg = SU_MSG_R_INIT;
  size_t len, xtra, ee_len, l_len = 0, l_xtra = 0;
  ta_list ta;
  int retval = -1;

  if (nua == NULL)
    return -1;

  if (nua->nua_shutdown_started && event != nua_r_shutdown)
    return -1;

  ta_start(ta, tag, value);

  ee_len = offsetof(nua_ee_data_t, ee_data[0].e_tags);
  len = tl_len(ta_args(ta));
  xtra = tl_xtra(ta_args(ta), len);

  if (su_msg_new(sumsg, ee_len + len + l_len + xtra + l_xtra) == 0) {
    nua_ee_data_t *ee = su_msg_data(sumsg);
    nua_event_data_t *e = ee->ee_data;
    tagi_t *t = e->e_tags;
    void *b = (char *)t + len + l_len;

    tagi_t *tend = (tagi_t *)b;
    char *bend = (char *)b + xtra + l_xtra;

    t = tl_dup(t, ta_args(ta), &b);

    assert(tend == t); (void)tend; assert(b == bend); (void)bend;

    e->e_always = event == nua_r_destroy || event == nua_r_shutdown;
    e->e_event = event;
    e->e_nh = nh ? nua_handle_ref(nh) : NULL;
    e->e_status = status;
    e->e_phrase = phrase;

    su_msg_deinitializer(sumsg, nua_event_deinit);

    retval = su_msg_send_to(sumsg, nua->nua_server, nua_stack_signal);

    if (retval == 0){
      SU_DEBUG_7(("nua(%p): %s signal %s\n", (void *)nh,
		  "sent", nua_event_name(event) + 4));
    }
    else {
      SU_DEBUG_0(("nua(%p): %s signal %s\n", (void *)nh,
		  "FAILED TO SEND", nua_event_name(event) + 4));

    }
  }

  ta_end(ta);

  return retval;
}
Example #2
0
/** Allocate and duplicate a tag list using memory home. */
tagi_t *tl_adup(su_home_t *home, tagi_t const lst[])
{
    size_t len = tl_len(lst);
    size_t xtra = tl_xtra(lst, 0);
    void *b = su_alloc(home, len + xtra);
    tagi_t *d, *newlst = b;

    void *end = (char *)b + len + xtra;
    tagi_t *tend = (tagi_t*)((char *)b + len);

    b = (char *)b + len;

    d = tl_dup(newlst, lst, &b);

    assert(b == end);
    assert(tend == d);
    (void)end;
    (void)tend;

    return newlst;
}
Example #3
0
/** @internal Send an event to the application. */
int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
		    nua_event_t event, int status, char const *phrase,
		    tagi_t const *tags)
{
  su_msg_r sumsg = SU_MSG_R_INIT;
  size_t e_len, len, xtra, p_len;

  if (event == nua_r_ack || event == nua_i_none)
    return event;

  if (nh == nua->nua_dhandle)
    nh = NULL;

  if (nua_log->log_level >= 5) {
    char const *name = nua_event_name(event) + 4;
    char const *p = phrase ? phrase : "";

    if (status == 0)
      SU_DEBUG_5(("nua(%p): event %s %s\n", (void *)nh, name, p));
    else
      SU_DEBUG_5(("nua(%p): event %s %u %s\n", (void *)nh, name, status, p));
  }

  if (event == nua_r_destroy) {
    if (msg)
      msg_destroy(msg);
    if (status >= 200) {
      nh_destroy(nua, nh);
    }
    return event;
  }

  if ((event > nua_r_authenticate && event <= nua_r_ack)
      || event < nua_i_error
      || (nh && !nh->nh_valid)
      || (nua->nua_shutdown && event != nua_r_shutdown &&
	  !nua->nua_prefs->ngp_shutdown_events)) {
    if (msg)
      msg_destroy(msg);
    return event;
  }

  if (tags) {
    e_len = offsetof(nua_ee_data_t, ee_data[0].e_tags);
    len = tl_len(tags);
    xtra = tl_xtra(tags, len);
  }
  else {
    e_len = sizeof(nua_ee_data_t), len = 0, xtra = 0;
  }
  p_len = phrase ? strlen(phrase) + 1 : 1;

  if (su_msg_new(sumsg, e_len + len + xtra + p_len) == 0) {
    nua_ee_data_t *ee = su_msg_data(sumsg);
    nua_event_data_t *e = ee->ee_data;
    void *p;

    if (tags) {
      tagi_t *t = e->e_tags, *t_end = (tagi_t *)((char *)t + len);
      void *b = t_end, *end = (char *)b + xtra;

      t = tl_dup(t, tags, &b); p = b;
      assert(t == t_end); assert(b == end); (void)end;
    }
    else
      p = e + 1;

    ee->ee_nua = nua_stack_ref(nua);
    e->e_event = event;
    e->e_nh = nh ? nua_handle_ref(nh) : NULL;
    e->e_status = status;
    e->e_phrase = strcpy(p, phrase ? phrase : "");
    if (msg)
      e->e_msg = msg, su_home_threadsafe(msg_home(msg));

    su_msg_deinitializer(sumsg, nua_event_deinit);

    su_msg_send_to(sumsg, nua->nua_client, nua_application_event);
  }

  return event;
}