about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/cmd_ac.c1
-rw-r--r--src/command/cmd_defs.c3
-rw-r--r--src/command/cmd_funcs.c13
-rw-r--r--src/command/cmd_funcs.h1
-rw-r--r--src/config/preferences.c2
-rw-r--r--src/omemo/omemo.c5
-rw-r--r--src/tools/http_upload.c2
-rw-r--r--src/ui/console.c20
-rw-r--r--src/ui/core.c14
-rw-r--r--src/ui/inputwin.c29
-rw-r--r--src/ui/titlebar.c23
-rw-r--r--src/ui/ui.h4
-rw-r--r--src/ui/win_types.h2
-rw-r--r--src/ui/window.c36
-rw-r--r--src/ui/window_list.c116
-rw-r--r--src/ui/window_list.h2
-rw-r--r--src/xmpp/omemo.c16
17 files changed, 279 insertions, 10 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index b84d4d2e..03c6e404 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -471,6 +471,7 @@ cmd_ac_init(void)
 
     wins_ac = autocomplete_new();
     autocomplete_add(wins_ac, "unread");
+    autocomplete_add(wins_ac, "attention");
     autocomplete_add(wins_ac, "prune");
     autocomplete_add(wins_ac, "swap");
 
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index 4ebc3432..0ebcf04f 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -973,6 +973,7 @@ static struct cmd_t command_defs[] = {
       parse_args, 0, 3, NULL,
       CMD_SUBFUNCS(
               { "unread", cmd_wins_unread },
+              { "attention", cmd_wins_attention },
               { "prune", cmd_wins_prune },
               { "swap", cmd_wins_swap })
       CMD_MAINFUNC(cmd_wins)
@@ -981,6 +982,7 @@ static struct cmd_t command_defs[] = {
       CMD_SYN(
               "/wins",
               "/wins unread",
+              "/wins attention",
               "/wins prune",
               "/wins swap <source> <target>")
       CMD_DESC(
@@ -988,6 +990,7 @@ static struct cmd_t command_defs[] = {
               "Passing no argument will list all currently active windows and information about their usage.")
       CMD_ARGS(
               { "unread", "List windows with unread messages." },
+              { "attention", "List windows that have been marked with the attention flag (alt+f). You can toggle between marked windows with alt+m." },
               { "prune", "Close all windows with no unread messages." },
               { "swap <source> <target>", "Swap windows, target may be an empty position." })
       CMD_NOEXAMPLES
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index b2262c5f..901c81a3 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -1299,6 +1299,13 @@ cmd_wins_unread(ProfWin* window, const char* const command, gchar** args)
 }
 
 gboolean
+cmd_wins_attention(ProfWin* window, const char* const command, gchar** args)
+{
+    cons_show_wins_attention();
+    return TRUE;
+}
+
+gboolean
 cmd_wins_prune(ProfWin* window, const char* const command, gchar** args)
 {
     ui_prune_wins();
@@ -9418,15 +9425,11 @@ cmd_editor(ProfWin* window, const char* const command, gchar** args)
     g_object_unref(fos);
 
     char* editor = prefs_get_string(PREF_COMPOSE_EDITOR);
-    if (!g_file_test(editor, G_FILE_TEST_EXISTS)) {
-        cons_show_error("Editor: binary %s not exist", editor);
-        return TRUE;
-    }
 
     // Fork / exec
     pid_t pid = fork();
     if (pid == 0) {
-        int x = execl(editor, editor, g_file_get_path(file), (char*)NULL);
+        int x = execlp(editor, editor, g_file_get_path(file), (char*)NULL);
         if (x == -1) {
             cons_show_error("Editor:Failed to exec %s", editor);
         }
diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h
index 0785963b..aadcb55f 100644
--- a/src/command/cmd_funcs.h
+++ b/src/command/cmd_funcs.h
@@ -209,6 +209,7 @@ gboolean cmd_otr_sendfile(ProfWin* window, const char* const command, gchar** ar
 
 gboolean cmd_wins(ProfWin* window, const char* const command, gchar** args);
 gboolean cmd_wins_unread(ProfWin* window, const char* const command, gchar** args);
+gboolean cmd_wins_attention(ProfWin* window, const char* const command, gchar** args);
 gboolean cmd_wins_prune(ProfWin* window, const char* const command, gchar** args);
 gboolean cmd_wins_swap(ProfWin* window, const char* const command, gchar** args);
 
diff --git a/src/config/preferences.c b/src/config/preferences.c
index 4ff51092..c930fccd 100644
--- a/src/config/preferences.c
+++ b/src/config/preferences.c
@@ -2340,7 +2340,7 @@ _get_default_string(preference_t pref)
     case PREF_URL_OPEN_CMD:
         return "xdg-open %u";
     case PREF_COMPOSE_EDITOR:
-        return "/usr/bin/vim";
+        return "vim";
     case PREF_URL_SAVE_CMD:
         return NULL; // Default to built-in method.
     default:
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index fa07cfb7..9b2b35f5 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -1348,14 +1348,15 @@ _handle_own_device_list(const char* const jid, GList* device_list)
 {
     // We didn't find the own device id -> publish
     if (!g_list_find(device_list, GINT_TO_POINTER(omemo_ctx.device_id))) {
-        log_debug("[OMEMO] No device id for our device? publish device list...");
+        cons_show("Could not find own OMEMO device ID. Going to publish own device ID: %d", GINT_TO_POINTER(omemo_ctx.device_id));
+        log_debug("[OMEMO] No device ID for our device. Publishing device list");
         device_list = g_list_copy(device_list);
         device_list = g_list_append(device_list, GINT_TO_POINTER(omemo_ctx.device_id));
         g_hash_table_insert(omemo_ctx.device_list, strdup(jid), device_list);
         omemo_devicelist_publish(device_list);
     }
 
-    log_debug("[OMEMO] Request OMEMO Bundles for my devices...");
+    log_debug("[OMEMO] Request OMEMO Bundles for our devices");
     GList* device_id;
     for (device_id = device_list; device_id != NULL; device_id = device_id->next) {
         omemo_bundle_request(jid, GPOINTER_TO_INT(device_id->data), omemo_start_device_session_handle_bundle, free, strdup(jid));
diff --git a/src/tools/http_upload.c b/src/tools/http_upload.c
index 17eca188..d1360b46 100644
--- a/src/tools/http_upload.c
+++ b/src/tools/http_upload.c
@@ -194,7 +194,7 @@ http_file_put(void* userdata)
 
     struct curl_slist* headers = NULL;
     content_type_header = g_strdup_printf("Content-Type: %s", upload->mime_type);
-    if (content_type_header) {
+    if (!content_type_header) {
         content_type_header = g_strdup(FALLBACK_CONTENTTYPE_HEADER);
     }
     headers = curl_slist_append(headers, content_type_header);
diff --git a/src/ui/console.c b/src/ui/console.c
index 3eff47d5..74a7740f 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -507,6 +507,26 @@ cons_show_wins(gboolean unread)
 }
 
 void
+cons_show_wins_attention() {
+    ProfWin* console = wins_get_console();
+    cons_show("");
+    GSList* window_strings = wins_create_summary_attention();
+
+    GSList* curr = window_strings;
+    while (curr) {
+        if (g_strstr_len(curr->data, strlen(curr->data), " unread") > 0) {
+            win_println(console, THEME_CMD_WINS_UNREAD, "-", "%s", curr->data);
+        } else {
+            win_println(console, THEME_DEFAULT, "-", "%s", curr->data);
+        }
+        curr = g_slist_next(curr);
+    }
+    g_slist_free_full(window_strings, free);
+
+    cons_alert(NULL);
+}
+
+void
 cons_show_room_invites(GList* invites)
 {
     cons_show("");
diff --git a/src/ui/core.c b/src/ui/core.c
index 4e4e39a0..f4ee4a86 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -996,6 +996,20 @@ ui_win_unread(int index)
     }
 }
 
+gboolean
+ui_win_has_attention(int index)
+{
+    gboolean ret = FALSE;
+
+    ProfWin* window = wins_get_by_num(index);
+    if (window) {
+        ret = win_has_attention(window);
+    }
+
+    return ret;
+}
+
+
 char*
 ui_ask_password(gboolean confirm)
 {
diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c
index 74fcfbb4..b2b2ea33 100644
--- a/src/ui/inputwin.c
+++ b/src/ui/inputwin.c
@@ -125,6 +125,8 @@ static int _inp_rl_win_20_handler(int count, int key);
 static int _inp_rl_win_prev_handler(int count, int key);
 static int _inp_rl_win_next_handler(int count, int key);
 static int _inp_rl_win_next_unread_handler(int count, int key);
+static int _inp_rl_win_attention_handler(int count, int key);
+static int _inp_rl_win_attention_next_handler(int count, int key);
 static int _inp_rl_win_pageup_handler(int count, int key);
 static int _inp_rl_win_pagedown_handler(int count, int key);
 static int _inp_rl_subwin_pageup_handler(int count, int key);
@@ -480,6 +482,8 @@ _inp_rl_startup_hook(void)
     rl_bind_keyseq("\\e\\e[C", _inp_rl_win_next_handler);
 
     rl_bind_keyseq("\\ea", _inp_rl_win_next_unread_handler);
+    rl_bind_keyseq("\\ef", _inp_rl_win_attention_handler);
+    rl_bind_keyseq("\\em", _inp_rl_win_attention_next_handler);
 
     rl_bind_keyseq("\\e\\e[5~", _inp_rl_subwin_pageup_handler);
     rl_bind_keyseq("\\e[5;3~", _inp_rl_subwin_pageup_handler);
@@ -807,6 +811,31 @@ _inp_rl_win_next_unread_handler(int count, int key)
 }
 
 static int
+_inp_rl_win_attention_handler(int count, int key) {
+    ProfWin* current = wins_get_current();
+    if ( current ) {
+        gboolean attention = win_toggle_attention(current);
+        if (attention) {
+            win_println(current, THEME_DEFAULT, "!", "Attention flag has been activated");
+        } else {
+            win_println(current, THEME_DEFAULT, "!", "Attention flag has been deactivated");
+        }
+        win_redraw(current);
+    }
+    return 0;
+}
+
+static int
+_inp_rl_win_attention_next_handler(int count, int key) {
+    ProfWin* window = wins_get_next_attention();
+    if (window) {
+        ui_focus_win(window);
+    }
+    return 0;
+}
+
+
+static int
 _inp_rl_win_pageup_handler(int count, int key)
 {
     ProfWin* current = wins_get_current();
diff --git a/src/ui/titlebar.c b/src/ui/titlebar.c
index dee6a7e2..98af2b24 100644
--- a/src/ui/titlebar.c
+++ b/src/ui/titlebar.c
@@ -67,6 +67,7 @@ static void _show_contact_presence(ProfChatWin* chatwin, int pos, int maxpos);
 static void _show_privacy(ProfChatWin* chatwin);
 static void _show_muc_privacy(ProfMucWin* mucwin);
 static void _show_scrolled(ProfWin* current);
+static void _show_attention(ProfWin* current, gboolean attention);
 
 void
 create_title_bar(void)
@@ -210,6 +211,7 @@ _title_bar_draw(void)
         assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
         _show_contact_presence(chatwin, pos, maxrightpos);
         _show_privacy(chatwin);
+        _show_attention(current, chatwin->has_attention);
         _show_scrolled(current);
 
         if (typing) {
@@ -219,6 +221,7 @@ _title_bar_draw(void)
         ProfMucWin* mucwin = (ProfMucWin*)current;
         assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
         _show_muc_privacy(mucwin);
+        _show_attention(current, mucwin->has_attention);
         _show_scrolled(current);
     }
 
@@ -229,6 +232,26 @@ _title_bar_draw(void)
 }
 
 static void
+_show_attention(ProfWin* current, gboolean attention)
+{
+    int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET);
+    int text_attrs = theme_attrs(THEME_TITLE_TEXT);
+
+    if (attention) {
+        wprintw(win, " ");
+        wattron(win, bracket_attrs);
+        wprintw(win, "[");
+        wattroff(win, bracket_attrs);
+        wattron(win, text_attrs);
+        wprintw(win, "ATTENTION");
+        wattroff(win, text_attrs);
+        wattron(win, bracket_attrs);
+        wprintw(win, "]");
+        wattroff(win, bracket_attrs);
+    }
+}
+
+static void
 _show_scrolled(ProfWin* current)
 {
     if (current && current->layout->paged == 1) {
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 391b906c..f9ef5cff 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -75,6 +75,9 @@ int ui_close_all_wins(void);
 int ui_close_read_wins(void);
 void ui_close_win(int index);
 int ui_win_unread(int index);
+gboolean ui_win_has_attention(int index);
+gboolean win_has_attention(ProfWin* window); 
+gboolean win_toggle_attention(ProfWin* window);
 char* ui_ask_password(gboolean confirm);
 char* ui_get_line(void);
 char* ui_ask_pgp_passphrase(const char* hint, int prev_fail);
@@ -256,6 +259,7 @@ void cons_show_contacts(GSList* list);
 void cons_show_roster(GSList* list);
 void cons_show_roster_group(const char* const group, GSList* list);
 void cons_show_wins(gboolean unread);
+void cons_show_wins_attention();
 char* cons_get_string(ProfConsoleWin* conswin);
 void cons_show_status(const char* const barejid);
 void cons_show_info(PContact pcontact);
diff --git a/src/ui/win_types.h b/src/ui/win_types.h
index e740b543..f2237a79 100644
--- a/src/ui/win_types.h
+++ b/src/ui/win_types.h
@@ -176,6 +176,7 @@ typedef struct prof_chat_win_t
     // For LMC
     char* last_message;
     char* last_msg_id;
+    gboolean has_attention;
 } ProfChatWin;
 
 typedef struct prof_muc_win_t
@@ -196,6 +197,7 @@ typedef struct prof_muc_win_t
     // For LMC
     char* last_message;
     char* last_msg_id;
+    gboolean has_attention;
 } ProfMucWin;
 
 typedef struct prof_conf_win_t ProfConfWin;
diff --git a/src/ui/window.c b/src/ui/window.c
index b6676774..4fb7d5f7 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -158,7 +158,7 @@ win_create_chat(const char* const barejid)
     new_win->outgoing_char = NULL;
     new_win->last_message = NULL;
     new_win->last_msg_id = NULL;
-
+    new_win->has_attention = FALSE;
     new_win->memcheck = PROFCHATWIN_MEMCHECK;
 
     return &new_win->window;
@@ -213,6 +213,7 @@ win_create_muc(const char* const roomjid)
     new_win->is_omemo = FALSE;
     new_win->last_message = NULL;
     new_win->last_msg_id = NULL;
+    new_win->has_attention = FALSE;
 
     new_win->memcheck = PROFMUCWIN_MEMCHECK;
 
@@ -1841,6 +1842,39 @@ win_unread(ProfWin* window)
     }
 }
 
+gboolean
+win_has_attention(ProfWin* window) 
+{
+    if (window->type == WIN_CHAT) {
+        ProfChatWin* chatwin = (ProfChatWin*)window;
+        assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
+        return chatwin->has_attention;
+    } else if (window->type == WIN_MUC) {
+        ProfMucWin* mucwin = (ProfMucWin*)window;
+        assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
+        return mucwin->has_attention;
+    }
+    return FALSE;
+}
+
+gboolean 
+win_toggle_attention(ProfWin* window) 
+{
+    if (window->type == WIN_CHAT) {
+        ProfChatWin* chatwin = (ProfChatWin*)window;
+        assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
+        chatwin->has_attention = !chatwin->has_attention;
+        return chatwin->has_attention;
+    } else if (window->type == WIN_MUC) {
+        ProfMucWin* mucwin = (ProfMucWin*)window;
+        assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
+        mucwin->has_attention = !mucwin->has_attention;
+        return mucwin->has_attention;
+    }
+    return FALSE;
+}
+
+
 void
 win_sub_print(WINDOW* win, char* msg, gboolean newline, gboolean wrap, int indent)
 {
diff --git a/src/ui/window_list.c b/src/ui/window_list.c
index a90c7141..19104ea0 100644
--- a/src/ui/window_list.c
+++ b/src/ui/window_list.c
@@ -52,6 +52,10 @@
 #include "xmpp/roster_list.h"
 #include "tools/http_upload.h"
 
+#ifdef HAVE_OMEMO
+#include "omemo/omemo.h"
+#endif
+
 static GHashTable* windows;
 static int current;
 static Autocomplete wins_ac;
@@ -864,6 +868,24 @@ wins_reestablished_connection(void)
         if (window->type != WIN_CONSOLE) {
             win_println(window, THEME_TEXT, "-", "Connection re-established.");
 
+#ifdef HAVE_OMEMO
+            if (window->type == WIN_CHAT) {
+                ProfChatWin* chatwin = (ProfChatWin*)window;
+                assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
+                if (chatwin->is_omemo) {
+                    win_println(window, THEME_TEXT, "-", "Restarted OMEMO session.");
+                    omemo_start_session(chatwin->barejid);
+                }
+            } else if (window->type == WIN_MUC) {
+                ProfMucWin* mucwin = (ProfMucWin*)window;
+                assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
+                if (mucwin->is_omemo) {
+                    win_println(window, THEME_TEXT, "-", "Restarted OMEMO session.");
+                    omemo_start_muc_sessions(mucwin->roomjid);
+                }
+            }
+#endif
+
             // if current win, set current_win_dirty
             if (wins_is_current(window)) {
                 win_update_virtual(window);
@@ -1102,6 +1124,51 @@ wins_create_summary(gboolean unread)
     return result;
 }
 
+GSList*
+wins_create_summary_attention()
+{
+    GSList* result = NULL;
+
+    GList* keys = g_hash_table_get_keys(windows);
+    keys = g_list_sort(keys, _wins_cmp_num);
+    GList* curr = keys;
+
+    while (curr) {
+        ProfWin* window = g_hash_table_lookup(windows, curr->data);
+        gboolean has_attention = FALSE;
+        if (window->type == WIN_CHAT) {
+            ProfChatWin* chatwin = (ProfChatWin*)window;
+            assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
+            has_attention = chatwin->has_attention;
+        } else if (window->type == WIN_MUC) {
+            ProfMucWin* mucwin = (ProfMucWin*)window;
+            assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
+            has_attention = mucwin->has_attention;
+        }
+        if (has_attention) {
+            GString* line = g_string_new("");
+
+            int ui_index = GPOINTER_TO_INT(curr->data);
+            char* winstring = win_to_string(window);
+            if (!winstring) {
+                g_string_free(line, TRUE);
+                continue;
+            }
+
+            g_string_append_printf(line, "%d: %s", ui_index, winstring);
+            free(winstring);
+
+            result = g_slist_append(result, strdup(line->str));
+            g_string_free(line, TRUE);
+        }
+        curr = g_list_next(curr);
+    }
+
+    g_list_free(keys);
+
+    return result;
+}
+
 char*
 win_autocomplete(const char* const search_str, gboolean previous, void* context)
 {
@@ -1160,6 +1227,55 @@ wins_get_next_unread(void)
     return NULL;
 }
 
+ProfWin*
+wins_get_next_attention(void)
+{
+    // get and sort win nums
+    GList* values = g_hash_table_get_values(windows);
+    values = g_list_sort(values, _wins_cmp_num);
+    GList* curr = values;
+
+    ProfWin* current_window = wins_get_by_num(current);
+
+    // search the current window
+    while (curr) {
+        ProfWin* window = curr->data;
+        if (current_window == window) {
+            current_window = window;
+            curr = g_list_next(curr);
+            break;
+        }
+        curr = g_list_next(curr);
+    }
+
+    // Start from current window
+    while (current_window && curr) {
+        ProfWin* window = curr->data;
+        if (win_has_attention(window)) {
+            g_list_free(values);
+            return window;
+        }
+        curr = g_list_next(curr);
+    }
+    // Start from begin
+    curr = values;
+    while (current_window && curr) {
+        ProfWin* window = curr->data;
+        if (current_window == window) {
+            // we are at current again
+            break;
+        }
+        if (win_has_attention(window)) {
+            g_list_free(values);
+            return window;
+        }
+        curr = g_list_next(curr);
+    }
+
+    g_list_free(values);
+    return NULL;
+}
+
 void
 wins_add_urls_ac(const ProfWin* const win, const ProfMessage* const message)
 {
diff --git a/src/ui/window_list.h b/src/ui/window_list.h
index e02358f9..06ae6d7e 100644
--- a/src/ui/window_list.h
+++ b/src/ui/window_list.h
@@ -74,6 +74,7 @@ ProfWin* wins_get_by_string(const char* str);
 ProfWin* wins_get_next(void);
 ProfWin* wins_get_previous(void);
 ProfWin* wins_get_next_unread(void);
+ProfWin* wins_get_next_attention(void);
 int wins_get_num(ProfWin* window);
 int wins_get_current_num(void);
 void wins_close_by_num(int i);
@@ -87,6 +88,7 @@ void wins_lost_connection(void);
 void wins_reestablished_connection(void);
 gboolean wins_tidy(void);
 GSList* wins_create_summary(gboolean unread);
+GSList* wins_create_summary_attention();
 void wins_destroy(void);
 GList* wins_get_nums(void);
 void wins_swap(int source_win, int target_win);
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index 773d6224..54cd12ad 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -51,6 +51,8 @@ static int _omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const
 static int _omemo_bundle_publish_configure(xmpp_stanza_t* const stanza, void* const userdata);
 static int _omemo_bundle_publish_configure_result(xmpp_stanza_t* const stanza, void* const userdata);
 
+static int _omemo_device_list_publish_result(xmpp_stanza_t* const stanza, void* const userdata);
+
 void
 omemo_devicelist_subscribe(void)
 {
@@ -71,6 +73,8 @@ omemo_devicelist_publish(GList* device_list)
         stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open");
     }
 
+    iq_id_handler_add(xmpp_stanza_get_id(iq), _omemo_device_list_publish_result, NULL, NULL);
+
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
 }
@@ -608,3 +612,15 @@ _omemo_bundle_publish_configure_result(xmpp_stanza_t* const stanza, void* const
 
     return 0;
 }
+
+static int
+_omemo_device_list_publish_result(xmpp_stanza_t* const stanza, void* const userdata)
+{
+    const char* type = xmpp_stanza_get_type(stanza);
+    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
+        cons_show_error("Unable to publish own OMEMO device list");
+        log_error("[OMEMO] Publishing device list failed");
+        return 0;
+    }
+    return 0;
+}