]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Skinny: Milestone 1 : device level (API)
authorMathieu Parent <math.parent@gmail.com>
Wed, 24 Feb 2010 11:58:15 +0000 (11:58 +0000)
committerMathieu Parent <math.parent@gmail.com>
Wed, 24 Feb 2010 11:58:15 +0000 (11:58 +0000)
skinny device *
skinny device <device_name>

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16751 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_skinny/mod_skinny.c

index f3c46cbe850a84be1869e776ffe067dabdfbc98e..04b9b153bac2cc6d9024c9a9619b2e214bd622aa 100644 (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;
                }