summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-01-25 07:14:11 +0100
committerMarcel Holtmann <marcel@holtmann.org>2010-01-25 07:14:11 +0100
commit32d267c1a6083f3f5183e5f3f15161b097f37419 (patch)
tree4de626ebde91e5104e02129d342a33c61206f47c
parentb5795c2b12e34ab29ad283b2ece3a507b17e3cb9 (diff)
downloadconnman-32d267c1a6083f3f5183e5f3f15161b097f37419.tar.gz
connman-32d267c1a6083f3f5183e5f3f15161b097f37419.tar.bz2
connman-32d267c1a6083f3f5183e5f3f15161b097f37419.zip
Add support for technology interface
-rw-r--r--Makefile.am2
-rw-r--r--doc/manager-api.txt4
-rw-r--r--doc/technology-api.txt34
-rw-r--r--include/dbus.h2
-rw-r--r--src/connman.h6
-rw-r--r--src/device.c15
-rw-r--r--src/manager.c5
-rw-r--r--src/technology.c265
-rwxr-xr-xtest/list-devices34
-rwxr-xr-xtest/monitor-manager2
-rwxr-xr-xtest/monitor-services2
-rwxr-xr-xtest/test-manager14
12 files changed, 349 insertions, 36 deletions
diff --git a/Makefile.am b/Makefile.am
index ce348ed6..15b41a6f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,7 +153,7 @@ EXTRA_DIST += doc/overview-api.txt doc/behavior-api.txt \
doc/ipconfig-api.txt doc/plugin-api.txt \
doc/manager-api.txt doc/agent-api.txt \
doc/profile-api.txt doc/service-api.txt \
- doc/counter-api.txt \
+ doc/technology-api.txt doc/counter-api.txt \
doc/device-lowlevel-api.txt \
doc/network-lowlevel-api.txt \
doc/advanced-configuration.txt
diff --git a/doc/manager-api.txt b/doc/manager-api.txt
index 1ba0480c..c8989353 100644
--- a/doc/manager-api.txt
+++ b/doc/manager-api.txt
@@ -187,9 +187,9 @@ Properties string State [readonly]
List of profile object paths.
- array{object} Devices [readonly]
+ array{object} Technologies [readonly]
- List of device object paths.
+ List of technology object paths.
array{object} Services [readonly]
diff --git a/doc/technology-api.txt b/doc/technology-api.txt
new file mode 100644
index 00000000..9b10c583
--- /dev/null
+++ b/doc/technology-api.txt
@@ -0,0 +1,34 @@
+Technology hierarchy
+====================
+
+Service org.moblin.connman
+Interface org.moblin.connman.Technology
+Object path [variable prefix]/{technology0,technology1,...}
+
+Methods dict GetProperties()
+
+ Returns properties for the technology object. See
+ the properties section for available properties.
+
+ Possible Errors: [service].Error.InvalidArguments
+
+Signals PropertyChanged(string name, variant value)
+
+ This signal indicates a changed value of the given
+ property.
+
+Properties string Name [readonly]
+
+ Name of this technology.
+
+ string Type [readonly]
+
+ The technology type (for example "ethernet" etc.)
+
+ This information should only be used to determine
+ advanced properties or showing the correct icon
+ to the user.
+
+ array{object} Devices [readonly]
+
+ List of device objects.
diff --git a/include/dbus.h b/include/dbus.h
index 36629dfb..2ff41b2a 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -29,6 +29,7 @@ extern "C" {
#endif
#define CONNMAN_SERVICE "org.moblin.connman"
+#define CONNMAN_PATH "/org/moblin/connman"
#define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug"
#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
@@ -44,6 +45,7 @@ extern "C" {
#define CONNMAN_DEVICE_INTERFACE CONNMAN_SERVICE ".Device"
#define CONNMAN_NETWORK_INTERFACE CONNMAN_SERVICE ".Network"
#define CONNMAN_PROVIDER_INTERFACE CONNMAN_SERVICE ".Provider"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
typedef void (* connman_dbus_append_cb_t) (DBusMessageIter *iter,
void *user_data);
diff --git a/src/connman.h b/src/connman.h
index a7040270..d399634d 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -269,6 +269,11 @@ connman_bool_t __connman_udev_get_blocked(int phyindex);
#include <connman/device.h>
+void __connman_technology_list(DBusMessageIter *iter, void *user_data);
+
+int __connman_technology_add_device(struct connman_device *device);
+int __connman_technology_remove_device(struct connman_device *device);
+
int __connman_device_init(void);
void __connman_device_cleanup(void);
@@ -282,7 +287,6 @@ void __connman_device_set_phyindex(struct connman_device *device,
int __connman_device_set_blocked(struct connman_device *device,
connman_bool_t blocked);
-
void __connman_device_increase_connections(struct connman_device *device);
void __connman_device_decrease_connections(struct connman_device *device);
diff --git a/src/device.c b/src/device.c
index 875b1972..c78e4219 100644
--- a/src/device.c
+++ b/src/device.c
@@ -478,13 +478,6 @@ static GDBusSignalTable device_signals[] = {
{ },
};
-static void emit_devices_signal(void)
-{
- connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "Devices",
- DBUS_TYPE_OBJECT_PATH, __connman_device_list, NULL);
-}
-
static int register_interface(struct connman_element *element)
{
struct connman_device *device = element->device;
@@ -501,8 +494,6 @@ static int register_interface(struct connman_element *element)
device->registered = TRUE;
- emit_devices_signal();
-
return 0;
}
@@ -514,8 +505,6 @@ static void unregister_interface(struct connman_element *element)
device->registered = FALSE;
- emit_devices_signal();
-
g_dbus_unregister_interface(connection, element->path,
CONNMAN_DEVICE_INTERFACE);
}
@@ -535,6 +524,8 @@ static int setup_device(struct connman_device *device)
return err;
}
+ __connman_technology_add_device(device);
+
type = __connman_device_get_service_type(device);
__connman_notifier_register(type);
@@ -596,6 +587,8 @@ static void remove_device(struct connman_device *device)
type = __connman_device_get_service_type(device);
__connman_notifier_unregister(type);
+ __connman_technology_remove_device(device);
+
unregister_interface(&device->element);
if (device->driver->remove)
diff --git a/src/manager.c b/src/manager.c
index 7b2f9963..141e9593 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -60,9 +60,8 @@ static DBusMessage *get_properties(DBusConnection *conn,
DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
connman_dbus_dict_append_array(&dict, "Providers",
DBUS_TYPE_OBJECT_PATH, __connman_provider_list, NULL);
-
- connman_dbus_dict_append_array(&dict, "Devices",
- DBUS_TYPE_OBJECT_PATH, __connman_device_list, NULL);
+ connman_dbus_dict_append_array(&dict, "Technologies",
+ DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
str = __connman_notifier_get_state();
connman_dbus_dict_append_basic(&dict, "State",
diff --git a/src/technology.c b/src/technology.c
index 6c460743..33fbc75b 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -23,16 +23,281 @@
#include <config.h>
#endif
+#include <gdbus.h>
+
#include "connman.h"
+static DBusConnection *connection;
+
+static GHashTable *device_table;
+static GSList *technology_list = NULL;
+
+struct connman_technology {
+ gint refcount;
+ enum connman_service_type type;
+ char *path;
+ GSList *device_list;
+};
+
+void __connman_technology_list(DBusMessageIter *iter, void *user_data)
+{
+ GSList *list;
+
+ for (list = technology_list; list; list = list->next) {
+ struct connman_technology *technology = list->data;
+
+ if (technology->path == NULL)
+ continue;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
+ &technology->path);
+ }
+}
+
+static void technologies_changed(void)
+{
+ connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "Technologies",
+ DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
+}
+
+static void device_list(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ GSList *list;
+
+ for (list = technology->device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+ const char *path;
+
+ path = connman_device_get_path(device);
+ if (path == NULL)
+ continue;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
+ &path);
+ }
+}
+
+static void devices_changed(struct connman_technology *technology)
+{
+ connman_dbus_property_changed_array(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE, "Devices",
+ DBUS_TYPE_OBJECT_PATH, device_list, technology);
+}
+
+static const char *get_name(enum connman_service_type type)
+{
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ break;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ return "Wired";
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ return "WiFi";
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ return "WiMAX";
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ return "Bluetooth";
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ return "3G";
+ }
+
+ return NULL;
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+ DBusMessage *message, void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ DBusMessage *reply;
+ DBusMessageIter array, dict;
+ const char *str;
+
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &array);
+
+ connman_dbus_dict_open(&array, &dict);
+
+ str = get_name(technology->type);
+ if (str != NULL)
+ connman_dbus_dict_append_basic(&dict, "Name",
+ DBUS_TYPE_STRING, &str);
+
+ str = __connman_service_type2string(technology->type);
+ if (str != NULL)
+ connman_dbus_dict_append_basic(&dict, "Type",
+ DBUS_TYPE_STRING, &str);
+
+ connman_dbus_dict_append_array(&dict, "Devices",
+ DBUS_TYPE_OBJECT_PATH, device_list, technology);
+
+ connman_dbus_dict_close(&array, &dict);
+
+ return reply;
+}
+
+static GDBusMethodTable technology_methods[] = {
+ { "GetProperties", "", "a{sv}", get_properties },
+ { },
+};
+
+static GDBusSignalTable technology_signals[] = {
+ { "PropertyChanged", "sv" },
+ { },
+};
+
+static struct connman_technology *technology_find(enum connman_service_type type)
+{
+ GSList *list;
+
+ DBG("type %d", type);
+
+ for (list = technology_list; list; list = list->next) {
+ struct connman_technology *technology = list->data;
+
+ if (technology->type == type)
+ return technology;
+ }
+
+ return NULL;
+}
+
+static struct connman_technology *technology_get(enum connman_service_type type)
+{
+ static unsigned int counter = 0;
+ struct connman_technology *technology;
+
+ DBG("type %d", type);
+
+ technology = technology_find(type);
+ if (technology != NULL) {
+ g_atomic_int_inc(&technology->refcount);
+ goto done;
+ }
+
+ technology = g_try_new0(struct connman_technology, 1);
+ if (technology == NULL)
+ return NULL;
+
+ technology->refcount = 1;
+
+ technology->type = type;
+ technology->path = g_strdup_printf("%s/technology%d",
+ CONNMAN_PATH, counter++);
+
+ if (g_dbus_register_interface(connection, technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE,
+ technology_methods, technology_signals,
+ NULL, technology, NULL) == FALSE) {
+ connman_error("Failed to register %s", technology->path);
+ g_free(technology);
+ return NULL;
+ }
+
+ technology_list = g_slist_append(technology_list, technology);
+
+ technologies_changed();
+
+done:
+ DBG("technology %p", technology);
+
+ return technology;
+}
+
+static void technology_put(struct connman_technology *technology)
+{
+ DBG("technology %p", technology);
+
+ if (g_atomic_int_dec_and_test(&technology->refcount) == FALSE)
+ return;
+
+ technology_list = g_slist_remove(technology_list, technology);
+
+ technologies_changed();
+
+ g_dbus_unregister_interface(connection, technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE);
+
+ g_free(technology->path);
+ g_free(technology);
+}
+
+static void unregister_device(gpointer data)
+{
+ struct connman_technology *technology = data;
+
+ DBG("technology %p", technology);
+
+ technology_put(technology);
+}
+
+int __connman_technology_add_device(struct connman_device *device)
+{
+ struct connman_technology *technology;
+ enum connman_service_type type;
+
+ DBG("device %p", device);
+
+ type = __connman_device_get_service_type(device);
+
+ technology = technology_get(type);
+ if (technology == NULL)
+ return -ENXIO;
+
+ g_hash_table_insert(device_table, device, technology);
+
+ technology->device_list = g_slist_append(technology->device_list,
+ device);
+
+ devices_changed(technology);
+
+ return 0;
+}
+
+int __connman_technology_remove_device(struct connman_device *device)
+{
+ struct connman_technology *technology;
+
+ DBG("device %p", device);
+
+ technology = g_hash_table_lookup(device_table, device);
+ if (technology == NULL)
+ return -ENXIO;
+
+ technology->device_list = g_slist_remove(technology->device_list,
+ device);
+
+ devices_changed(technology);
+
+ g_hash_table_remove(device_table, device);
+
+ return 0;
+}
+
int __connman_technology_init(void)
{
DBG("");
+ connection = connman_dbus_get_connection();
+
+ device_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, unregister_device);
+
return 0;
}
void __connman_technology_cleanup(void)
{
DBG("");
+
+ g_hash_table_destroy(device_table);
+
+ dbus_connection_unref(connection);
}
diff --git a/test/list-devices b/test/list-devices
index 61d8bbcf..78c319b3 100755
--- a/test/list-devices
+++ b/test/list-devices
@@ -9,21 +9,27 @@ manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"),
properties = manager.GetProperties()
-for path in properties["Devices"]:
- device = dbus.Interface(bus.get_object("org.moblin.connman", path),
- "org.moblin.connman.Device")
+for path in properties["Technologies"]:
+ technology = dbus.Interface(bus.get_object("org.moblin.connman", path),
+ "org.moblin.connman.Technology")
- properties = device.GetProperties()
+ properties = technology.GetProperties()
- print "[ %s ]" % (path)
+ for path in properties["Devices"]:
+ device = dbus.Interface(bus.get_object("org.moblin.connman", path),
+ "org.moblin.connman.Device")
- for key in properties.keys():
- if key in ["Networks"]:
- val = ""
- for i in properties[key]:
- val += i + " "
- else:
- val = str(properties[key])
- print " %s = %s" % (key, val)
+ properties = device.GetProperties()
- print
+ print "[ %s ]" % (path)
+
+ for key in properties.keys():
+ if key in ["Networks"]:
+ val = ""
+ for i in properties[key]:
+ val += i + " "
+ else:
+ val = str(properties[key])
+ print " %s = %s" % (key, val)
+
+ print
diff --git a/test/monitor-manager b/test/monitor-manager
index a6192421..82ca805b 100755
--- a/test/monitor-manager
+++ b/test/monitor-manager
@@ -6,7 +6,7 @@ import dbus
import dbus.mainloop.glib
def property_changed(name, value):
- if name in ["Profiles", "Services", "Providers",
+ if name in ["Profiles", "Services", "Providers", "Technologies",
"Devices", "Networks"]:
val = "["
for i in value:
diff --git a/test/monitor-services b/test/monitor-services
index c435a34a..7d654471 100755
--- a/test/monitor-services
+++ b/test/monitor-services
@@ -10,7 +10,7 @@ def property_changed(name, value, path, interface):
ipath = path[path.rfind("/") + 1:]
if iface not in ["Service"]:
return
- if name in ["Profiles", "Services", "Providers",
+ if name in ["Profiles", "Services", "Providers", "Technologies",
"Devices", "Networks"]:
val = "["
for i in value:
diff --git a/test/test-manager b/test/test-manager
index a41d6570..6f9c2004 100755
--- a/test/test-manager
+++ b/test/test-manager
@@ -18,6 +18,8 @@ def print_properties(key, value):
interface = "org.moblin.connman.Service"
elif key == "Providers":
interface = "org.moblin.connman.Provider"
+ elif key == "Technologies":
+ interface = "org.moblin.connman.Technology"
else:
return
@@ -30,7 +32,8 @@ def print_properties(key, value):
properties = obj.GetProperties()
for key in properties.keys():
- if key in ["Networks", "Services", "Providers"]:
+ if key in ["Devices", "Networks", "Services",
+ "Providers", "Technologies"]:
continue
if key in ["Powered", "Scanning", "Connected",
@@ -46,6 +49,12 @@ def print_properties(key, value):
print " %s = %s" % (key, val)
+ if "Devices" in properties.keys():
+ list = ""
+ for path in properties["Devices"]:
+ val = str(path)
+ list = list + val[val.rfind("/") + 1:] + " "
+ print " Devices = [ %s]" % (list)
if "Networks" in properties.keys():
list = ""
for path in properties["Networks"]:
@@ -67,7 +76,8 @@ def print_properties(key, value):
for key in properties.keys():
- if key in ["Profiles", "Devices", "Services", "Providers"]:
+ if key in ["Profiles", "Devices", "Services", "Providers",
+ "Technologies"]:
print_properties(key, properties[key])
elif key in ["AvailableTechnologies", "EnabledTechnologies",
"ConnectedTechnologies",