#define CONTEXT_ADDED "ContextAdded"
#define CONTEXT_REMOVED "ContextRemoved"
+#define SET_PROPERTY "SetProperty"
#define GET_MODEMS "GetModems"
#define TIMEOUT 40000
connman_bool_t powered;
connman_bool_t online;
uint8_t interfaces;
+
+ connman_bool_t set_powered;
+
+ /* pending calls */
+ DBusPendingCall *call_set_property;
};
+typedef void (*set_property_cb)(struct modem_data *data,
+ connman_bool_t success);
+
+struct property_info {
+ struct modem_data *modem;
+ const char *path;
+ const char *interface;
+ const char *property;
+ set_property_cb set_property_cb;
+};
+
+static void set_property_reply(DBusPendingCall *call, void *user_data)
+{
+ struct property_info *info = user_data;
+ DBusMessage *reply;
+ DBusError error;
+ connman_bool_t success = TRUE;
+
+ DBG("%s path %s %s.%s", info->modem->path,
+ info->path, info->interface, info->property);
+
+ info->modem->call_set_property = NULL;
+
+ dbus_error_init(&error);
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("Failed to change property: %s %s.%s: %s %s",
+ info->path, info->interface, info->property,
+ error.name, error.message);
+ dbus_error_free(&error);
+ success = FALSE;
+ }
+
+ if (info->set_property_cb != NULL)
+ (*info->set_property_cb)(info->modem, success);
+
+ dbus_message_unref(reply);
+
+ dbus_pending_call_unref(call);
+}
+
+static int set_property(struct modem_data *modem,
+ const char *path, const char *interface,
+ const char *property, int type, void *value,
+ set_property_cb notify)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ struct property_info *info;
+
+ DBG("%s path %s %s.%s", modem->path, path, interface, property);
+
+ if (modem->call_set_property != NULL) {
+ connman_error("Pending SetProperty");
+ return -EBUSY;
+ }
+
+ message = dbus_message_new_method_call(OFONO_SERVICE, path,
+ interface, SET_PROPERTY);
+ if (message == NULL)
+ return -ENOMEM;
+
+ dbus_message_iter_init_append(message, &iter);
+ connman_dbus_property_append_basic(&iter, property, type, value);
+
+ if (dbus_connection_send_with_reply(connection, message,
+ &modem->call_set_property, TIMEOUT) == FALSE) {
+ connman_error("Failed to change property: %s %s.%s",
+ path, interface, property);
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ if (modem->call_set_property == NULL) {
+ connman_error("D-Bus connection not available");
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ info = g_try_new0(struct property_info, 1);
+ if (info == NULL) {
+ dbus_message_unref(message);
+ return -ENOMEM;
+ }
+
+ info->modem = modem;
+ info->path = path;
+ info->interface = interface;
+ info->property = property;
+ info->set_property_cb = notify;
+
+ dbus_pending_call_set_notify(modem->call_set_property,
+ set_property_reply, info, g_free);
+
+ dbus_message_unref(message);
+
+ return -EINPROGRESS;
+}
+
+static int modem_set_powered(struct modem_data *modem)
+{
+ DBG("%s", modem->path);
+
+ modem->set_powered = TRUE;
+
+ return set_property(modem, modem->path,
+ OFONO_MODEM_INTERFACE,
+ "Powered", DBUS_TYPE_BOOLEAN,
+ &modem->set_powered,
+ NULL);
+}
+
static uint8_t extract_interfaces(DBusMessageIter *array)
{
DBusMessageIter entry;
dbus_message_iter_get_basic(&value, &modem->powered);
DBG("%s Powered %d", modem->path, modem->powered);
+
+ if (modem->powered == FALSE)
+ modem_set_powered(modem);
} else if (g_str_equal(key, "Online") == TRUE) {
dbus_message_iter_get_basic(&value, &modem->online);
dbus_message_iter_next(prop);
}
+
+ if (modem->powered == FALSE)
+ modem_set_powered(modem);
}
static void remove_modem(gpointer data)
DBG("%s", modem->path);
+ if (modem->call_set_property != NULL)
+ dbus_pending_call_cancel(modem->call_set_property);
+
g_free(modem->serial);
g_free(modem->path);