summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/phonesim-control-api.txt34
-rw-r--r--plugins/phonesim.c129
2 files changed, 156 insertions, 7 deletions
diff --git a/doc/phonesim-control-api.txt b/doc/phonesim-control-api.txt
new file mode 100644
index 0000000..39d7036
--- /dev/null
+++ b/doc/phonesim-control-api.txt
@@ -0,0 +1,34 @@
+Phonesim control hierarchy
+
+==========================
+
+Service org.ofono
+Interface org.ofono.phonesim.Manager
+Object path /
+
+Methods Add(string name, string address, string port)
+
+ Instantiates a new modem in phonesim with the given
+ specifications.
+
+ RemoveAll()
+
+ Removes all modems from phonesim.
+
+ Reset()
+
+ Removes all modems and instantiates all those modems listed
+ in the configuration file. Equivalent to stopping and
+ restarting the daemon.
+
+Examples
+
+To add a new phonesim modem on the fly do the following:
+
+- Start new phonesim instance
+ * ./phonesim -p 12346 your_very_own.xml
+- Call the [interface].Add("myname", "127.0.0.1", "12346")
+ * dbus-send --system --print-reply --dest=org.ofono / \
+ org.ofono.phonesim.Manager.Add string:myname string:127.0.0.1 string:12346
+ * dbus-send --system --print-reply --dest=org.ofono \
+ /myname org.ofono.Modem.SetProperty string:Powered variant:boolean:true
diff --git a/plugins/phonesim.c b/plugins/phonesim.c
index 16bccd5..8a124c5 100644
--- a/plugins/phonesim.c
+++ b/plugins/phonesim.c
@@ -35,6 +35,7 @@
#include <glib.h>
#include <gatmux.h>
#include <gatchat.h>
+#include <gdbus.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/plugin.h>
@@ -73,6 +74,8 @@ static const char *none_prefix[] = { NULL };
static const char *ptty_prefix[] = { "+PTTY:", NULL };
static const char *simstate_prefix[] = { "+SIMSTATE:", NULL };
static int next_iface = 0;
+static const char CONTROL_PATH[] = "/";
+static const char CONTROL_INTERFACE[] = "org.ofono.phonesim.Manager";
struct phonesim_data {
GAtMux *mux;
@@ -1137,6 +1140,119 @@ done:
g_key_file_free(keyfile);
}
+static void release_modems(void)
+{
+ GSList *list;
+
+ for (list = modem_list; list; list = list->next) {
+ struct ofono_modem *modem = list->data;
+
+ ofono_modem_remove(modem);
+ }
+
+ g_slist_free(modem_list);
+ modem_list = NULL;
+}
+
+static DBusMessage *control_add(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ const char *driver = "phonesim";
+ struct ofono_modem *modem;
+ DBusMessageIter iter;
+ char *name;
+ char *address;
+ char *port;
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return __ofono_error_invalid_args(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return __ofono_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter, &name);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return __ofono_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter, &address);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return __ofono_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter, &port);
+
+ modem = ofono_modem_create(name, driver);
+ if (modem == NULL)
+ return NULL;
+
+ ofono_modem_set_string(modem, "Address", address);
+ ofono_modem_set_integer(modem, "Port", atoi(port));
+ if (ofono_modem_register(modem) != 0) {
+ ofono_modem_remove(modem);
+ return __ofono_error_invalid_args(msg);
+ }
+ modem_list = g_slist_prepend(modem_list, modem);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *control_remove_all(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ release_modems();
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *control_reset(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ release_modems();
+ parse_config();
+
+ return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable control_methods[] = {
+ { GDBUS_METHOD("Add",
+ GDBUS_ARGS({ "name", "s" }, {"address", "s"}, {"port", "s"}),
+ NULL,
+ control_add) },
+ { GDBUS_METHOD("RemoveAll",
+ GDBUS_ARGS({ }),
+ NULL,
+ control_remove_all) },
+ { GDBUS_METHOD("Reset",
+ GDBUS_ARGS({ }),
+ NULL,
+ control_reset) },
+ {}
+};
+
+static int setup_control_channel(void)
+{
+ int err = 0;
+ DBusConnection *conn = ofono_dbus_get_connection();
+ void *user_data = NULL;
+ g_dbus_register_interface(conn,
+ CONTROL_PATH, CONTROL_INTERFACE,
+ control_methods,
+ NULL,
+ NULL,
+ user_data,
+ NULL);
+ return err;
+}
+
+static void shutdown_control_channel(void)
+{
+ g_dbus_unregister_interface(ofono_dbus_get_connection(),
+ CONTROL_PATH, CONTROL_INTERFACE);
+}
+
static int phonesim_init(void)
{
int err;
@@ -1157,20 +1273,19 @@ static int phonesim_init(void)
else
parse_config(CONFIGDIR "/phonesim.conf");
+ err = setup_control_channel();
+ if (err < 0)
+ return err;
+
return 0;
}
static void phonesim_exit(void)
{
- GSList *list;
+ shutdown_control_channel();
- for (list = modem_list; list; list = list->next) {
- struct ofono_modem *modem = list->data;
+ release_modems();
- ofono_modem_remove(modem);
- }
-
- g_slist_free(modem_list);
modem_list = NULL;
ofono_radio_settings_driver_unregister(&radio_settings_driver);