Ejemplo n.º 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;
}
/** This callback will be called by SIP stack to process incoming events */
static void mrcp_sofia_event_callback( nua_event_t           nua_event,
									   int                   status,
									   char const           *phrase,
									   nua_t                *nua,
									   mrcp_sofia_agent_t   *sofia_agent,
									   nua_handle_t         *nh,
									   mrcp_sofia_session_t *sofia_session,
									   sip_t const          *sip,
									   tagi_t                tags[])
{
	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive SIP Event [%s] Status %d %s",nua_event_name(nua_event),status,phrase);

	switch(nua_event) {
		case nua_i_state:
			mrcp_sofia_on_state_change(sofia_agent,nh,sofia_session,sip,tags);
			break;
		case nua_i_options:
			mrcp_sofia_on_resource_discover(sofia_agent,nh,sofia_session,sip,tags);
			break;
		case nua_r_shutdown:
			/* if status < 200, shutdown still in progress */
			if(status >= 200) {
				/* break main loop of sofia thread */
				su_root_break(sofia_agent->root);
			}
			break;
		default:
			break;
	}
}
Ejemplo n.º 3
0
static int luasofia_nua_event_name(lua_State *L)
{
    nua_event_t event = lua_tointeger(L, -1);
    char const *name = nua_event_name(event);
    lua_pushstring(L, name);
    return 1;
}
Ejemplo n.º 4
0
/*# Receive event from protocol machine and hand it over to application */
static
void nua_application_event(nua_t *dummy, su_msg_r sumsg, nua_ee_data_t *ee)
{
  nua_t *nua = ee->ee_nua;
  nua_event_data_t *e = ee->ee_data;
  nua_handle_t *nh = e->e_nh;

  enter;

  ee->ee_nua = NULL;
  e->e_nh = NULL;

  if (nh == NULL) {
    /* Xyzzy */
  }
  else if (nh->nh_valid) {
    if (!nh->nh_ref_by_user) {
      /* Application must now call nua_handle_destroy() */
      nh->nh_ref_by_user = 1;
      nua_handle_ref(nh);
    }
  }
  else if (!nh->nh_valid) {	/* Handle has been destroyed */
    if (nua_log->log_level >= 7) {
      char const *name = nua_event_name((enum nua_event_e)e->e_event) + 4;
      SU_DEBUG_7(("nua(%p): event %s dropped\n", (void *)nh, name));
    }
    nua_handle_unref(nh);
    nua_stack_unref(nua);
    return;
  }

  if (e->e_event == nua_r_shutdown && e->e_status >= 200)
    nua->nua_shutdown_final = 1;

  if (nua->nua_callback) {
    nua_event_frame_t frame[1];

    su_msg_save(frame->nf_saved, sumsg);
    frame->nf_next = nua->nua_current, nua->nua_current = frame;

    nua->nua_callback((enum nua_event_e)e->e_event, e->e_status, e->e_phrase,
		      nua, nua->nua_magic,
		      nh, nh ? nh->nh_magic : NULL,
		      e->e_msg ? sip_object(e->e_msg) : NULL,
		      e->e_tags);

    su_msg_destroy(frame->nf_saved);
    nua->nua_current = frame->nf_next;
  }

  nua_handle_unref(nh);
  nua_stack_unref(nua);
}
Ejemplo n.º 5
0
/* ----------------------------------------------------------------------
 * Receiving events from client
 */
