[PATCH] bluetooth: Remove Bluez 4.x support
by Patrik Flykt
Remove Bluez 4.x support as the 4.x versions have been discontinued
for quite some time already. Bluez 5.x versions have been supported
since ConnMan 1.11 and are actively maintained.
---
Makefile.plugins | 2 -
plugins/bluetooth_legacy.c | 1385 --------------------------------------------
2 files changed, 1387 deletions(-)
delete mode 100644 plugins/bluetooth_legacy.c
diff --git a/Makefile.plugins b/Makefile.plugins
index e90ad19..b01fd80 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -27,8 +27,6 @@ builtin_sources += plugins/wifi.c $(gsupplicant_sources)
endif
if BLUETOOTH
-builtin_modules += bluetooth_legacy
-builtin_sources += plugins/bluetooth_legacy.c
builtin_modules += bluetooth
builtin_sources += plugins/bluetooth.c
endif
diff --git a/plugins/bluetooth_legacy.c b/plugins/bluetooth_legacy.c
deleted file mode 100644
index 2d7a9e0..0000000
--- a/plugins/bluetooth_legacy.c
+++ /dev/null
@@ -1,1385 +0,0 @@
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netinet/ether.h>
-
-#include <gdbus.h>
-
-#define CONNMAN_API_SUBJECT_TO_CHANGE
-#include <connman/plugin.h>
-#include <connman/technology.h>
-#include <connman/device.h>
-#include <connman/inet.h>
-#include <connman/dbus.h>
-#include <connman/log.h>
-
-#define BLUEZ_SERVICE "org.bluez"
-#define BLUEZ_MANAGER_INTERFACE BLUEZ_SERVICE ".Manager"
-#define BLUEZ_ADAPTER_INTERFACE BLUEZ_SERVICE ".Adapter"
-#define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device"
-#define BLUEZ_NETWORK_INTERFACE BLUEZ_SERVICE ".Network"
-#define BLUEZ_NETWORK_SERVER BLUEZ_SERVICE ".NetworkServer"
-
-#define LIST_ADAPTERS "ListAdapters"
-#define ADAPTER_ADDED "AdapterAdded"
-#define ADAPTER_REMOVED "AdapterRemoved"
-#define DEVICE_REMOVED "DeviceRemoved"
-
-#define PROPERTY_CHANGED "PropertyChanged"
-#define GET_PROPERTIES "GetProperties"
-#define SET_PROPERTY "SetProperty"
-
-#define CONNECT "Connect"
-#define DISCONNECT "Disconnect"
-
-#define REGISTER "Register"
-#define UNREGISTER "Unregister"
-
-#define UUID_NAP "00001116-0000-1000-8000-00805f9b34fb"
-
-#define TIMEOUT 60000
-
-static DBusConnection *connection;
-
-static GHashTable *bluetooth_devices = NULL;
-static GHashTable *bluetooth_networks = NULL;
-static GHashTable *pending_networks = NULL;
-
-static int pan_probe(struct connman_network *network)
-{
- GHashTableIter iter;
- gpointer key, val;
-
- g_hash_table_iter_init(&iter, bluetooth_networks);
- while (g_hash_table_iter_next(&iter, &key, &val)) {
- struct connman_network *known = val;
-
- if (network != known)
- continue;
-
- DBG("network %p", network);
-
- return 0;
- }
-
- return -EOPNOTSUPP;
-}
-
-static void pan_remove(struct connman_network *network)
-{
- DBG("network %p", network);
-}
-
-static void connect_reply(DBusPendingCall *call, void *user_data)
-{
- char *path = user_data;
- struct connman_network *network;
- DBusMessage *reply;
- DBusError error;
- const char *interface = NULL;
- int index;
-
- network = g_hash_table_lookup(bluetooth_networks, path);
- if (!network)
- return;
-
- DBG("network %p", network);
-
- reply = dbus_pending_call_steal_reply(call);
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
-
- goto err;
- }
-
- if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING,
- &interface, DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set(&error)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- } else
- connman_error("Wrong arguments for connect");
- goto err;
- }
-
- if (!interface)
- goto err;
-
- DBG("interface %s", interface);
-
- index = connman_inet_ifindex(interface);
-
- connman_network_set_index(network, index);
-
- connman_network_set_connected(network, true);
-
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-
- return;
-err:
-
- connman_network_set_connected(network, false);
-
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-}
-
-static int pan_connect(struct connman_network *network)
-{
- const char *path = connman_network_get_string(network, "Path");
- const char *uuid = "nap";
- DBusMessage *message;
- DBusPendingCall *call;
-
- DBG("network %p", network);
-
- if (!path)
- return -EINVAL;
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
- BLUEZ_NETWORK_INTERFACE, CONNECT);
- if (!message)
- return -ENOMEM;
-
- dbus_message_set_auto_start(message, FALSE);
-
- dbus_message_append_args(message, DBUS_TYPE_STRING, &uuid,
- DBUS_TYPE_INVALID);
-
- if (!dbus_connection_send_with_reply(connection, message,
- &call, TIMEOUT * 10)) {
- connman_error("Failed to connect service");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- dbus_pending_call_set_notify(call, connect_reply, g_strdup(path),
- g_free);
-
- dbus_message_unref(message);
-
- return -EINPROGRESS;
-}
-
-static void disconnect_reply(DBusPendingCall *call, void *user_data)
-{
- char *path = user_data;
- struct connman_network *network;
- DBusMessage *reply;
- DBusError error;
-
- network = g_hash_table_lookup(bluetooth_networks, path);
- if (!network)
- return;
-
- DBG("network %p", network);
-
- reply = dbus_pending_call_steal_reply(call);
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- goto done;
- }
-
- if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set(&error)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- } else
- connman_error("Wrong arguments for disconnect");
- goto done;
- }
-
- connman_network_set_connected(network, false);
-
-done:
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-
- connman_network_unref(network);
-}
-
-static int pan_disconnect(struct connman_network *network)
-{
- const char *path = connman_network_get_string(network, "Path");
- DBusMessage *message;
- DBusPendingCall *call;
-
- DBG("network %p", network);
-
- if (!path)
- return -EINVAL;
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
- BLUEZ_NETWORK_INTERFACE, DISCONNECT);
- if (!message)
- return -ENOMEM;
-
- dbus_message_set_auto_start(message, FALSE);
-
- dbus_message_append_args(message, DBUS_TYPE_INVALID);
-
- if (!dbus_connection_send_with_reply(connection, message,
- &call, TIMEOUT)) {
- connman_error("Failed to disconnect service");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- connman_network_ref(network);
-
- connman_network_set_associating(network, false);
-
- dbus_pending_call_set_notify(call, disconnect_reply, g_strdup(path),
- g_free);
-
- dbus_message_unref(message);
-
- return 0;
-}
-
-static struct connman_network_driver pan_driver = {
- .name = "bluetooth_legacy-pan",
- .type = CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN,
- .priority = CONNMAN_NETWORK_PRIORITY_LOW,
- .probe = pan_probe,
- .remove = pan_remove,
- .connect = pan_connect,
- .disconnect = pan_disconnect,
-};
-
-static gboolean network_changed(DBusConnection *conn,
- DBusMessage *message, void *user_data)
-{
- const char *path = dbus_message_get_path(message);
- struct connman_network *network;
- DBusMessageIter iter, value;
- const char *key;
-
- DBG("path %s", path);
-
- network = g_hash_table_lookup(bluetooth_networks, path);
- if (!network)
- return TRUE;
-
- if (!dbus_message_iter_init(message, &iter))
- 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, "Connected")) {
- dbus_bool_t connected;
-
- dbus_message_iter_get_basic(&value, &connected);
-
- if (connected)
- return TRUE;
-
- connman_network_set_associating(network, false);
- connman_network_set_connected(network, false);
- }
-
- return TRUE;
-}
-
-static void extract_properties(DBusMessage *reply, const char **parent,
- const char **address,
- const char **name,
- const char **alias,
- dbus_bool_t *powered,
- dbus_bool_t *scanning,
- DBusMessageIter *uuids,
- DBusMessageIter *networks)
-{
- DBusMessageIter array, dict;
-
- if (!dbus_message_iter_init(reply, &array))
- return;
-
- if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
- return;
-
- dbus_message_iter_recurse(&array, &dict);
-
- while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter entry, value;
- const char *key;
-
- dbus_message_iter_recurse(&dict, &entry);
- dbus_message_iter_get_basic(&entry, &key);
-
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &value);
-
- if (g_str_equal(key, "Adapter")) {
- if (parent)
- dbus_message_iter_get_basic(&value, parent);
- } else if (g_str_equal(key, "Address")) {
- if (address)
- dbus_message_iter_get_basic(&value, address);
- } else if (g_str_equal(key, "Name")) {
- if (name)
- dbus_message_iter_get_basic(&value, name);
- } else if (g_str_equal(key, "Alias")) {
- if (alias)
- dbus_message_iter_get_basic(&value, alias);
- } else if (g_str_equal(key, "Powered")) {
- if (powered)
- dbus_message_iter_get_basic(&value, powered);
- } else if (g_str_equal(key, "Discovering")) {
- if (scanning)
- dbus_message_iter_get_basic(&value, scanning);
- } else if (g_str_equal(key, "Devices")) {
- if (networks)
- memcpy(networks, &value, sizeof(value));
- } else if (g_str_equal(key, "UUIDs")) {
- if (uuids)
- memcpy(uuids, &value, sizeof(value));
- }
-
- dbus_message_iter_next(&dict);
- }
-}
-
-static dbus_bool_t has_pan(DBusMessageIter *array)
-{
- DBusMessageIter value;
-
- if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
- return FALSE;
-
- dbus_message_iter_recurse(array, &value);
-
- while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) {
- const char *uuid;
-
- dbus_message_iter_get_basic(&value, &uuid);
-
- if (g_strcmp0(uuid, UUID_NAP) == 0)
- return TRUE;
-
- dbus_message_iter_next(&value);
- }
-
- return FALSE;
-}
-
-static void network_properties_reply(DBusPendingCall *call, void *user_data)
-{
- char *path = user_data;
- struct connman_device *device;
- struct connman_network *network;
- DBusMessage *reply;
- DBusMessageIter uuids;
- const char *parent = NULL, *address = NULL, *name = NULL;
- struct ether_addr addr;
- char ident[13];
-
- reply = dbus_pending_call_steal_reply(call);
-
- extract_properties(reply, &parent, &address, NULL, &name,
- NULL, NULL, &uuids, NULL);
-
- if (!parent)
- goto done;
-
- device = g_hash_table_lookup(bluetooth_devices, parent);
- if (!device)
- goto done;
-
- if (!address)
- goto done;
-
- 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]);
-
- if (!has_pan(&uuids))
- goto done;
-
- network = connman_device_get_network(device, ident);
- if (network)
- goto done;
-
- network = connman_network_create(ident,
- CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN);
- if (!network)
- goto done;
-
- connman_network_set_string(network, "Path", path);
-
- connman_network_set_name(network, name);
-
- g_hash_table_replace(bluetooth_networks, g_strdup(path), network);
-
- connman_device_add_network(device, network);
-
- connman_network_set_group(network, ident);
-
-done:
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-}
-
-static void add_network(const char *path)
-{
- DBusMessage *message;
- DBusPendingCall *call;
-
- DBG("path %s", path);
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
- BLUEZ_DEVICE_INTERFACE, GET_PROPERTIES);
- if (!message)
- return;
-
- dbus_message_set_auto_start(message, FALSE);
-
- if (!dbus_connection_send_with_reply(connection, message,
- &call, TIMEOUT)) {
- connman_error("Failed to get network properties for %s", path);
- goto done;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- goto done;
- }
-
- dbus_pending_call_set_notify(call, network_properties_reply,
- g_strdup(path), g_free);
-
-done:
- dbus_message_unref(message);
-}
-
-static void check_networks(DBusMessageIter *array)
-{
- DBusMessageIter value;
-
- if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
- return;
-
- dbus_message_iter_recurse(array, &value);
-
- while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
- const char *path;
-
- dbus_message_iter_get_basic(&value, &path);
-
- add_network(path);
-
- dbus_message_iter_next(&value);
- }
-}
-
-static void check_pending_networks(const char *adapter)
-{
- GSList *networks, *list;
-
- networks = g_hash_table_lookup(pending_networks, adapter);
- if (!networks)
- return;
-
- for (list = networks; list; list = list->next) {
- char *path = list->data;
-
- add_network(path);
- }
-
- g_hash_table_remove(pending_networks, adapter);
-}
-
-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)
- return TRUE;
-
- if (!dbus_message_iter_init(message, &iter))
- 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")) {
- dbus_bool_t val;
-
- dbus_message_iter_get_basic(&value, &val);
- connman_device_set_powered(device, val);
- if (val)
- check_pending_networks(path);
- } else if (g_str_equal(key, "Discovering")) {
- dbus_bool_t val;
-
- dbus_message_iter_get_basic(&value, &val);
- connman_device_set_scanning(device,
- CONNMAN_SERVICE_TYPE_BLUETOOTH, val);
- } else if (g_str_equal(key, "Devices")) {
- check_networks(&value);
- }
-
- return TRUE;
-}
-
-static gboolean device_removed(DBusConnection *conn,
- DBusMessage *message, void *user_data)
-{
- const char *network_path;
- struct connman_network *network;
- struct connman_device *device;
- DBusMessageIter iter;
-
- DBG("");
-
- if (!dbus_message_iter_init(message, &iter))
- return TRUE;
-
- dbus_message_iter_get_basic(&iter, &network_path);
-
- network = g_hash_table_lookup(bluetooth_networks, network_path);
- if (!network)
- return TRUE;
-
- device = connman_network_get_device(network);
- if (!device)
- return TRUE;
-
- g_hash_table_remove(bluetooth_networks, network_path);
-
- return TRUE;
-}
-
-static gboolean device_changed(DBusConnection *conn,
- DBusMessage *message, void *user_data)
-{
- const char *path = dbus_message_get_path(message);
- DBusMessageIter iter, value;
- const char *key;
-
- DBG("path %s", path);
-
- if (!dbus_message_iter_init(message, &iter))
- return TRUE;
-
- dbus_message_iter_get_basic(&iter, &key);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &value);
-
- DBG("key %s", key);
-
- if (g_str_equal(key, "UUIDs"))
- add_network(path);
-
- return TRUE;
-}
-
-static void remove_device_networks(struct connman_device *device)
-{
- GHashTableIter iter;
- gpointer key, value;
- GSList *key_list = NULL;
- GSList *list;
-
- if (!bluetooth_networks)
- return;
-
- g_hash_table_iter_init(&iter, bluetooth_networks);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- struct connman_network *network = value;
-
- if (connman_network_get_device(network) != device)
- continue;
-
- key_list = g_slist_prepend(key_list, key);
- }
-
- for (list = key_list; list; list = list->next) {
- const char *network_path = list->data;
-
- g_hash_table_remove(bluetooth_networks, network_path);
- }
-
- g_slist_free(key_list);
-}
-
-static void add_pending_networks(const char *adapter, DBusMessageIter *array)
-{
- DBusMessageIter value;
- GSList *list = NULL;
-
- if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
- return;
-
- dbus_message_iter_recurse(array, &value);
-
- while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
- const char *path;
-
- dbus_message_iter_get_basic(&value, &path);
-
- list = g_slist_prepend(list, g_strdup(path));
-
- dbus_message_iter_next(&value);
- }
-
- if (!list)
- return;
-
- g_hash_table_replace(pending_networks, g_strdup(adapter), list);
-}
-
-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)
- goto done;
-
- extract_properties(reply, NULL, &address, &name, NULL,
- &powered, &scanning, NULL, &networks);
-
- if (!address)
- 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)
- 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)
- 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,
- CONNMAN_SERVICE_TYPE_BLUETOOTH, scanning);
-
- if (!powered) {
- remove_device_networks(device);
- add_pending_networks(path, &networks);
- } else
- check_networks(&networks);
-
-done:
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-}
-
-static void add_adapter(DBusConnection *conn, const char *path)
-{
- DBusMessage *message;
- DBusPendingCall *call;
-
- DBG("path %s", path);
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
- BLUEZ_ADAPTER_INTERFACE, GET_PROPERTIES);
- if (!message)
- return;
-
- dbus_message_set_auto_start(message, FALSE);
-
- if (!dbus_connection_send_with_reply(conn, message, &call, TIMEOUT)) {
- connman_error("Failed to get adapter properties for %s", path);
- goto done;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- goto done;
- }
-
- dbus_pending_call_set_notify(call, adapter_properties_reply,
- g_strdup(path), g_free);
-
-done:
- dbus_message_unref(message);
-}
-
-static gboolean adapter_added(DBusConnection *conn, DBusMessage *message,
- void *user_data)
-{
- const char *path;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
- add_adapter(conn, path);
- return TRUE;
-}
-
-static void remove_adapter(DBusConnection *conn, const char *path)
-{
- DBG("path %s", path);
-
- g_hash_table_remove(bluetooth_devices, path);
- g_hash_table_remove(pending_networks, path);
-}
-
-static gboolean adapter_removed(DBusConnection *conn, DBusMessage *message,
- void *user_data)
-{
- const char *path;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
- remove_adapter(conn, path);
- return TRUE;
-}
-
-static void list_adapters_reply(DBusPendingCall *call, void *user_data)
-{
- DBusMessage *reply;
- DBusError error;
- char **adapters;
- int i, num_adapters;
-
- DBG("");
-
- reply = dbus_pending_call_steal_reply(call);
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- goto done;
- }
-
- if (!dbus_message_get_args(reply, &error, DBUS_TYPE_ARRAY,
- DBUS_TYPE_OBJECT_PATH, &adapters,
- &num_adapters, DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set(&error)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- } else
- connman_error("Wrong arguments for adapter list");
- goto done;
- }
-
- for (i = 0; i < num_adapters; i++)
- add_adapter(connection, adapters[i]);
-
- g_strfreev(adapters);
-
-done:
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-}
-
-static void unregister_device(gpointer data)
-{
- struct connman_device *device = data;
-
- DBG("");
-
- remove_device_networks(device);
-
- connman_device_unregister(device);
- connman_device_unref(device);
-}
-
-static void remove_network(gpointer data)
-{
- struct connman_network *network = data;
- struct connman_device *device;
-
- DBG("network %p", network);
-
- device = connman_network_get_device(network);
- if (device)
- connman_device_remove_network(device, network);
-
- connman_network_unref(network);
-}
-
-static void remove_pending_networks(gpointer data)
-{
- GSList *list = data;
-
- g_slist_free_full(list, g_free);
-}
-
-static void bluetooth_connect(DBusConnection *conn, void *user_data)
-{
- DBusMessage *message;
- DBusPendingCall *call;
-
- DBG("connection %p", conn);
-
- bluetooth_devices = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, unregister_device);
-
- bluetooth_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, remove_network);
-
- pending_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, remove_pending_networks);
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, "/",
- BLUEZ_MANAGER_INTERFACE, LIST_ADAPTERS);
- if (!message)
- return;
-
- dbus_message_set_auto_start(message, FALSE);
-
- if (!dbus_connection_send_with_reply(conn, message, &call, TIMEOUT)) {
- connman_error("Failed to get Bluetooth adapters");
- goto done;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- goto done;
- }
-
- dbus_pending_call_set_notify(call, list_adapters_reply, NULL, NULL);
-
-done:
- dbus_message_unref(message);
-}
-
-static void bluetooth_disconnect(DBusConnection *conn, void *user_data)
-{
- DBG("connection %p", conn);
-
- if (!bluetooth_devices)
- return;
-
- g_hash_table_destroy(bluetooth_networks);
- bluetooth_networks = NULL;
- g_hash_table_destroy(bluetooth_devices);
- bluetooth_devices = NULL;
- g_hash_table_destroy(pending_networks);
- pending_networks = NULL;
-}
-
-static int bluetooth_probe(struct connman_device *device)
-{
- GHashTableIter iter;
- gpointer key, value;
-
- DBG("device %p", device);
-
- if (!bluetooth_devices)
- return -ENOTSUP;
-
- g_hash_table_iter_init(&iter, bluetooth_devices);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- struct connman_device *device_pan = value;
-
- if (device == device_pan)
- return 0;
- }
-
- return -ENOTSUP;
-}
-
-static void bluetooth_remove(struct connman_device *device)
-{
- DBG("device %p", device);
-}
-
-static void powered_reply(DBusPendingCall *call, void *user_data)
-{
- DBusError error;
- DBusMessage *reply;
-
- DBG("");
-
- reply = dbus_pending_call_steal_reply(call);
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- dbus_message_unref(reply);
- dbus_pending_call_unref(call);
- return;
- }
-
- dbus_message_unref(reply);
- dbus_pending_call_unref(call);
-
- add_adapter(connection, user_data);
-}
-
-static int change_powered(DBusConnection *conn, const char *path,
- dbus_bool_t powered)
-{
- DBusMessage *message;
- DBusMessageIter iter;
- DBusPendingCall *call;
-
- DBG("");
-
- if (!path)
- return -EINVAL;
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
- BLUEZ_ADAPTER_INTERFACE, SET_PROPERTY);
- if (!message)
- return -ENOMEM;
-
- dbus_message_set_auto_start(message, FALSE);
-
- dbus_message_iter_init_append(message, &iter);
- connman_dbus_property_append_basic(&iter, "Powered",
- DBUS_TYPE_BOOLEAN, &powered);
-
- if (!dbus_connection_send_with_reply(conn, message, &call, TIMEOUT)) {
- connman_error("Failed to change Powered property");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- dbus_pending_call_set_notify(call, powered_reply,
- g_strdup(path), g_free);
-
- dbus_message_unref(message);
-
- return -EINPROGRESS;
-}
-
-static int bluetooth_enable(struct connman_device *device)
-{
- const char *path = connman_device_get_string(device, "Path");
-
- DBG("device %p", device);
-
- return change_powered(connection, path, TRUE);
-}
-
-static int bluetooth_disable(struct connman_device *device)
-{
- const char *path = connman_device_get_string(device, "Path");
-
- DBG("device %p", device);
-
- return change_powered(connection, path, FALSE);
-}
-
-static struct connman_device_driver bluetooth_driver = {
- .name = "bluetooth_legacy",
- .type = CONNMAN_DEVICE_TYPE_BLUETOOTH,
- .probe = bluetooth_probe,
- .remove = bluetooth_remove,
- .enable = bluetooth_enable,
- .disable = bluetooth_disable,
-};
-
-static int tech_probe(struct connman_technology *technology)
-{
- return 0;
-}
-
-static void tech_remove(struct connman_technology *technology)
-{
-}
-
-static void server_register_reply(DBusPendingCall *call, void *user_data)
-{
- struct connman_technology *technology = user_data;
- DBusError error;
- DBusMessage *reply;
-
- DBG("");
-
- reply = dbus_pending_call_steal_reply(call);
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- dbus_message_unref(reply);
- dbus_pending_call_unref(call);
- return;
- }
-
- dbus_message_unref(reply);
- dbus_pending_call_unref(call);
-
- connman_technology_tethering_notify(technology, true);
-}
-
-static void server_unregister_reply(DBusPendingCall *call, void *user_data)
-{
- struct connman_technology *technology = user_data;
- DBusError error;
- DBusMessage *reply;
-
- DBG("");
-
- reply = dbus_pending_call_steal_reply(call);
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- dbus_message_unref(reply);
- dbus_pending_call_unref(call);
- return;
- }
-
- dbus_message_unref(reply);
- dbus_pending_call_unref(call);
-
- connman_technology_tethering_notify(technology, false);
-}
-
-
-static void server_register(const char *path, const char *uuid,
- struct connman_technology *technology,
- const char *bridge, bool enabled)
-{
- DBusMessage *message;
- DBusPendingCall *call;
- char *command;
-
- DBG("path %s enabled %d", path, enabled);
-
- command = enabled ? REGISTER : UNREGISTER;
-
- message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
- BLUEZ_NETWORK_SERVER, command);
- if (!message)
- return;
-
- dbus_message_set_auto_start(message, FALSE);
-
- dbus_message_append_args(message, DBUS_TYPE_STRING, &uuid,
- DBUS_TYPE_INVALID);
-
- if (enabled)
- dbus_message_append_args(message, DBUS_TYPE_STRING, &bridge,
- DBUS_TYPE_INVALID);
-
- if (!dbus_connection_send_with_reply(connection, message,
- &call, TIMEOUT)) {
- connman_error("Failed to enable PAN server");
- dbus_message_unref(message);
- return;
- }
-
- if (!call) {
- connman_error("D-Bus connection not available");
- dbus_message_unref(message);
- return;
- }
-
- if (enabled)
- dbus_pending_call_set_notify(call, server_register_reply,
- technology, NULL);
- else
- dbus_pending_call_set_notify(call, server_unregister_reply,
- technology, NULL);
-
- dbus_message_unref(message);
-}
-
-struct tethering_info {
- struct connman_technology *technology;
- const char *bridge;
-};
-
-static void enable_nap(gpointer key, gpointer value, gpointer user_data)
-{
- struct tethering_info *info = user_data;
- struct connman_device *device = value;
- const char *path;
-
- DBG("");
-
- path = connman_device_get_string(device, "Path");
-
- server_register(path, "nap", info->technology, info->bridge, true);
-}
-
-static void disable_nap(gpointer key, gpointer value, gpointer user_data)
-{
- struct tethering_info *info = user_data;
- struct connman_device *device = value;
- const char *path;
-
- DBG("");
-
- path = connman_device_get_string(device, "Path");
-
- server_register(path, "nap", info->technology, info->bridge, false);
-}
-
-static int tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
- const char *bridge, bool enabled)
-{
- struct tethering_info info = {
- .technology = technology,
- .bridge = bridge,
- };
-
- DBG("bridge %s", bridge);
-
- if (!bluetooth_devices)
- return -ENOTCONN;
-
- if (enabled)
- g_hash_table_foreach(bluetooth_devices, enable_nap, &info);
- else
- g_hash_table_foreach(bluetooth_devices, disable_nap, &info);
-
- return 0;
-}
-
-static struct connman_technology_driver tech_driver = {
- .name = "bluetooth_legacy",
- .type = CONNMAN_SERVICE_TYPE_BLUETOOTH,
- .priority = -10,
- .probe = tech_probe,
- .remove = tech_remove,
- .set_tethering = tech_set_tethering,
-};
-
-static guint watch;
-static guint added_watch;
-static guint removed_watch;
-static guint adapter_watch;
-static guint device_watch;
-static guint device_removed_watch;
-static guint network_watch;
-
-static int bluetooth_init(void)
-{
- int err;
-
- connection = connman_dbus_get_connection();
- if (!connection)
- return -EIO;
-
- watch = g_dbus_add_service_watch(connection, BLUEZ_SERVICE,
- bluetooth_connect, bluetooth_disconnect, NULL, NULL);
-
- added_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
- BLUEZ_MANAGER_INTERFACE,
- ADAPTER_ADDED, adapter_added,
- NULL, NULL);
-
- removed_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
- BLUEZ_MANAGER_INTERFACE,
- ADAPTER_REMOVED, adapter_removed,
- NULL, NULL);
-
- adapter_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE,
- NULL, BLUEZ_ADAPTER_INTERFACE,
- PROPERTY_CHANGED, adapter_changed,
- NULL, NULL);
-
- device_removed_watch = g_dbus_add_signal_watch(connection,
- BLUEZ_SERVICE, NULL,
- BLUEZ_ADAPTER_INTERFACE,
- DEVICE_REMOVED, device_removed,
- NULL, NULL);
-
- device_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
- BLUEZ_DEVICE_INTERFACE,
- PROPERTY_CHANGED, device_changed,
- NULL, NULL);
-
- network_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE,
- NULL, BLUEZ_NETWORK_INTERFACE,
- PROPERTY_CHANGED, network_changed,
- NULL, NULL);
-
- if (watch == 0 || added_watch == 0 || removed_watch == 0
- || adapter_watch == 0 || network_watch == 0
- || device_watch == 0
- || device_removed_watch == 0) {
- err = -EIO;
- goto remove;
- }
-
- err = connman_network_driver_register(&pan_driver);
- if (err < 0)
- goto remove;
-
- err = connman_device_driver_register(&bluetooth_driver);
- if (err < 0) {
- connman_network_driver_unregister(&pan_driver);
- goto remove;
- }
-
- err = connman_technology_driver_register(&tech_driver);
- if (err < 0) {
- connman_device_driver_unregister(&bluetooth_driver);
- connman_network_driver_unregister(&pan_driver);
- goto remove;
- }
-
- return 0;
-
-remove:
- g_dbus_remove_watch(connection, watch);
- g_dbus_remove_watch(connection, added_watch);
- g_dbus_remove_watch(connection, removed_watch);
- g_dbus_remove_watch(connection, adapter_watch);
- g_dbus_remove_watch(connection, device_removed_watch);
- g_dbus_remove_watch(connection, device_watch);
- g_dbus_remove_watch(connection, network_watch);
-
- dbus_connection_unref(connection);
-
- return err;
-}
-
-static void bluetooth_exit(void)
-{
- g_dbus_remove_watch(connection, watch);
- g_dbus_remove_watch(connection, added_watch);
- g_dbus_remove_watch(connection, removed_watch);
- g_dbus_remove_watch(connection, adapter_watch);
- g_dbus_remove_watch(connection, device_removed_watch);
- g_dbus_remove_watch(connection, device_watch);
- g_dbus_remove_watch(connection, network_watch);
-
- /*
- * We unset the disabling of the Bluetooth device when shutting down
- * so that non-PAN BT connections are not affected.
- */
- bluetooth_driver.disable = NULL;
-
- bluetooth_disconnect(connection, NULL);
-
- connman_technology_driver_unregister(&tech_driver);
-
- connman_device_driver_unregister(&bluetooth_driver);
- connman_network_driver_unregister(&pan_driver);
-
- dbus_connection_unref(connection);
-}
-
-CONNMAN_PLUGIN_DEFINE(bluetooth_legacy, "Bluetooth technology plugin (legacy)",
- VERSION, CONNMAN_PLUGIN_PRIORITY_LOW,
- bluetooth_init, bluetooth_exit)
--
2.1.4
6 years, 1 month
[RFC] Storage based service retrieval + removal
by MANIEZZO Marco (MM)
>-----Messaggio originale-----
>Da: Patrik Flykt [mailto:Patrik.Flykt@linux.intel.com]
>Inviato: lunedì 1 febbraio 2016 14:26
>A: Marcel Holtmann
>Cc: MANIEZZO Marco (MM); connman(a)lists.01.org
>Oggetto: Re: [RFC 1/2] Storage based service retrieval
>
>On Mon, 2016-02-01 at 14:18 +0100, Marcel Holtmann wrote:
>> calling Remove on an immutable service (provided by a .config)
>> essentially means resetting that service to its defaults. If that is
>> not working, then it is a bug.
>
>Ok, in this case the current implementation may (or may not) have a bug with Remove().
>
>Cheers,
>
>Patrik
Hello Patrick, Marcel,
Thank you for your feedback, I worked on the subject trying to follow your suggestions but keeping at minimum the modifications and resources usage.
Currently the services that are available (say visible Access Points for WiFi) are kept in the heap and they have an active DBUS path for methods and signals. I could add to these data structures also the services got from storage, for removal purposes mainly, but also for config methods like you mentioned. But I thought that I would waste memory doubling data related to services both available and stored.
Another solution could be to reuse the Favorite property of the service and keep in the heap these so they could be accessed by GetKnowServices but I saw too much logic change with related risks, in actual architecture in the mechanism to insert/remove of available services in/from heap.
Then I preferred to implement a solution that doesn’t touch the current logic on available service and does not introduce extra permanent allocated heap: the available services have their location in heap plus in the storage once they become favorite and saved services can be accessed only reading from storage. If they are also available some properties (like state) are read from heap structures. To be accessed by the DBUS I added them to it with a "_stored" appended to the path so to not confuse with their heap location, and DBUS path, that can be present or not, depending on availability or not. For now I have only supported the Remove method, but being services all the current methods can be extended to take care of them. So the user will get the list of available services with GetServices and the list of the stored services with GetKnownServices. On both the Remove method will apply, while the other methods will apply only on available ones.
The Remove method keeps current strategy where immutable services .config file is not touched; only the service folder and its content is deleted while heap info are re-provisioned from .config file implementing the requested "reset to its default". For mutable services like now it will clear heap data but it introduces the missing removal of the folder and its content, as well as "_stored" DBUS path.
The modifications showed no issues with valgrind, and 1000+ stored services did not show excessive lag.
You can find below the new modification, please let me know your comments.
Thanks and Regards,
Marco
client/commands.c | 13 ++
doc/connmanctl.1.in | 7 +
doc/manager-api.txt | 17 ++
doc/service-api.txt | 13 +-
include/provision.h | 4 +
src/config.c | 5 +
src/connman.h | 1 +
src/manager.c | 23 +++
src/service.c | 498 +++++++++++++++++++++++++++++++++++++++++++++-------
tools/manager-api.c | 33 ++++
10 files changed, 543 insertions(+), 71 deletions(-)
diff --git a/client/commands.c b/client/commands.c
index eec200f..f7941e2 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -348,6 +348,17 @@ static int object_properties(DBusMessageIter *iter,
return 0;
}
+static int cmd_known_services(char *args[], int num, struct connman_option *options)
+{
+if (num > 1)
+return -E2BIG;
+
+return __connmanctl_dbus_method_call(connection,
+CONNMAN_SERVICE, CONNMAN_PATH,
+"net.connman.Manager", "GetKnownServices",
+services_list, NULL, NULL, NULL);
+}
+
static int cmd_services(char *args[], int num, struct connman_option *options)
{
char *service_name = NULL;
@@ -2553,6 +2564,8 @@ static const struct {
lookup_tether },
{ "services", "[<service>]", service_options, cmd_services,
"Display services", lookup_service_arg },
+{ "known-services", NULL, NULL, cmd_known_services,
+ "Display known services", NULL },
{ "peers", "[peer]", NULL, cmd_peers,
"Display peers", lookup_peer_arg },
{ "scan", "<technology>", NULL, cmd_scan,
diff --git a/doc/connmanctl.1.in b/doc/connmanctl.1.in
index 0f891bd..2c6e569 100644
--- a/doc/connmanctl.1.in
+++ b/doc/connmanctl.1.in
@@ -12,6 +12,7 @@ SYNOPSIS
.BI tether \ technology\ \fRon|off\ |
.BI tether\fR\ wifi\ on|off\ ssid\ passphrase\fR\ |
.BR services \ [\fIservice\fR]\ |
+.BR known-services\fR\ |
.BI peers \ peer\fR\ |
.BI scan \ technology\fR\ |
.RI \fBconnect \ service | peer \ |
@@ -103,6 +104,12 @@ Only the service path (e.g. wifi_6834534139723_managed_none)
is accepted as a parameter.
.PP
.TP
+.B known-services
+Returns a sorted list of tuples with service object path and dictionary of service
+properties, for the known services (both mutable and immutable).
+This list will not contain sensitive information like passphrases etc.
+.PP
+.TP
.BI scan \ technology
Scans for new services on the given technology.
.PP
diff --git a/doc/manager-api.txt b/doc/manager-api.txt
index 31e137c..f2a2267 100644
--- a/doc/manager-api.txt
+++ b/doc/manager-api.txt
@@ -45,6 +45,23 @@ Methodsdict GetProperties()
and dictionary of peer properties
Possible Errors: [service].Error.InvalidArguments
+
+array{object,dict} GetKnownServices() [experimental]
+
+Returns a sorted list of tuples with service object
+path and dictionary of service properties, for the
+known services (both mutable and immutable).
+
+This list will not contain sensitive information
+like passphrases etc.
+
+The objects have a "_stored" appended to the path
+(e.g. wifi_6067208eac78_474f4c5045_managed_psk_stored)
+and the only available method of this kind of services
+is currently Remove, while the other Service methods
+will return error.
+
+Possible Errors: [service].Error.InvalidArguments
object ConnectProvider(dict provider)[deprecated]
diff --git a/doc/service-api.txt b/doc/service-api.txt
index e2e9e84..1e23072 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -94,11 +94,14 @@ Methodsdict GetProperties() [deprecated]
service is in the State=failure, this method can
also be used to reset the service.
-Calling this method on Ethernet devices, hidden WiFi
-services or provisioned services will cause an error
-message. It is not possible to remove these kind of
-services.
-
+Calling this method on Ethernet devices and hidden WiFi
+services will cause an error message. It is not possible
+to remove these kind ofservices.
+
+For the other services the removal will cause the
+deletion of their folder inSTORAGEDIR. Immutable
+services .config file will not be deleted.
+
Possible Errors: [service].Error.InvalidArguments
void MoveBefore(object service)
diff --git a/include/provision.h b/include/provision.h
index 3eb80a8..a497415 100644
--- a/include/provision.h
+++ b/include/provision.h
@@ -23,6 +23,7 @@
#define __CONNMAN_PROVISION_H
#include <stdbool.h>
+#include <connman/service.h>
#ifdef __cplusplus
extern "C" {
@@ -40,6 +41,9 @@ struct connman_config_entry {
void *ssid;
unsigned int ssid_len;
bool hidden;
+char *config_ident;
+char *config_entry;
+enum connman_service_security security;
};
int connman_config_provision_mutable_service(GKeyFile *keyfile);
diff --git a/src/config.c b/src/config.c
index 344b8ce..6e1151a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1575,6 +1575,9 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
entries[i]->ident = g_strdup(config->ident);
entries[i]->name = g_strdup(config->name);
+entries[i]->security = config->security;
+entries[i]->config_ident = g_strdup(config->config_ident);
+entries[i]->config_entry = g_strdup(config->config_entry);
entries[i]->ssid = g_try_malloc0(config->ssid_len + 1);
if (!entries[i]->ssid)
goto cleanup;
@@ -1617,6 +1620,8 @@ void connman_config_free_entries(struct connman_config_entry **entries)
g_free(entries[i]->ident);
g_free(entries[i]->name);
g_free(entries[i]->ssid);
+g_free(entries[i]->config_ident);
+g_free(entries[i]->config_entry);
g_free(entries[i]);
}
diff --git a/src/connman.h b/src/connman.h
index 447bdd7..041b191 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -654,6 +654,7 @@ int __connman_service_init(void);
void __connman_service_cleanup(void);
int __connman_service_load_modifiable(struct connman_service *service);
+void __connman_known_service_list_struct(DBusMessageIter *iter);
void __connman_service_list_struct(DBusMessageIter *iter);
int __connman_service_compare(const struct connman_service *a,
diff --git a/src/manager.c b/src/manager.c
index d15ce20..1f59644 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -175,6 +175,11 @@ static struct connman_notifier technology_notifier = {
.idle_state= idle_state,
};
+static void append_known_service_structs(DBusMessageIter *iter, void *user_data)
+{
+__connman_known_service_list_struct(iter);
+}
+
static void append_service_structs(DBusMessageIter *iter, void *user_data)
{
__connman_service_list_struct(iter);
@@ -195,6 +200,21 @@ static DBusMessage *get_services(DBusConnection *conn,
return reply;
}
+static DBusMessage *get_known_services(DBusConnection *conn,
+DBusMessage *msg, void *data)
+{
+DBusMessage *reply;
+
+reply = dbus_message_new_method_return(msg);
+if (!reply)
+return NULL;
+
+__connman_dbus_append_objpath_dict_array(reply,
+append_known_service_structs, NULL);
+
+return reply;
+}
+
static void append_peer_structs(DBusMessageIter *iter, void *user_data)
{
__connman_peer_list_struct(iter);
@@ -513,6 +533,9 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_DEPRECATED_METHOD("RemoveProvider",
GDBUS_ARGS({ "provider", "o" }), NULL,
remove_provider) },
+{ GDBUS_METHOD("GetKnownServices",
+NULL, GDBUS_ARGS({ "knownServices", "a(oa{sv})" }),
+get_known_services) },
{ GDBUS_METHOD("GetServices",
NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
get_services) },
diff --git a/src/service.c b/src/service.c
index a93aebf..b04afba 100644
--- a/src/service.c
+++ b/src/service.c
@@ -34,7 +34,7 @@
#include <connman/storage.h>
#include <connman/setting.h>
#include <connman/agent.h>
-
+#include <connman/provision.h>
#include "connman.h"
#define CONNECT_TIMEOUT120
@@ -49,6 +49,11 @@ static unsigned int vpn_autoconnect_timeout = 0;
static struct connman_service *current_default = NULL;
static bool services_dirty = false;
+struct provision_user_data {
+const char *ident;
+int ret;
+};
+
struct connman_stats {
bool valid;
bool enabled;
@@ -127,6 +132,12 @@ struct connman_service {
char *config_entry;
};
+static void service_free_data(struct connman_service *service);
+
+static void provision_changed(gpointer value, gpointer user_data);
+
+static void service_free(gpointer user_data);
+
static bool allow_property_changed(struct connman_service *service);
static struct connman_ipconfig *create_ip4config(struct connman_service *service,
@@ -589,6 +600,20 @@ static int service_load(struct connman_service *service)
service->hidden_service = g_key_file_get_boolean(keyfile,
service->identifier, "Hidden", NULL);
+str = g_key_file_get_string(keyfile,
+service->identifier, "Config.ident", NULL);
+if (str) {
+g_free(service->config_entry);
+service->config_entry = str;
+}
+
+str = g_key_file_get_string(keyfile,
+service->identifier, "Config.file", NULL);
+if (str) {
+g_free(service->config_file);
+service->config_file = str;
+}
+
done:
g_key_file_free(keyfile);
@@ -4085,7 +4110,7 @@ bool __connman_service_remove(struct connman_service *service)
service->type == CONNMAN_SERVICE_TYPE_GADGET)
return false;
-if (service->immutable || service->hidden ||
+if (service->hidden ||
__connman_provider_is_immutable(service->provider))
return false;
@@ -4095,6 +4120,12 @@ bool __connman_service_remove(struct connman_service *service)
__connman_service_disconnect(service);
+/* in case of immutable service don't touch data, it will be
+ * re-provisioned from .config file by __connman_known_service_remove
+ */
+if (service->immutable)
+return(true);
+
g_free(service->passphrase);
service->passphrase = NULL;
@@ -4118,17 +4149,118 @@ bool __connman_service_remove(struct connman_service *service)
service_save(service);
+return(true);
+}
+
+bool __connman_known_service_remove(struct connman_service *service)
+{
+DBG("Removing %s", service->identifier);
+
+if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
+service->type == CONNMAN_SERVICE_TYPE_GADGET)
+{
+return false;
+}
+
+if (service->hidden ||
+__connman_provider_is_immutable(service->provider))
+{
+return false;
+}
+
+__connman_storage_remove_service(service->identifier);
+
+
+if (service->immutable == true && service->config_file)
+{/* force reprovision of immutable services */
+struct provision_user_data data = {
+.ident = service->config_file,
+.ret = 0,
+};
+
+provision_changed(service, &data);
+}
+
return true;
}
static DBusMessage *remove_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
-struct connman_service *service = user_data;
+struct connman_service *service = NULL;
+struct connman_service *available_service = NULL;
+char *available_service_path = NULL;
+gchar **service_ID_parts = NULL;
+gchar *identifier;
+int return_val = 0;
+
+if(user_data == NULL)
+{//if it is null then we are talking about a saved service
+service = connman_service_create();
+
+if(service != NULL)
+{
+service->path = g_strdup(dbus_message_get_path(msg));
+service_ID_parts = g_strsplit(service->path, "/", -1);
+identifier = g_strdup(service_ID_parts[g_strv_length(service_ID_parts)-1]);
+g_strfreev(service_ID_parts);
+service_ID_parts = g_strsplit(identifier, "_stored", -1);
+g_free(identifier);
+service->identifier = g_strdup(service_ID_parts[0]);
+g_strfreev(service_ID_parts);
+service_ID_parts = g_strsplit(service->identifier, "_", -1);
+service->type = __connman_service_string2type(service_ID_parts[0]);
+g_strfreev(service_ID_parts);
+
+/*get service from available service list, if present*/
+available_service_path = g_strconcat(CONNMAN_PATH, "/service/",service->identifier,NULL);
+available_service = find_service(available_service_path);
+g_free(available_service_path);
+
+if(available_service == NULL)
+{/*remove asked for a stored service not currently available*/
+
+/*retrieve mutable/immutable info*/
+if (-EIO == service_load(service) || (service->config_file != NULL && service->config_entry != NULL))
+service->immutable = true;
+
+/*remove from storage if present*/
+return_val = __connman_known_service_remove(service);
+
+/*once removed the _stored service must disappear from DBUS*/
+g_dbus_unregister_interface(connection, service->path, CONNMAN_SERVICE_INTERFACE);
+}
+else
+{/*remove asked for a stored service currently available*/
-DBG("service %p", service);
+/*disconnect + reset data in memory*/
+return_val = __connman_service_remove(available_service);
+
+/*remove from storage if present*/
+return_val &= __connman_known_service_remove(available_service);
+}
+}
+else
+return __connman_error_operation_aborted(msg);
+
+}
+else
+{/* remove asked for an available service*/
+service = user_data;
+DBG("service %p", service);
+
+/*disconnect + reset data*/
+return_val = __connman_service_remove(service);
+
+/*remove from storage if present*/
+return_val &= __connman_known_service_remove(service);
+}
+
+
+if(user_data == NULL)
+service_free_data(service);
-if (!__connman_service_remove(service))
+if (!return_val)
return __connman_error_not_supported(msg);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
@@ -4467,7 +4599,7 @@ static const GDBusMethodTable service_methods[] = {
GDBUS_ARGS({ "name", "s" }), NULL,
clear_property) },
{ GDBUS_ASYNC_METHOD("Connect", NULL, NULL,
- connect_service) },
+connect_service) },
{ GDBUS_METHOD("Disconnect", NULL, NULL,
disconnect_service) },
{ GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
@@ -4487,92 +4619,153 @@ static const GDBusSignalTable service_signals[] = {
{ },
};
-static void service_free(gpointer user_data)
-{
-struct connman_service *service = user_data;
-char *path = service->path;
-
-DBG("service %p", service);
-
-reply_pending(service, ENOENT);
-
-__connman_notifier_service_remove(service);
-service_schedule_removed(service);
-
-__connman_wispr_stop(service);
-stats_stop(service);
-service->path = NULL;
-
-if (path) {
-__connman_connection_update_gateway();
-
-g_dbus_unregister_interface(connection, path,
-CONNMAN_SERVICE_INTERFACE);
-g_free(path);
-}
+static void service_free_data(struct connman_service *service)
+{
+if(service->path != NULL)
+g_free(service->path);
-g_hash_table_destroy(service->counter_table);
+if(service->counter_table != NULL)
+g_hash_table_destroy(service->counter_table);
-if (service->network) {
+if (service->network != NULL) {
__connman_network_disconnect(service->network);
connman_network_unref(service->network);
service->network = NULL;
}
-if (service->provider)
+if (service->provider != NULL)
connman_provider_unref(service->provider);
-if (service->ipconfig_ipv4) {
+if (service->ipconfig_ipv4 != NULL) {
__connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
__connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
__connman_ipconfig_unref(service->ipconfig_ipv4);
service->ipconfig_ipv4 = NULL;
}
-if (service->ipconfig_ipv6) {
+if (service->ipconfig_ipv6 != NULL) {
__connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
__connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
__connman_ipconfig_unref(service->ipconfig_ipv6);
service->ipconfig_ipv6 = NULL;
}
-g_strfreev(service->timeservers);
-g_strfreev(service->timeservers_config);
-g_strfreev(service->nameservers);
-g_strfreev(service->nameservers_config);
-g_strfreev(service->nameservers_auto);
-g_strfreev(service->domains);
-g_strfreev(service->proxies);
-g_strfreev(service->excludes);
+if(service->timeservers != NULL)
+g_strfreev(service->timeservers);
-g_free(service->hostname);
-g_free(service->domainname);
-g_free(service->pac);
-g_free(service->name);
-g_free(service->passphrase);
-g_free(service->identifier);
-g_free(service->eap);
-g_free(service->identity);
-g_free(service->anonymous_identity);
-g_free(service->agent_identity);
-g_free(service->ca_cert_file);
-g_free(service->client_cert_file);
-g_free(service->private_key_file);
-g_free(service->private_key_passphrase);
-g_free(service->phase2);
-g_free(service->config_file);
-g_free(service->config_entry);
+if(service->timeservers_config != NULL)
+g_strfreev(service->timeservers_config);
+
+if(service->nameservers != NULL)
+g_strfreev(service->nameservers);
+
+if(service->nameservers_config != NULL)
+g_strfreev(service->nameservers_config);
+
+if(service->nameservers_auto != NULL)
+g_strfreev(service->nameservers_auto);
+
+if(service->domains != NULL)
+g_strfreev(service->domains);
-if (service->stats.timer)
+if(service->proxies != NULL)
+g_strfreev(service->proxies);
+
+if(service->excludes != NULL)
+g_strfreev(service->excludes);
+
+if(service->hostname != NULL)
+g_free(service->hostname);
+
+if(service->domainname != NULL)
+g_free(service->domainname);
+
+if(service->pac != NULL)
+g_free(service->pac);
+
+if(service->name != NULL)
+g_free(service->name);
+
+if(service->passphrase != NULL)
+g_free(service->passphrase);
+
+if(service->identifier != NULL)
+g_free(service->identifier);
+
+if(service->eap != NULL)
+g_free(service->eap);
+
+if(service->identity != NULL)
+g_free(service->identity);
+
+if(service->anonymous_identity != NULL)
+g_free(service->anonymous_identity);
+
+if(service->agent_identity != NULL)
+g_free(service->agent_identity);
+
+if(service->ca_cert_file != NULL)
+g_free(service->ca_cert_file);
+
+if(service->client_cert_file != NULL)
+g_free(service->client_cert_file);
+
+if(service->private_key_file != NULL)
+g_free(service->private_key_file);
+
+if(service->private_key_passphrase != NULL)
+g_free(service->private_key_passphrase);
+
+if(service->phase2 != NULL)
+g_free(service->phase2);
+
+if(service->config_file != NULL)
+g_free(service->config_file);
+
+if(service->config_entry != NULL)
+g_free(service->config_entry);
+
+if (service->stats.timer != NULL)
g_timer_destroy(service->stats.timer);
-if (service->stats_roaming.timer)
+
+if (service->stats_roaming.timer != NULL)
g_timer_destroy(service->stats_roaming.timer);
+if(service != NULL)
+g_free(service);
+}
+
+
+static void service_free(gpointer user_data)
+{
+struct connman_service *service = user_data;
+char *path = service->path;
+
+DBG("service %p", service);
+
+
+reply_pending(service, ENOENT);
+
+__connman_notifier_service_remove(service);
+service_schedule_removed(service);
+
+__connman_wispr_stop(service);
+stats_stop(service);
+
+
+if (path) {
+
+__connman_connection_update_gateway();
+
+g_dbus_unregister_interface(connection, path,
+CONNMAN_SERVICE_INTERFACE);
+}
+
if (current_default == service)
current_default = NULL;
-g_free(service);
+service_free_data(service);
}
static void stats_init(struct connman_service *service)
@@ -6195,10 +6388,7 @@ static struct connman_service *lookup_by_identifier(const char *identifier)
return g_hash_table_lookup(service_hash, identifier);
}
-struct provision_user_data {
-const char *ident;
-int ret;
-};
+
static void provision_changed(gpointer value, gpointer user_data)
{
@@ -7149,3 +7339,179 @@ void __connman_service_cleanup(void)
dbus_connection_unref(connection);
}
+
+static const GDBusMethodTable known_service_methods[] = {
+{ GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
+{ },
+};
+
+struct find_provision {
+char *provision;
+bool found;
+};
+
+static void find_provision(gpointer value, gpointer user_data)
+{
+gchar *current_provision = value;
+struct find_provision *data = user_data;
+
+if (data->found)
+return;
+
+if (g_strcmp0(current_provision, data->provision) == 0)
+data->found = true;
+}
+
+void __connman_known_service_list_struct(DBusMessageIter *iter)
+{
+gchar **services = NULL;
+gchar **service_ID_parts = NULL;
+gchar *provision_string = NULL;
+GSList *provisions_list = NULL;
+struct connman_config_entry **comman_config_entries;
+int i = 0, j = 0;
+struct connman_service *service = NULL;
+struct find_provision data = { .provision = NULL, .found = false };
+
+DBG("listing known services");
+
+services = connman_storage_get_services();
+if (services == NULL)
+return;
+
+for (i = 0; i < g_strv_length(services); i++)
+{
+service = connman_service_create();
+if (service == NULL)
+{
+connman_error("connman_service_create() allocation failed");
+return ;
+}
+
+service->identifier = g_strdup(services[i]);
+service_ID_parts = g_strsplit(services[i], "_", -1);
+
+if(service_ID_parts != NULL)
+{
+service->type = __connman_service_string2type(service_ID_parts[0]);
+service->path = g_strdup_printf("%s/service/%s", CONNMAN_PATH, service->identifier);
+if(service->type == CONNMAN_SERVICE_TYPE_WIFI)
+service->security = __connman_service_string2security(service_ID_parts[g_strv_length(service_ID_parts)-1]);
+
+if(service->path != NULL)
+{
+if(find_service(service->path) != NULL)
+{
+service->state = (find_service(service->path))->state;
+service->name = g_strdup((find_service(service->path))->name);
+service->autoconnect = (find_service(service->path))->autoconnect;
+service->favorite = (find_service(service->path))->favorite;
+}
+
+if (service_load(service) != 0)
+{
+connman_error("service_load() returned error");
+service_free_data(service);
+g_strfreev(service_ID_parts);
+g_strfreev(services);
+return;
+}
+
+/* save immutable ident and entry, if present, to be used later while
+ * adding immutable services*/
+if(service->config_entry != NULL && service->config_file != NULL)
+{
+provision_string = g_strdup_printf("%s%s",service->config_entry,service->config_file);
+
+if (provision_string != NULL)
+{
+provisions_list = g_slist_insert_sorted(provisions_list,
+g_strdup(provision_string),
+(GCompareFunc)strcmp);
+
+g_free(provision_string);
+provision_string = NULL;
+}
+}
+
+/* append "_stored" to the service path, to distinguish it from available services */
+g_free(service->path);
+service->path = g_strdup_printf("%s/service/%s_stored", CONNMAN_PATH, service->identifier);
+
+append_struct_service(iter, append_dict_properties, service);
+
+g_dbus_register_interface(connection, service->path,
+CONNMAN_SERVICE_INTERFACE,
+known_service_methods, NULL,
+NULL, NULL, NULL);
+}
+g_strfreev(service_ID_parts);
+}
+service_free_data(service);
+}
+g_strfreev(services);
+
+
+/* Now read the services provided of a .config file*/
+for(j=CONNMAN_SERVICE_TYPE_SYSTEM; j <MAX_CONNMAN_SERVICE_TYPES; j++)
+{
+comman_config_entries = connman_config_get_entries(__connman_service_type2string(j));
+for(i=0; comman_config_entries != NULL && comman_config_entries[i] != NULL; i++)
+{
+/*check we haven't already loaded it*/
+data.provision = g_strdup_printf("%s%s",
+comman_config_entries[i]->config_entry,
+comman_config_entries[i]->config_ident);
+data.found = false;
+g_slist_foreach(provisions_list, find_provision, &data);
+
+g_free(data.provision);
+
+if(!data.found)
+{
+service = connman_service_create();
+if (service == NULL)
+{
+connman_error("connman_service_create() allocation failed");
+connman_config_free_entries(comman_config_entries);
+g_slist_free_full(provisions_list, g_free);
+return ;
+}
+
+service->type = j;
+/*create an obj path for service, using unique fields */
+service->identifier = g_strdup_printf("%s_%s_%s",
+__connman_service_type2string(service->type),
+comman_config_entries[i]->config_ident,
+comman_config_entries[i]->config_entry);
+service->path = g_strdup_printf("%s/service/%s_stored", CONNMAN_PATH, service->identifier);
+if(find_service(service->path) != NULL)
+{
+service->state = (find_service(service->path))->state;
+service->security = (find_service(service->path))->security;
+service->name = g_strdup((find_service(service->path))->name);
+service->autoconnect = (find_service(service->path))->autoconnect;
+service->favorite = (find_service(service->path))->favorite;
+}
+else
+{
+service->security = comman_config_entries[i]->security;
+if(comman_config_entries[i]->name != NULL)
+service->name = g_strdup(comman_config_entries[i]->name);
+}
+
+append_struct_service(iter, append_dict_properties, service);
+
+g_dbus_register_interface(connection, service->path,
+CONNMAN_SERVICE_INTERFACE,
+known_service_methods, NULL,
+NULL, NULL, NULL);
+
+service_free_data(service);
+}
+}
+connman_config_free_entries(comman_config_entries);
+}
+
+g_slist_free_full(provisions_list, g_free);
+}
diff --git a/tools/manager-api.c b/tools/manager-api.c
index e082962..9e97f70 100644
--- a/tools/manager-api.c
+++ b/tools/manager-api.c
@@ -64,6 +64,39 @@ static DBusMessage *set_property(DBusConnection *connection,
return reply;
}
+DBusMessage *manager_get_known_services(DBusConnection *connection)
+{
+DBusMessage *message, *reply;
+DBusError error;
+
+message = dbus_message_new_method_call(CONNMAN_SERVICE,
+CONNMAN_MANAGER_PATH,
+CONNMAN_MANAGER_INTERFACE,
+"GetKnownServices");
+
+if (!message)
+return NULL;
+
+dbus_error_init(&error);
+
+reply = dbus_connection_send_with_reply_and_block(connection,
+message, -1, &error);
+if (!reply) {
+if (dbus_error_is_set(&error)) {
+LOG("%s", error.message);
+dbus_error_free(&error);
+} else {
+LOG("Failed to get known services");
+}
+dbus_message_unref(message);
+return NULL;
+}
+
+dbus_message_unref(message);
+
+return reply;
+}
+
DBusMessage *manager_get_services(DBusConnection *connection)
{
DBusMessage *message, *reply;
________________________________
VISITA IL NOSTRO NUOVO SITO WEB! - VISIT OUR NEW WEB SITE! www.magnetimarelli.com
Confidential Notice: This message - including its attachments - may contain proprietary, confidential and/or legally protected information and is intended solely for the use of the designated addressee(s) above. If you are not the intended recipient be aware that any downloading, copying, disclosure, distribution or use of the contents of the above information is strictly prohibited.
If you have received this communication by mistake, please forward the message back to the sender at the email address above, delete the message from all mailboxes and any other electronic storage medium and destroy all copies.
Disclaimer Notice: Internet communications cannot be guaranteed to be safe or error-free. Therefore we do not assure that this message is complete or accurate and we do not accept liability for any errors or omissions in the contents of this message.
6 years, 2 months
[PATCH] test: Correct format specifier used in printf for int and unsigned int
by Nishant Chaprana
---
tools/addr-test.c | 2 +-
tools/stats-tool.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/addr-test.c b/tools/addr-test.c
index 273ab02..5d53fa7 100644
--- a/tools/addr-test.c
+++ b/tools/addr-test.c
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
for (i = 0; i < 4; i++) {
len = (i + 1) * 8;
addr.s_addr = htonl(~(0xfffffffflu >> len));
- printf("prefixlen %-2u netmask %s\n", len, inet_ntoa(addr));
+ printf("prefixlen %-2d netmask %s\n", len, inet_ntoa(addr));
}
return 0;
diff --git a/tools/stats-tool.c b/tools/stats-tool.c
index b076478..f773413 100644
--- a/tools/stats-tool.c
+++ b/tools/stats-tool.c
@@ -277,9 +277,9 @@ static void stats_hdr_info(struct stats_file *file)
get_index(file, begin), hdr->begin);
printf(" end [%d] 0x%08x\n",
get_index(file, end), hdr->end);
- printf(" home [%d] 0x%08x\n",
+ printf(" home [%u] 0x%08x\n",
home_idx, hdr->home);
- printf(" roaming [%d] 0x%08x\n\n",
+ printf(" roaming [%u] 0x%08x\n\n",
roaming_idx, hdr->roaming);
--
1.9.1
6 years, 2 months
[PATCH] vpn: Add an optional configuration option to the VPN plugin for choosing the device type.
by Hendrik Donner
This allows to use virtual tap devices and removes the hardcoded default to
virtual tun devices.
Signed-off-by: Hendrik Donner <hendrik(a)rennod.org>
---
Only tested with OpenVPN. I have no idea if one of the other VPN plugins
would benefit from tap device support.
doc/connman-vpn-provider.config.5.in | 6 +++++-
doc/vpn-config-format.txt | 2 ++
vpn/plugins/openvpn.c | 2 +-
vpn/plugins/vpn.c | 18 ++++++++++++------
4 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/doc/connman-vpn-provider.config.5.in b/doc/connman-vpn-provider.config.5.in
index 5393260..c50fc46 100644
--- a/doc/connman-vpn-provider.config.5.in
+++ b/doc/connman-vpn-provider.config.5.in
@@ -48,12 +48,16 @@ VPN server IP address.
.BI Domain= domain
Domain name for the VPN service.
.TP
-The following field is optional:
+The following fields are optional:
.TP
.BI Networks= network / netmask / gateway [,...]
Networks behind the VPN. If all traffic should go through the VPN, this
field can be left out. The gateway can be left out. For IPv6 addresses,
only the prefix length is accepted as the netmask.
+.TP
+.BI DeviceType= tun \fR|\fB tap
+Whether the VPN should use a tun (OSI layer 3) or tap (OSI layer 2) device.
+Defaults to tun if omitted.
.SS OpenConnect
The following keys can be used for \fBopenconnect\fP(8) networks:
.TP
diff --git a/doc/vpn-config-format.txt b/doc/vpn-config-format.txt
index 1f5bac8..e33acfc 100644
--- a/doc/vpn-config-format.txt
+++ b/doc/vpn-config-format.txt
@@ -44,6 +44,8 @@ VPN related parameters (M = mandatory, O = optional):
is network/netmask/gateway. The gateway can be left out. (O)
Example: 192.168.100.0/24/10.1.0.1,192.168.200.0/255.255.255.0/10.1.0.2
For IPv6 addresses only prefix length is accepted like this 2001:db8::1/64
+- DeviceType: Whether the VPN should use a tun (OSI layer 3) or tap
+ (OSI layer 2) device. Value is "tun" (default) or "tap" (O)
OpenConnect VPN supports following options (see openconnect(8) for details):
Option name OpenConnect option Description
diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c
index 9ee5795..c920dc3 100644
--- a/vpn/plugins/openvpn.c
+++ b/vpn/plugins/openvpn.c
@@ -71,6 +71,7 @@ struct {
{ "OpenVPN.CompLZO", "--comp-lzo", 0 },
{ "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
{ "OpenVPN.ConfigFile", "--config", 1 },
+ { "DeviceType", "--dev-type", 1 },
};
struct nameserver_entry {
@@ -362,7 +363,6 @@ static int ov_connect(struct vpn_provider *provider,
connman_task_get_path(task));
connman_task_add_argument(task, "--dev", if_name);
- connman_task_add_argument(task, "--dev-type", "tun");
connman_task_add_argument(task, "--persist-tun", NULL);
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index 1b5af6e..a031c42 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -56,6 +56,7 @@ struct vpn_data {
unsigned int watch;
enum vpn_state state;
struct connman_task *task;
+ int tun_flags;
};
struct vpn_driver_data {
@@ -89,7 +90,7 @@ static int stop_vpn(struct vpn_provider *provider)
return 0;
memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
sprintf(ifr.ifr_name, "%s", data->if_name);
fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
@@ -335,7 +336,7 @@ static DBusMessage *vpn_notify(struct connman_task *task,
return NULL;
}
-static int vpn_create_tun(struct vpn_provider *provider)
+static int vpn_create_tun(struct vpn_provider *provider, int flags)
{
struct vpn_data *data = vpn_provider_get_data(provider);
struct ifreq ifr;
@@ -355,7 +356,7 @@ static int vpn_create_tun(struct vpn_provider *provider)
}
memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ ifr.ifr_flags = flags | IFF_NO_PI;
for (i = 0; i < 256; i++) {
sprintf(ifr.ifr_name, "vpn%d", i);
@@ -371,6 +372,7 @@ static int vpn_create_tun(struct vpn_provider *provider)
goto exist_err;
}
+ data->tun_flags = flags;
data->if_name = (char *)g_strdup(ifr.ifr_name);
if (!data->if_name) {
connman_error("Failed to allocate memory");
@@ -411,8 +413,8 @@ static int vpn_connect(struct vpn_provider *provider,
{
struct vpn_data *data = vpn_provider_get_data(provider);
struct vpn_driver_data *vpn_driver_data;
- const char *name;
- int ret = 0;
+ const char *name, *tun;
+ int ret = 0, tun_flags = IFF_TUN;
enum vpn_state state = VPN_STATE_UNKNOWN;
if (data)
@@ -460,7 +462,11 @@ static int vpn_connect(struct vpn_provider *provider,
}
if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
- ret = vpn_create_tun(provider);
+ tun = vpn_provider_get_string(provider, "DeviceType");
+ if (g_str_equal(tun, "tap")) {
+ tun_flags = IFF_TAP;
+ }
+ ret = vpn_create_tun(provider, tun_flags);
if (ret < 0)
goto exist_err;
}
--
2.7.0
6 years, 2 months
Add CAP_SYS_MODULE to CapabilityBoundingSet...
by Brian H. Anderson
I'm running connmand 1.31 on a 4.1.18 kernel started using systemd 215.
When attempting to establish a wifi tether, connman fails since it
cannot load the required kernel modules (iptables_init/iptables.c).
Adding CAP_SYS_MODULE to the systemd unit file CapabilityBoundingSet
declaration appears to fix the problem.
ba
6 years, 2 months
Re: [PATCH] Add AlwaysUseFallbackNameservers flag in the configuration file.
by Grant Erickson
On Feb 26, 2016, at 1:57 AM, connman-request(a)lists.01.org wrote:
> On Thu, 2016-02-25 at 10:52 -0800, wangfe-nestlabs wrote:
>> Background information.
>>
>> Connmand will not use fallback name servers when some name servers are
>> provided by DHCP reply. But in some cases, the ISP provided its own
>> name servers can?t be down, then DNS won?t work. So some requirement
>> is to use some fallback name severs such as 8.8.8.8, 8.8.4.4 for
>> backup.
>>
>> Add the option flag ?AlwaysUseFallbackNameservers?. Which it is
>> enabled, the fallback name servers are appended to name server list,
>> and will be used. The duplicate servers will be filtered out in the
>> __connman_service_nameserver_append.
>
> NACK. FallBackNameservers are just that, a list of servers to use when
> there are zero nameservers provided otherwise. Every service has already
> a Nameservers.Configuration attribute which takes precedence over the
> ones provided by DHCP.
Patrik,
It’s easy to see how this is done one-off, statically for a provision or via a per-service-specific configuration setting using Nameservers.Configuration.
However, what’s the recommended way to ensure that nameservers can be configured, via Nameservers.Configuration, and applied to all services, without regard to their technology type or the service name?
The use case here is that a particular ISP supplies DNS servers in DHCP. However, their DNS servers are notoriously flaky and non-responsive (i.e. failed average response rate is high). Consequently, given how conman’s DNS proxy functions, statically-configured servers are a stopgap guarantee that will work even when the DHCP-provided servers do not.
Best,
Grant
6 years, 2 months
Re: nftables
by Daniel Wagner
Hi,
On 02/22/2016 10:30 AM, Zheng, Wu wrote:
> Hi Tomasz Bursztyka and Daniel Wagner,
>
> We want to use nftable in our system.
Yes, it makes sense to abandon iptables.
> Do you have an plan to implement nftable in Connman?
Well, as I said i was playing with the idea to do it as spare time project.
> If so, do you have an plan when do upstream can implement the feature?
I was asking Tomasz on how to use nftables. nftables doesn't enforce any
policies on the chain/table structure such as iptables. So that is first
thing we have to figure out.
Probably, we should also discuss it with the systemd-netwokd guys.
cheers,
daniel
6 years, 2 months
[PATCH] gdhcp: use opened listening socket to send DHCP renew request
by Feng Wang
It fix DHCP ACK lost issue when doing DHCP renewal.
When doing DHCP renew, 2 sockets are opened. One is for
listening DHCP ACK, the other is for transmitting DHCP request
which is closed immediately after transmitting is done. But in
some cases, the socket is closed after the DHCP ACK is received.
The kernel will route the packet to the transmitting socket
because it has a better match result(dst ip/port etc). And the
packet was dropped when the socket was closed.
---
gdhcp/client.c | 6 ++++--
gdhcp/common.c | 57 +++++++++++++++++++++++++++++++++++----------------------
gdhcp/common.h | 2 +-
3 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/gdhcp/client.c b/gdhcp/client.c
index 3bf8cb2..ad587b1 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -502,7 +502,8 @@ static int send_request(GDHCPClient *dhcp_client)
if (dhcp_client->state == RENEWING)
return dhcp_send_kernel_packet(&packet,
dhcp_client->requested_ip, CLIENT_PORT,
- dhcp_client->server_ip, SERVER_PORT);
+ dhcp_client->server_ip, SERVER_PORT,
+ dhcp_client->listener_sockfd);
return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
INADDR_BROADCAST, SERVER_PORT,
@@ -526,7 +527,8 @@ static int send_release(GDHCPClient *dhcp_client,
dhcp_add_option_uint32(&packet, DHCP_SERVER_ID, server);
return dhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT,
- server, SERVER_PORT);
+ server, SERVER_PORT,
+ dhcp_client->listener_sockfd);
}
static gboolean ipv4ll_probe_timeout(gpointer dhcp_data);
diff --git a/gdhcp/common.c b/gdhcp/common.c
index f3d4677..c841a0a 100644
--- a/gdhcp/common.c
+++ b/gdhcp/common.c
@@ -626,46 +626,59 @@ int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port,
- uint32_t dest_ip, int dest_port)
+ uint32_t dest_ip, int dest_port, int openedfd)
{
struct sockaddr_in client;
- int fd, n, opt = 1;
+ int n, fd, ret, opt = 1;
enum {
DHCP_SIZE = sizeof(struct dhcp_packet) -
EXTEND_FOR_BUGGY_SERVERS,
};
- fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
- if (fd < 0)
- return -errno;
-
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
-
- memset(&client, 0, sizeof(client));
- client.sin_family = AF_INET;
- client.sin_port = htons(source_port);
- client.sin_addr.s_addr = htonl(source_ip);
- if (bind(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
- close(fd);
- return -errno;
+ if (openedfd < 0) {
+ /* no socket opened, open a new socket to tx the packet and close it */
+ fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
+ if (fd < 0)
+ return -errno;
+
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ memset(&client, 0, sizeof(client));
+ client.sin_family = AF_INET;
+ client.sin_port = htons(source_port);
+ client.sin_addr.s_addr = htonl(source_ip);
+ if (bind(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
+ ret = -errno;
+ close(fd);
+ return ret;
+ }
}
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(dest_port);
client.sin_addr.s_addr = htonl(dest_ip);
- if (connect(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
- close(fd);
- return -errno;
- }
- n = write(fd, dhcp_pkt, DHCP_SIZE);
+ if (openedfd < 0) {
+ if (connect(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
+ ret = -errno;
+ close(fd);
+ return ret;
+ }
- close(fd);
+ n = write(fd, dhcp_pkt, DHCP_SIZE);
+ ret = -errno;
+ close(fd);
+ } else {
+ /* Using existed socket to transmit the packet */
+ n = sendto(openedfd, dhcp_pkt, DHCP_SIZE, MSG_DONTWAIT,
+ (struct sockaddr *) &client, sizeof(client));
+ ret = -errno;
+ }
if (n < 0)
- return -errno;
+ return ret;
return n;
}
diff --git a/gdhcp/common.h b/gdhcp/common.h
index 75abc18..b92d214 100644
--- a/gdhcp/common.h
+++ b/gdhcp/common.h
@@ -209,7 +209,7 @@ int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len);
int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port,
- uint32_t dest_ip, int dest_port);
+ uint32_t dest_ip, int dest_port, int fd);
int dhcp_l3_socket(int port, const char *interface, int family);
int dhcp_recv_l3_packet(struct dhcp_packet *packet, int fd);
int dhcpv6_recv_l3_packet(struct dhcpv6_packet **packet, unsigned char *buf,
--
2.7.0.rc3.207.g0ac5344
6 years, 2 months
Delete STORAGEDIR folders when services are removed
by Marco Maniezzo
Hello,
currently when a service is removed (Remove d-bus method) some of its properties are cleared but its folder and files in STORAGEDIR are not deleted. This patch removes such data.
Immutable services have a .config file in STORAGEDIR, and if they have been connected at least once they also have the same folder of mutable services: the Remove method will delete the folder and force a re-provision of the service: this will act as a reset of the service to its default.
Regards,
Marco Maniezzo
6 years, 2 months