static void ethernet_newlink(unsigned flags, unsigned change, void *user_data) { struct connman_device *device = user_data; struct ethernet_data *ethernet = connman_device_get_data(device); _DBG_ETHERNET("index %d flags %d change %d", ethernet->index, flags, change); if ((ethernet->flags & IFF_UP) != (flags & IFF_UP)) { if (flags & IFF_UP) { _DBG_ETHERNET("power on"); connman_device_set_powered(device, TRUE); } else { _DBG_ETHERNET("power off"); connman_device_set_powered(device, FALSE); } } if ((ethernet->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) { if (flags & IFF_LOWER_UP) { _DBG_ETHERNET("carrier on"); connman_device_set_carrier(device, TRUE); } else { _DBG_ETHERNET("carrier off"); connman_device_set_carrier(device, FALSE); } } ethernet->flags = flags; }
int __connman_device_enable(struct connman_device *device) { int err; DBG("device %p", device); if (!device->driver || !device->driver->enable) return -EOPNOTSUPP; /* There is an ongoing power disable request. */ if (device->powered_pending == PENDING_DISABLE) return -EBUSY; if (device->powered_pending == PENDING_ENABLE) return -EALREADY; if (device->powered_pending == PENDING_NONE && device->powered) return -EALREADY; if (device->index > 0) { err = connman_inet_ifup(device->index); if (err < 0 && err != -EALREADY) return err; } device->powered_pending = PENDING_ENABLE; err = device->driver->enable(device); /* * device gets enabled right away. * Invoke the callback */ if (err == 0) { connman_device_set_powered(device, true); goto done; } if (err == -EALREADY) { /* If device is already powered, but connman is not updated */ connman_device_set_powered(device, true); goto done; } /* * if err == -EINPROGRESS, then the DBus call to the respective daemon * was successful. We set a 4 sec timeout so if the daemon never * returns a reply, we would reset the pending request. */ if (err == -EINPROGRESS) device->pending_timeout = g_timeout_add_seconds(4, device_pending_reset, device); done: return err; }
static gboolean device_changed(DBusConnection *conn, DBusMessage *message, void *user_data) { (void)conn; (void)user_data; DBG(""); DBusMessageIter iter; if (dbus_message_iter_init(message, &iter) == FALSE) return TRUE; const char *property; dbus_message_iter_get_basic(&iter, &property); dbus_message_iter_next(&iter); DBusMessageIter value; dbus_message_iter_recurse(&iter, &value); if (g_str_equal(property, POWERED_NAME) == TRUE) { dbus_bool_t powered; dbus_message_iter_get_basic(&value, &powered); connman_device_set_powered(jolla_gps_device, powered); } return TRUE; }
static void device_disable_cb(const DBusError *error, void *user_data) { char *path = user_data; struct connman_device *device; GHashTableIter iter; gpointer key, value; device = g_hash_table_lookup(devices, path); if (device == NULL) { DBG("device already removed"); goto out; } if (dbus_error_is_set(error) == TRUE) { connman_warn("Bluetooth device %s not disabled: %s", path, error->message); goto out; } DBG("device %p %s", device, path); connman_device_set_powered(device, FALSE); g_hash_table_iter_init(&iter, networks); while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { struct bluetooth_pan *pan = value; if (connman_network_get_device(pan->network) == device) { DBG("disable network %p", pan->network); connman_device_remove_network(device, pan->network); } } out: g_free(path); }
static void cfun_callback(gboolean ok, GAtResult *result, gpointer user_data) { struct connman_device *device = user_data; struct mbm_data *data = connman_device_get_data(device); GAtResultIter iter; int status; if (ok == FALSE) return; g_at_result_iter_init(&iter, result); if (g_at_result_iter_next(&iter, "+CFUN:") == FALSE) return; g_at_result_iter_next_number(&iter, &status); if (status == 1) { connman_device_set_powered(device, TRUE); data->network = connman_network_create("internet", CONNMAN_NETWORK_TYPE_MBM); if (data->network != NULL) { int index; index = connman_device_get_index(device); connman_network_set_index(data->network, index); connman_network_set_protocol(data->network, CONNMAN_NETWORK_PROTOCOL_IP); connman_network_set_group(data->network, "internet"); connman_device_add_network(device, data->network); } } else { connman_device_set_powered(device, FALSE); data->network = NULL; } }
static int jolla_gps_disable(struct connman_device *device) { (void)device; DBG(""); if (connman_device_get_string(jolla_gps_device, "Path") == NULL) { connman_device_set_powered(jolla_gps_device, FALSE); return 0; } return change_powered(connection, FALSE); }
static void add_interface_reply(DBusPendingCall *call, void *user_data) { struct supplicant_task *task = user_data; DBusMessage *reply; DBusError error; const char *path; _DBG_SUPPLICANT("task %p", task); reply = dbus_pending_call_steal_reply(call); if (reply == NULL) return; if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) goto failed; dbus_error_init(&error); if (dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) == FALSE) { if (dbus_error_is_set(&error) == TRUE) { connman_error("%s", error.message); dbus_error_free(&error); } else connman_error("Wrong arguments for add interface"); goto failed; } _DBG_SUPPLICANT("path %s", path); task->path = g_strdup(path); task->created = TRUE; connman_device_set_powered(task->device, TRUE); dbus_message_unref(reply); return; failed: dbus_message_unref(reply); task_list = g_slist_remove(task_list, task); connman_device_unref(task->device); free_task(task); }
int __connman_device_disable(struct connman_device *device) { int err; DBG("device %p", device); if (!device->driver || !device->driver->disable) return -EOPNOTSUPP; /* Ongoing power enable request */ if (device->powered_pending == PENDING_ENABLE) return -EBUSY; if (device->powered_pending == PENDING_DISABLE) return -EALREADY; if (device->powered_pending == PENDING_NONE && device->powered == FALSE) return -EALREADY; device->powered_pending = PENDING_DISABLE; device->reconnect = FALSE; if (device->network) { struct connman_service *service = connman_service_lookup_from_network(device->network); if (service != NULL) __connman_service_disconnect(service); else connman_network_set_connected(device->network, FALSE); } err = device->driver->disable(device); if (err == 0 || err == -EALREADY) { connman_device_set_powered(device, FALSE); goto done; } if (err == -EINPROGRESS) device->pending_timeout = g_timeout_add_seconds(4, device_pending_reset, device); done: return err; }
/** * connman_device_set_powered: * @device: device structure * @powered: powered state * * Change power state of device */ int connman_device_set_powered(struct connman_device *device, connman_bool_t powered) { int err; enum connman_service_type type; DBG("driver %p powered %d", device, powered); if (device->powered == powered) { device->powered_pending = powered; return -EALREADY; } if (powered == TRUE) err = __connman_device_enable(device); else err = __connman_device_disable(device); if (err < 0 && err != -EINPROGRESS && err != -EALREADY) return err; device->powered = powered; device->powered_pending = powered; type = __connman_device_get_service_type(device); if (device->powered == TRUE) __connman_technology_enable(type); else __connman_technology_disable(type); if (device->offlinemode == TRUE && powered == TRUE) return connman_device_set_powered(device, FALSE); if (powered == FALSE) return 0; reset_scan_trigger(device); if (device->driver && device->driver->scan) device->driver->scan(device); return 0; }
static void disable_device(struct connman_device *device, const char *path) { GHashTableIter iter; gpointer key, value; DBG("device %p %s", device, path); connman_device_set_powered(device, false); g_hash_table_iter_init(&iter, networks); while (g_hash_table_iter_next(&iter, &key, &value)) { struct bluetooth_pan *pan = value; if (pan->network && connman_network_get_device(pan->network) == device) { DBG("disable network %p", pan->network); connman_device_remove_network(device, pan->network); } } }
static int remove_interface(struct supplicant_task *task) { DBusMessage *message; DBusPendingCall *call; _DBG_SUPPLICANT("task %p", task); #if 0 if (task->created == FALSE) { connman_device_set_powered(task->device, FALSE); return 0; } #endif message = dbus_message_new_method_call(SUPPLICANT_NAME, SUPPLICANT_PATH, SUPPLICANT_INTF, "removeInterface"); if (message == NULL) return -ENOMEM; dbus_message_set_auto_start(message, FALSE); dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &task->path, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(connection, message, &call, TIMEOUT) == FALSE) { connman_error("Failed to remove interface"); dbus_message_unref(message); return -EIO; } if (call == NULL) { connman_error("D-Bus connection not available"); dbus_message_unref(message); return -EIO; } dbus_pending_call_set_notify(call, remove_interface_reply, task, NULL); dbus_message_unref(message); return -EINPROGRESS; }
static void remove_interface_reply(DBusPendingCall *call, void *user_data) { struct supplicant_task *task = user_data; DBusMessage *reply; _DBG_SUPPLICANT("task %p", task); reply = dbus_pending_call_steal_reply(call); connman_device_set_powered(task->device, FALSE); connman_device_unref(task->device); connman_inet_ifdown(task->ifindex); free_task(task); dbus_message_unref(reply); }
static void enable_device(struct connman_device *device, const char *path) { GHashTableIter iter; gpointer key, value; DBG("device %p %s", device, path); connman_device_set_powered(device, true); g_hash_table_iter_init(&iter, networks); while (g_hash_table_iter_next(&iter, &key, &value)) { struct bluetooth_pan *pan = value; if (g_strcmp0(proxy_get_string(pan->btdevice_proxy, "Adapter"), path) == 0) { DBG("enable network %p", pan->network); pan_create_nap(pan); } } }
static void device_create(GDBusProxy *proxy) { struct connman_device *device = NULL; const char *path = g_dbus_proxy_get_path(proxy); const char *address; char ident[BLUETOOTH_ADDR_LEN * 2 + 1]; bool powered; address = proxy_get_string(proxy, "Address"); if (!address) return; address2ident(address, ident); device = connman_device_create("bluetooth", CONNMAN_DEVICE_TYPE_BLUETOOTH); if (!device) return; connman_device_set_data(device, g_dbus_proxy_ref(proxy)); connman_device_set_ident(device, ident); g_hash_table_replace(devices, g_strdup(path), device); DBG("device %p %s device powered %d adapter powered %d", device, path, connman_device_get_powered(device), proxy_get_bool(proxy, "Powered")); if (connman_device_register(device) < 0) { g_hash_table_remove(devices, device); return; } g_dbus_proxy_set_property_watch(proxy, adapter_property_change, NULL); powered = proxy_get_bool(proxy, "Powered"); connman_device_set_powered(device, powered); if (proxy_get_role(proxy) && !bluetooth_tethering) tethering_create(path, NULL, NULL, false); }
static gboolean adapter_changed(DBusConnection *conn, DBusMessage *message, void *user_data) { const char *path = dbus_message_get_path(message); struct connman_device *device; DBusMessageIter iter, value; const char *key; DBG("path %s", path); device = g_hash_table_lookup(bluetooth_devices, path); if (device == NULL) return TRUE; if (dbus_message_iter_init(message, &iter) == FALSE) return TRUE; dbus_message_iter_get_basic(&iter, &key); dbus_message_iter_next(&iter); dbus_message_iter_recurse(&iter, &value); if (g_str_equal(key, "Powered") == TRUE) { dbus_bool_t val; dbus_message_iter_get_basic(&value, &val); connman_device_set_powered(device, val); if (val == TRUE) check_pending_networks(path); } else if (g_str_equal(key, "Discovering") == TRUE) { dbus_bool_t val; dbus_message_iter_get_basic(&value, &val); connman_device_set_scanning(device, val); } else if (g_str_equal(key, "Devices") == TRUE) { check_networks(&value); } return TRUE; }
static void device_enable_cb(const DBusError *error, void *user_data) { char *path = user_data; struct connman_device *device; GHashTableIter iter; gpointer key, value; device = g_hash_table_lookup(devices, path); if (device == NULL) { DBG("device already removed"); goto out; } if (dbus_error_is_set(error) == TRUE) { connman_warn("Bluetooth device %s not enabled %s", path, error->message); goto out; } DBG("device %p %s", device, path); connman_device_set_powered(device, TRUE); g_hash_table_iter_init(&iter, networks); while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { struct bluetooth_pan *pan = value; if (g_strcmp0(proxy_get_string(pan->btdevice_proxy, "Adapter"), path) == 0) { DBG("enable network %p", pan->network); pan_create_nap(pan); } } out: g_free(path); }
static void wifi_remove(struct connman_device *device) { struct wifi_data *wifi = connman_device_get_data(device); DBG("device %p wifi %p", device, wifi); if (wifi == NULL) return; iface_list = g_list_remove(iface_list, wifi); remove_networks(device, wifi); connman_device_set_powered(device, FALSE); connman_device_set_data(device, NULL); connman_device_unref(wifi->device); connman_rtnl_remove_watch(wifi->watch); g_supplicant_interface_set_data(wifi->interface, NULL); g_free(wifi->autoscan); g_free(wifi->identifier); g_free(wifi); }
static void adapter_properties_reply(DBusPendingCall *call, void *user_data) { char *path = user_data; struct connman_device *device; DBusMessage *reply; DBusMessageIter networks; const char *address = NULL, *name = NULL; dbus_bool_t powered = FALSE, scanning = FALSE; struct ether_addr addr; char ident[13]; DBG("path %s", path); reply = dbus_pending_call_steal_reply(call); if (path == NULL) goto done; extract_properties(reply, NULL, &address, &name, NULL, &powered, &scanning, NULL, &networks); if (address == NULL) goto done; if (g_strcmp0(address, "00:00:00:00:00:00") == 0) goto done; device = g_hash_table_lookup(bluetooth_devices, path); if (device != NULL) goto update; ether_aton_r(address, &addr); snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x", addr.ether_addr_octet[0], addr.ether_addr_octet[1], addr.ether_addr_octet[2], addr.ether_addr_octet[3], addr.ether_addr_octet[4], addr.ether_addr_octet[5]); device = connman_device_create("bluetooth_legacy", CONNMAN_DEVICE_TYPE_BLUETOOTH); if (device == NULL) goto done; g_hash_table_insert(bluetooth_devices, g_strdup(path), device); connman_device_set_ident(device, ident); connman_device_set_string(device, "Path", path); if (connman_device_register(device) < 0) { connman_device_unref(device); g_hash_table_remove(bluetooth_devices, path); goto done; } update: connman_device_set_string(device, "Address", address); connman_device_set_string(device, "Name", name); connman_device_set_string(device, "Path", path); connman_device_set_powered(device, powered); connman_device_set_scanning(device, scanning); if (powered == FALSE) { remove_device_networks(device); add_pending_networks(path, &networks); } else check_networks(&networks); done: dbus_message_unref(reply); dbus_pending_call_unref(call); }