static
void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_ee_data_t *ee)
{
  nua_event_data_t *e = ee->ee_data;
  nua_handle_t *nh = e->e_nh;
  tagi_t *tags = e->e_tags;
  nua_event_t event;
  int error = 0;

  if (nh) {
    if (!nh->nh_prev)
      nh_append(nua, nh);
    if (!nh->nh_ref_by_stack) {
      /* Mark handle as used by stack */
      nh->nh_ref_by_stack = 1;
      nua_handle_ref(nh);
    }
  }

  if (nua_log->log_level >= 5) {
    char const *name = nua_event_name((enum nua_event_e)e->e_event);

    if (e->e_status == 0)
      SU_DEBUG_5(("nua(%p): %s signal %s\n", (void *)nh, "recv", name + 4));
    else
      SU_DEBUG_5(("nua(%p): recv signal %s %u %s\n",
		  (void *)nh, name + 4,
		  e->e_status, e->e_phrase ? e->e_phrase : ""));
  }

  su_msg_save(nua->nua_signal, msg);

  event = (enum nua_event_e)e->e_event;

  if (nua->nua_shutdown && !e->e_always) {
    /* Shutting down */
    nua_stack_event(nua, nh, NULL, event,
		    901, "Stack is going down",
		    NULL);
  }
  else switch (event) {
  case nua_r_get_params:
    nua_stack_get_params(nua, nh ? nh : nua->nua_dhandle, event, tags);
    break;
  case nua_r_set_params:
    nua_stack_set_params(nua, nh ? nh : nua->nua_dhandle, event, tags);
    break;
  case nua_r_shutdown:
    nua_stack_shutdown(nua);
    break;
  case nua_r_register:
  case nua_r_unregister:
    nua_stack_register(nua, nh, event, tags);
    break;
  case nua_r_invite:
    error = nua_stack_invite(nua, nh, event, tags);
    break;
  case nua_r_cancel:
    error = nua_stack_cancel(nua, nh, event, tags);
    break;
  case nua_r_bye:
    error = nua_stack_bye(nua, nh, event, tags);
    break;
  case nua_r_options:
    error = nua_stack_options(nua, nh, event, tags);
    break;
  case nua_r_refer:
    error = nua_stack_refer(nua, nh, event, tags);
    break;
  case nua_r_publish:
  case nua_r_unpublish:
    error = nua_stack_publish(nua, nh, event, tags);
    break;
  case nua_r_info:
    error = nua_stack_info(nua, nh, event, tags);
    break;
  case nua_r_prack:
    error = nua_stack_prack(nua, nh, event, tags);
    break;
  case nua_r_update:
    error = nua_stack_update(nua, nh, event, tags);
    break;
  case nua_r_message:
    error = nua_stack_message(nua, nh, event, tags);
    break;
  case nua_r_subscribe:
  case nua_r_unsubscribe:
    error = nua_stack_subscribe(nua, nh, event, tags);
    break;
  case nua_r_notify:
    error = nua_stack_notify(nua, nh, event, tags);
    break;
  case nua_r_notifier:
    nua_stack_notifier(nua, nh, event, tags);
    break;
  case nua_r_terminate:
    nua_stack_terminate(nua, nh, event, tags);
    break;
  case nua_r_method:
    error = nua_stack_method(nua, nh, event, tags);
    break;
  case nua_r_authenticate:
    nua_stack_authenticate(nua, nh, event, tags);
    break;
  case nua_r_authorize:
    nua_stack_authorize(nua, nh, event, tags);
    break;
  case nua_r_ack:
    error = nua_stack_ack(nua, nh, event, tags);
    break;
  case nua_r_respond:
    nua_stack_respond(nua, nh, e->e_status, e->e_phrase, tags);
    break;
  case nua_r_destroy:
    nua_stack_destroy_handle(nua, nh, tags);
    su_msg_destroy(nua->nua_signal);
    return;
  default:
    break;
  }

  if (error < 0) {
    nua_stack_event(nh->nh_nua, nh, NULL, event,
		    NUA_ERROR_AT(__FILE__, __LINE__), NULL);
  }

  su_msg_destroy(nua->nua_signal);
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/* NUA event callback */
static void nua_event_callback(nua_event_t event,
                               int status, char const *phrase,
                               nua_t *nua, nua_magic_t *magic,
                               nua_handle_t *nh, nua_hmagic_t *hmagic,
                               sip_t const *sip,
                               tagi_t tags[])
{
    int error;
    lua_State *L = (lua_State *)magic;

    SU_DEBUG_9(("nua_event_callback: event[%s] status[%d] phrase[%s] "
                "nua[%p] magic[%p] nh[%p] hmagic[%p] sip[%p] tags[%p]\n",
                nua_event_name(event), status, phrase, nua, magic, nh, hmagic, sip, tags));

    /* put nua userdatum at stack and check if it is ok. */
    luasofia_userdata_table_get(L, nua);

    if (lua_isnil(L, -1)) {
        SU_DEBUG_1(("nua_event_callback: nua userdata not found on userdata_table!\n"));
        return;
    }

    luaL_checkudata(L, -1, NUA_MTABLE);

    /* put env table at stack */
    lua_getfenv(L, -1);

    /* put callback table at stack */
    lua_rawgeti(L, -1, ENV_CALLBACK_INDEX);
    if (lua_isnil(L, -1)) {
        lua_pop(L, 3);
        SU_DEBUG_1(("nua_event_callback: callback table not found!\n"));
        return;
    }

    /* get event callback */
    lua_rawgeti(L, -1, event);
    if (lua_isnil(L, -1)) {
        lua_pop(L, 1);
        /* get event default callback */
        lua_rawgeti(L, -1, NUA_EVENT_DEFAULT_INDEX);
        if (lua_isnil(L, -1)) {
            lua_pop(L, 4);
            SU_DEBUG_9(("nua_event_callback: event[%s] callback not found!\n", nua_event_name(event)));
            return;
        }
    }

    lua_pushinteger(L, event);
    lua_pushinteger(L, status);
    lua_pushstring(L, phrase);
    lua_pushvalue(L, -7);

    /* get magic field */
    lua_rawgeti(L, -7, ENV_MAGIC_INDEX);

    if (nh) { 
        /* put nua_handle userdatum at stack */
        luasofia_userdata_table_get(L, nh);
        if (lua_isnil(L, -1)) {
            /* create a new nua_handle userdatum */
            lua_pop(L, 1);
            luasofia_nua_handle_create_userdata(L, nh);
            lua_pushnil(L);
        } else {
            /* check if it is a nua_handle */
            luaL_checkudata(L, -1, NUA_HANDLE_MTABLE);
            
            /* put env table at stack */
            lua_getfenv(L, -1);
        }
    } else {
        lua_pushnil(L);
        lua_pushnil(L);
    }

    sip ? lua_pushlightuserdata(L, (void*)sip) : lua_pushnil(L);

    tags ? lua_pushlightuserdata(L, (void*)tags) : lua_pushnil(L);

    SU_DEBUG_9(("nua_event_callback: calling lua callback\n"));
    if ((error = lua_pcall(L, 9, 0, 0)) != 0) {
        if (error == LUA_ERRMEM) 
            SU_DEBUG_0(("nua_event_callback: memory allocation error! error[%s]\n", lua_tostring(L, -1)));
        else
            SU_DEBUG_1(("nua_event_callback: error on calling callback! error[%s]\n", lua_tostring(L, -1)));
        lua_pop(L, 1);
    }
    lua_pop(L, 3);
}