Mark access points with "linksys" SSID as unique
[connman] / plugins / modem.c
index b770170..4c8a3e3 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  Connection Manager
  *
- *  Copyright (C) 2007-2008  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
 struct modem_data {
        char *device;
        GIOChannel *channel;
+       guint watch;
+       GSList *callbacks;
        GSList *commands;
        char buf[1024];
        int offset;
 };
 
+struct modem_callback {
+       char *command;
+       modem_cb_t function;
+       void *user_data;
+};
+
 struct modem_cmd {
        char *cmd;
        char *arg;
@@ -118,6 +126,7 @@ static gboolean modem_event(GIOChannel *channel,
 {
        struct modem_data *modem = user_data;
        struct modem_cmd *cmd;
+       GSList *list;
        gsize len;
        GIOError err;
 
@@ -132,7 +141,20 @@ static gboolean modem_event(GIOChannel *channel,
                return FALSE;
        }
 
-       DBG("Read %d bytes (offset %d)", len, modem->offset);
+       DBG("Read %zu bytes (offset %d)", len, modem->offset);
+
+       if (g_str_has_suffix(modem->buf, "\r\n") == TRUE) {
+               for (list = modem->callbacks; list; list = list->next) {
+                       struct modem_callback *callback = list->data;
+
+                       if (callback->function == NULL)
+                               continue;
+
+                       if (g_strrstr(modem->buf, callback->command) != NULL)
+                               callback->function(modem->buf,
+                                                       callback->user_data);
+               }
+       }
 
        if (g_strrstr(modem->buf, "\r\nERROR\r\n") == NULL &&
                                g_strrstr(modem->buf, "\r\nOK\r\n") == NULL) {
@@ -140,6 +162,7 @@ static gboolean modem_event(GIOChannel *channel,
                return TRUE;
        }
 
+       memset(modem->buf, 0, sizeof(modem->buf));
        modem->offset = 0;
 
        cmd = g_slist_nth_data(modem->commands, 0);
@@ -178,7 +201,9 @@ static int open_device(const char *device)
        tcflush(fd, TCIOFLUSH);
 
        /* Switch TTY to raw mode */
+       memset(&ti, 0, sizeof(ti));
        cfmakeraw(&ti);
+
        tcsetattr(fd, TCSANOW, &ti);
 
        return fd;
@@ -210,7 +235,7 @@ int modem_open(struct modem_data *modem)
        modem->channel = g_io_channel_unix_new(fd);
        g_io_channel_set_close_on_unref(modem->channel, TRUE);
 
-       g_io_add_watch(modem->channel,
+       modem->watch = g_io_add_watch(modem->channel,
                                G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
                                                        modem_event, modem);
 
@@ -224,14 +249,33 @@ int modem_close(struct modem_data *modem)
        if (modem == NULL)
                return -ENOENT;
 
-       g_io_channel_shutdown(modem->channel, TRUE, NULL);
-       g_io_channel_unref(modem->channel);
+       g_source_remove(modem->watch);
+       modem->watch = 0;
 
+       g_io_channel_unref(modem->channel);
        modem->channel = NULL;
 
        return 0;
 }
 
+int modem_add_callback(struct modem_data *modem, const char *command,
+                                       modem_cb_t function, void *user_data)
+{
+       struct modem_callback *callback;
+
+       callback = g_try_new0(struct modem_callback, 1);
+       if (callback == NULL)
+               return -ENOMEM;
+
+       callback->command   = g_strdup(command);
+       callback->function  = function;
+       callback->user_data = user_data;
+
+       modem->callbacks = g_slist_append(modem->callbacks, callback);
+
+       return 0;
+}
+
 static int modem_command_valist(struct modem_data *modem, modem_cb_t callback,
                                        void *user_data, const char *command,
                                        const char *format, va_list var_args)