Skinny: Milestone 1 : device level (API)

skinny device *
skinny device <device_name>

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16751 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Mathieu Parent 2010-02-24 11:58:15 +00:00
parent b78542299c
commit ba1950a75d
1 changed files with 160 additions and 16 deletions

View File

@ -113,7 +113,7 @@ struct register_message {
char deviceName[16];
uint32_t userId;
uint32_t instance;
uint32_t ip;
struct in_addr ip;
uint32_t deviceType;
uint32_t maxStreams;
};
@ -156,13 +156,15 @@ struct skinny_device {
char deviceName[16];
uint32_t userId;
uint32_t instance;
uint32_t ip;
struct in_addr ip;
uint32_t deviceType;
uint32_t maxStreams;
uint16_t port;
};
typedef struct skinny_device skinny_device_t;
typedef switch_status_t (*skinny_command_t) (char **argv, int argc, switch_stream_handle_t *stream);
/*****************************************************************************/
/* LISTENERS TYPES */
/*****************************************************************************/
@ -189,7 +191,7 @@ struct listener {
typedef struct listener listener_t;
typedef switch_status_t (*skinny_listener_callback_func_t) (listener_t *listener);
typedef switch_status_t (*skinny_listener_callback_func_t) (listener_t *listener, void *pvt);
static struct {
switch_socket_t *sock;
@ -218,7 +220,7 @@ static switch_status_t channel_kill_channel(switch_core_session_t *session, int
/* LISTENER FUNCTIONS */
static switch_status_t keepalive_listener(listener_t *listener);
static switch_status_t keepalive_listener(listener_t *listener, void *pvt);
/*****************************************************************************/
/* CHANNEL FUNCTIONS */
@ -735,7 +737,7 @@ static switch_status_t skinny_parse_request(listener_t *listener, skinny_message
reply->data.reg_ack.secondaryKeepAlive = globals.keep_alive;
/* TODO send CapabilitiesReqMessage (and parse the CapabilitiesResMessage) */
/* TODO event */
keepalive_listener(listener);
keepalive_listener(listener, NULL);
break;
case PORT_MESSAGE:
/* Nothing to do */
@ -744,7 +746,7 @@ static switch_status_t skinny_parse_request(listener_t *listener, skinny_message
reply = switch_core_alloc(listener->pool, 12);
reply->type = KEEP_ALIVE_ACK_MESSAGE;
reply->length = 4;
keepalive_listener(listener);
keepalive_listener(listener, NULL);
break;
/* TODO */
default:
@ -807,13 +809,13 @@ static void remove_listener(listener_t *listener)
}
static void walk_listeners(skinny_listener_callback_func_t callback)
static void walk_listeners(skinny_listener_callback_func_t callback, void *pvt)
{
listener_t *l;
switch_mutex_lock(globals.listener_mutex);
for (l = listen_list.listeners; l; l = l->next) {
callback(l);
callback(l, pvt);
}
switch_mutex_unlock(globals.listener_mutex);
@ -825,6 +827,47 @@ static void flush_listener(listener_t *listener, switch_bool_t flush_log, switch
/* TODO */
}
static listener_t *find_listener(char *device_name)
{
listener_t *l, *r = NULL;
skinny_device_t *device;
switch_mutex_lock(globals.listener_mutex);
for (l = listen_list.listeners; l; l = l->next) {
if (l->device) {
device = l->device;
if(!strcasecmp(device->deviceName,device_name)) {
if (switch_thread_rwlock_tryrdlock(l->rwlock) == SWITCH_STATUS_SUCCESS) {
r = l;
}
break;
}
}
}
switch_mutex_unlock(globals.listener_mutex);
return r;
}
static switch_status_t dump_listener(listener_t *listener, void *pvt)
{
switch_stream_handle_t *stream = (switch_stream_handle_t *) pvt;
const char *line = "=================================================================================================";
skinny_device_t *device;
if(listener->device) {
device = listener->device;
stream->write_function(stream, "%s\n", line);
stream->write_function(stream, "DeviceName \t%s\n", switch_str_nil(device->deviceName));
stream->write_function(stream, "UserId \t%d\n", device->userId);
stream->write_function(stream, "Instance \t%d\n", device->instance);
stream->write_function(stream, "IP \t%s\n", inet_ntoa(device->ip));
stream->write_function(stream, "DeviceType \t%d\n", device->deviceType);
stream->write_function(stream, "MaxStreams \t%d\n", device->maxStreams);
stream->write_function(stream, "Port \t%d\n", device->port);
stream->write_function(stream, "%s\n", line);
}
return SWITCH_STATUS_SUCCESS;
}
static void close_socket(switch_socket_t **sock)
{
switch_mutex_lock(listen_list.sock_mutex);
@ -836,7 +879,7 @@ static void close_socket(switch_socket_t **sock)
switch_mutex_unlock(listen_list.sock_mutex);
}
static switch_status_t kill_listener(listener_t *listener)
static switch_status_t kill_listener(listener_t *listener, void *pvt)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Killing listener.\n");
switch_clear_flag(listener, LFLAG_RUNNING);
@ -844,15 +887,15 @@ static switch_status_t kill_listener(listener_t *listener)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kill_expired_listener(listener_t *listener)
static switch_status_t kill_expired_listener(listener_t *listener, void *pvt)
{
if(listener->expire_time < switch_epoch_time_now(NULL)) {
return kill_listener(listener);
return kill_listener(listener, pvt);
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t keepalive_listener(listener_t *listener)
static switch_status_t keepalive_listener(listener_t *listener, void *pvt)
{
switch_assert(listener);
@ -895,7 +938,7 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK, TRUE);
switch_set_flag_locked(listener, LFLAG_RUNNING);
keepalive_listener(listener);
keepalive_listener(listener, NULL);
add_listener(listener);
@ -1140,15 +1183,110 @@ static switch_status_t load_skinny_config(void)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t cmd_device(char **argv, int argc, switch_stream_handle_t *stream)
{
listener_t *listener;
if (argc != 1) {
stream->write_function(stream, "Invalid Args!\n");
return SWITCH_STATUS_SUCCESS;
}
if (argv[0] && !strcasecmp(argv[0], "*")) {
walk_listeners(dump_listener, stream);
} else {
listener=find_listener(argv[0]);
if(listener) {
dump_listener(listener, stream);
}
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(skinny_function)
{
char *argv[1024] = { 0 };
int argc = 0;
char *mycmd = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
skinny_command_t func = NULL;
const char *usage_string = "USAGE:\n"
"--------------------------------------------------------------------------------\n"
"skinny help\n"
"skinny device *\n"
"skinny device <device_name>\n"
"--------------------------------------------------------------------------------\n";
if (session) {
return SWITCH_STATUS_FALSE;
}
if (zstr(cmd)) {
stream->write_function(stream, "%s", usage_string);
goto done;
}
if (!(mycmd = strdup(cmd))) {
status = SWITCH_STATUS_MEMERR;
goto done;
}
if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) || !argv[0]) {
stream->write_function(stream, "%s", usage_string);
goto done;
}
if (!strcasecmp(argv[0], "device")) {
func = cmd_device;
} else if (!strcasecmp(argv[0], "help")) {
stream->write_function(stream, "%s", usage_string);
goto done;
}
if (func) {
status = func(&argv[1], argc - 1, stream);
} else {
stream->write_function(stream, "Unknown Command [%s]\n", argv[0]);
}
done:
switch_safe_free(mycmd);
return status;
}
static void event_handler(switch_event_t *event)
{
if (event->event_id == SWITCH_EVENT_HEARTBEAT) {
walk_listeners(kill_expired_listener);
walk_listeners(kill_expired_listener, NULL);
}
}
static switch_status_t skinny_list_devices(const char *line, const char *cursor, switch_console_callback_match_t **matches)
{
switch_console_callback_match_t *my_matches = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
listener_t *l;
skinny_device_t *device;
switch_mutex_lock(globals.listener_mutex);
for (l = listen_list.listeners; l; l = l->next) {
if(l->device) {
device = l->device;
switch_console_push_match(&my_matches, device->deviceName);
}
}
switch_mutex_unlock(globals.listener_mutex);
if (my_matches) {
*matches = my_matches;
status = SWITCH_STATUS_SUCCESS;
}
return status;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
{
switch_api_interface_t *api_interface;
module_pool = pool;
@ -1174,6 +1312,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
skinny_endpoint_interface->state_handler = &skinny_state_handlers;
SWITCH_ADD_API(api_interface, "skinny", "Skinny Controls", skinny_function, "<cmd> <args>");
switch_console_set_complete("add skinny help");
switch_console_set_complete("add skinny device *");
switch_console_set_complete("add skinny device ::skinny::list_devices");
switch_console_add_complete_func("::skinny::list_devices", skinny_list_devices);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@ -1191,13 +1335,13 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
running = 0;
walk_listeners(kill_listener);
walk_listeners(kill_listener, NULL);
close_socket(&listen_list.sock);
while (globals.listener_threads) {
switch_yield(100000);
walk_listeners(kill_listener);
walk_listeners(kill_listener, NULL);
if (++sanity >= 200) {
break;
}