[PATCH 4/6] emulator: Add Enable/Disable for oFono emulator
Zhenhua Zhang
zhenhua.zhang at intel.com
Sun Jul 4 22:45:07 PDT 2010
Use tty descriptor passed from BlueZ agent to enable emulator. It uses
gatserver to handle incoming AT commands.
In disable or remove emulator stage, we shutdown the gatserver.
---
include/emulator.h | 3 +
plugins/dun_gw.c | 15 ++++++
src/emulator.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/include/emulator.h b/include/emulator.h
index 0c87b13..9d96d67 100644
--- a/include/emulator.h
+++ b/include/emulator.h
@@ -52,6 +52,9 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
struct ofono_emulator_driver *driver);
void ofono_emulator_remove(struct ofono_emulator *e);
+ofono_bool_t ofono_emulator_enable(struct ofono_emulator *e, int fd);
+void ofono_emulator_disable(struct ofono_emulator *e);
+
int ofono_emulator_driver_register(const struct ofono_emulator_driver *driver);
void ofono_emulator_driver_unregister(
const struct ofono_emulator_driver *driver);
diff --git a/plugins/dun_gw.c b/plugins/dun_gw.c
index 95b176c..43a0b0a 100644
--- a/plugins/dun_gw.c
+++ b/plugins/dun_gw.c
@@ -111,6 +111,8 @@ static DBusMessage *dun_agent_new_connection(DBusConnection *conn,
DBusMessage *msg,
void *user_data)
{
+ struct dun_data *data = user_data;
+ struct ofono_emulator *e = data->e;
DBusMessage *reply;
int fd;
@@ -121,6 +123,14 @@ static DBusMessage *dun_agent_new_connection(DBusConnection *conn,
goto error;
}
+ if (!ofono_emulator_enable(e, fd)) {
+ reply = g_dbus_create_error(msg, DUN_AGENT_INTERFACE, ".Failed",
+ "Failed to enable DUN Server");
+ goto error;
+ }
+
+ DBG("Accept new DUN connection");
+
return dbus_message_new_method_return(msg);
error:
@@ -211,6 +221,9 @@ static int dun_gw_enable(struct ofono_emulator *e, int fd)
{
DBG("%p", e);
+ if (!ofono_emulator_enable(e, fd))
+ return -EINVAL;
+
return 0;
}
@@ -218,6 +231,8 @@ static int dun_gw_disable(struct ofono_emulator *e)
{
DBG("%p", e);
+ ofono_emulator_disable(e);
+
return 0;
}
diff --git a/src/emulator.c b/src/emulator.c
index 6b63398..1155769 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -30,6 +30,7 @@
#include <gdbus.h>
#include "ofono.h"
+#include "gatserver.h"
#include "common.h"
struct ofono_emulator {
@@ -38,12 +39,19 @@ struct ofono_emulator {
struct ofono_atom *atom;
unsigned int id;
void *user_data;
+ GAtServer *server;
+ ofono_bool_t powered;
};
static GSList *emulator_list;
static GSList *ofono_emulator_drivers;
static unsigned int ofono_emulator_ids;
+static void ofono_emulator_debug(const char *str, void *data)
+{
+ g_print("%s: %s\n", (char *)data, str);
+}
+
static unsigned int ofono_emulator_next_id()
{
unsigned int i;
@@ -121,6 +129,9 @@ static void emulator_remove(struct ofono_atom *atom)
emulator_list = g_slist_remove(emulator_list, e);
+ if (e->powered)
+ e->driver->disable(e);
+
if (e->driver->remove)
e->driver->remove(e);
@@ -129,6 +140,78 @@ static void emulator_remove(struct ofono_atom *atom)
e = NULL;
}
+void ofono_emulator_disable(struct ofono_emulator *e)
+{
+ if (e->server == NULL)
+ return;
+
+ g_at_server_shutdown(e->server);
+ g_at_server_unref(e->server);
+ e->server = NULL;
+
+ e->powered = FALSE;
+}
+
+static int set_powered(struct ofono_emulator *e, ofono_bool_t powered, int fd)
+{
+ int val;
+
+ if (powered == TRUE && e->driver->enable)
+ val = e->driver->enable(e, fd);
+ else if (powered == FALSE && e->driver->disable)
+ val = e->driver->disable(e);
+ else
+ return -EINVAL;
+
+ e->powered = powered;
+
+ return val;
+}
+
+static void emulator_disconnect(gpointer data)
+{
+ struct ofono_emulator *e = data;
+
+ set_powered(e, FALSE, 0);
+}
+
+ofono_bool_t ofono_emulator_enable(struct ofono_emulator *e, int fd)
+{
+ GAtServer *server;
+ GIOChannel *channel;
+
+ if (fd <= 0 || e->server != NULL)
+ return FALSE;
+
+ channel = g_io_channel_unix_new(fd);
+ server = g_at_server_new(channel);
+ if (!server)
+ goto error;
+
+ e->server = server;
+ g_at_server_set_debug(e->server, ofono_emulator_debug, "Server");
+ g_at_server_set_disconnect_function(e->server, emulator_disconnect, e);
+
+ g_io_channel_unref(channel);
+
+ e->powered = TRUE;
+
+ return TRUE;
+
+error:
+ if (channel) {
+ g_io_channel_shutdown(channel, FALSE, NULL);
+ g_io_channel_unref(channel);
+ }
+
+ if (server) {
+ g_at_server_shutdown(server);
+ g_at_server_unref(server);
+ }
+
+ return FALSE;
+}
+
static struct ofono_emulator *create_emulator(struct ofono_modem *modem,
struct ofono_emulator_driver *driver)
{
@@ -156,8 +239,52 @@ static DBusMessage *emulator_get_properties(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
+static DBusMessage *emulator_enable(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ struct ofono_emulator *e = data;
+ const char *path;
+ int fd;
+ ofono_bool_t powered = TRUE;
+
+ if (!e)
+ return FALSE;
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UNIX_FD, &fd,
+ DBUS_TYPE_INVALID) == FALSE)
+ return __ofono_error_invalid_args(msg);
+
+ if (set_powered(e, TRUE, fd) < 0)
+ return __ofono_error_failed(msg);
+
+ reply = dbus_message_new_method_return(msg);
+ path = ofono_emulator_get_path(e);
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_EMULATOR_INTERFACE,
+ "Powered", DBUS_TYPE_BOOLEAN,
+ &powered);
+ return reply;
+}
+
+static DBusMessage *emulator_disable(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_emulator *e = data;
+
+ set_powered(e, FALSE, 0);
+
+ return dbus_message_new_method_return(msg);
+}
+
static GDBusMethodTable ofono_emulator_methods[] = {
{ "GetProperties", "", "a{sv}", emulator_get_properties },
+ { "Enable", "h", "", emulator_enable,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "Disable", "", "", emulator_disable },
{ }
};
--
1.6.3.3
More information about the ofono
mailing list