static switch_status_t handle_msg_session_event(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { int custom = 0; switch_event_types_t type; int i = 0; switch_thread_rwlock_wrlock(session->event_rwlock); for (i = 1; i < arity; i++) { if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_insert(session->event_hash, atom, MARKER); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { if (type == SWITCH_EVENT_ALL) { uint32_t x = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ALL events enabled for %s\n", session->uuid_str); for (x = 0; x < SWITCH_EVENT_ALL; x++) { session->event_list[x] = 1; } } if (type <= SWITCH_EVENT_ALL) { session->event_list[type] = 1; } if (type == SWITCH_EVENT_CUSTOM) { custom++; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s for session %s\n", atom, session->uuid_str); } } switch_thread_rwlock_unlock(session->event_rwlock); ei_x_encode_atom(rbuf, "ok"); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t handle_msg_session_nixevent(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { int custom = 0; int i = 0; switch_event_types_t type; switch_thread_rwlock_wrlock(session->event_rwlock); for (i = 1; i < arity; i++) { if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_delete(session->event_hash, atom); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { uint32_t x = 0; if (type == SWITCH_EVENT_CUSTOM) { custom++; } else if (type == SWITCH_EVENT_ALL) { for (x = 0; x <= SWITCH_EVENT_ALL; x++) { session->event_list[x] = 0; } } else { if (session->event_list[SWITCH_EVENT_ALL]) { session->event_list[SWITCH_EVENT_ALL] = 0; for (x = 0; x < SWITCH_EVENT_ALL; x++) { session->event_list[x] = 1; } } session->event_list[type] = 0; } } } } switch_thread_rwlock_unlock(session->event_rwlock); ei_x_encode_atom(rbuf, "ok"); } else { /* no session for this pid */ ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; switch_status_t ret = SWITCH_STATUS_SUCCESS; if (ei_decode_atom(buf->buff, &buf->index, atom)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else if (!strncmp(atom, "nolog", MAXATOMLEN)) { if (switch_test_flag(listener, LFLAG_LOG)) { void *pop; /*purge the log queue */ while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS); switch_clear_flag_locked(listener, LFLAG_LOG); } ei_x_encode_atom(rbuf, "ok"); } else if (!strncmp(atom, "register_log_handler", MAXATOMLEN)) { ei_link(listener, ei_self(listener->ec), &msg->from); listener->log_process.type = ERLANG_PID; memcpy(&listener->log_process.pid, &msg->from, sizeof(erlang_pid)); listener->level = SWITCH_LOG_DEBUG; switch_set_flag(listener, LFLAG_LOG); ei_x_encode_atom(rbuf, "ok"); } else if (!strncmp(atom, "register_event_handler", MAXATOMLEN)) { ei_link(listener, ei_self(listener->ec), &msg->from); listener->event_process.type = ERLANG_PID; memcpy(&listener->event_process.pid, &msg->from, sizeof(erlang_pid)); if (!switch_test_flag(listener, LFLAG_EVENTS)) { switch_set_flag_locked(listener, LFLAG_EVENTS); } ei_x_encode_atom(rbuf, "ok"); } else if (!strncmp(atom, "noevents", MAXATOMLEN)) { void *pop; /*purge the event queue */ while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS); if (switch_test_flag(listener, LFLAG_EVENTS)) { uint8_t x = 0; switch_clear_flag_locked(listener, LFLAG_EVENTS); for (x = 0; x <= SWITCH_EVENT_ALL; x++) { listener->event_list[x] = 0; } /* wipe the hash */ switch_core_hash_destroy(&listener->event_hash); switch_core_hash_init(&listener->event_hash, listener->pool); ei_x_encode_atom(rbuf, "ok"); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } else if (!strncmp(atom, "session_noevents", MAXATOMLEN)) { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { void *pop; uint8_t x = 0; /*purge the event queue */ while (switch_queue_trypop(session->event_queue, &pop) == SWITCH_STATUS_SUCCESS); for (x = 0; x <= SWITCH_EVENT_ALL; x++) { session->event_list[x] = 0; } /* wipe the hash */ switch_core_hash_destroy(&session->event_hash); switch_core_hash_init(&session->event_hash, session->pool); ei_x_encode_atom(rbuf, "ok"); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } else if (!strncmp(atom, "exit", MAXATOMLEN)) { ei_x_encode_atom(rbuf, "ok"); ret = SWITCH_STATUS_TERM; } else if (!strncmp(atom, "getpid", MAXATOMLEN)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "ok"); ei_x_encode_pid(rbuf, ei_self(listener->ec)); } else if (!strncmp(atom, "link", MAXATOMLEN)) { /* debugging */ ei_link(listener, ei_self(listener->ec), &msg->from); ret = SWITCH_STATUS_FALSE; } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "undef"); } return ret; }
static switch_status_t handle_msg_session_setevent(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1){ ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { uint8_t event_list[SWITCH_EVENT_ALL + 1]; switch_hash_t *event_hash; int custom = 0; int i = 0; switch_event_types_t type; uint32_t x = 0; /* clear any previous event registrations */ for (x = 0; x <= SWITCH_EVENT_ALL; x++){ event_list[x] = 0; } /* create new hash */ switch_core_hash_init(&event_hash, session->pool); for (i = 1; i < arity; i++){ if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_insert(event_hash, atom, MARKER); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { if (type == SWITCH_EVENT_ALL) { ei_x_encode_tuple_header(rbuf, 1); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); break; } if (type <= SWITCH_EVENT_ALL) { event_list[type] = 1; } if (type == SWITCH_EVENT_CUSTOM) { custom++; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s for session %s\n", atom, session->uuid_str); } } /* update the event subscriptions with the new ones */ switch_thread_rwlock_wrlock(session->event_rwlock); memcpy(session->event_list, event_list, sizeof(uint8_t) * (SWITCH_EVENT_ALL + 1)); /* wipe the old hash, and point the pointer at the new one */ switch_core_hash_destroy(&session->event_hash); session->event_hash = event_hash; switch_thread_rwlock_unlock(session->event_rwlock); /* TODO - we should flush any non-matching events from the queue */ ei_x_encode_atom(rbuf, "ok"); } else { /* no session for this pid */ ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } return SWITCH_STATUS_SUCCESS; }