+static DBusMessage *join_network(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct connman_device *device = data;
+ struct connman_network *network;
+ enum connman_network_type type;
+ DBusMessageIter iter, array;
+ int err, index;
+
+ DBG("conn %p", conn);
+
+ if (__connman_security_check_privilege(msg,
+ CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
+ return __connman_error_permission_denied(msg);
+
+ if (!device->driver || !device->driver->join)
+ return __connman_error_not_supported(msg);
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_recurse(&iter, &array);
+
+ switch (device->type) {
+ case CONNMAN_DEVICE_TYPE_WIFI:
+ type = CONNMAN_NETWORK_TYPE_WIFI;
+ break;
+ default:
+ return __connman_error_not_supported(msg);
+ }
+
+ network = connman_network_create("00_00_00_00_00_00", type);
+ if (network == NULL)
+ return __connman_error_failed(msg, ENOMEM);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key, *str;
+
+ dbus_message_iter_recurse(&array, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ switch (dbus_message_iter_get_arg_type(&value)) {
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_get_basic(&value, &str);
+ if (g_str_equal(key, "WiFi.SSID") == TRUE)
+ connman_network_set_blob(network, key,
+ str, strlen(str));
+ else
+ connman_network_set_string(network, key, str);
+ break;
+ }
+
+ dbus_message_iter_next(&array);
+ }
+
+ index = connman_device_get_index(device);
+ connman_network_set_index(network, index);
+
+ connman_network_set_protocol(network, CONNMAN_NETWORK_PROTOCOL_IP);
+
+ err = device->driver->join(device, network);
+
+ connman_network_unref(network);
+
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+