5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 static DBusConnection *connection;
32 static GHashTable *device_table;
33 static GSList *technology_list = NULL;
35 struct connman_technology {
37 enum connman_service_type type;
42 void __connman_technology_list(DBusMessageIter *iter, void *user_data)
46 for (list = technology_list; list; list = list->next) {
47 struct connman_technology *technology = list->data;
49 if (technology->path == NULL)
52 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
57 static void technologies_changed(void)
59 connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
60 CONNMAN_MANAGER_INTERFACE, "Technologies",
61 DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
64 static void device_list(DBusMessageIter *iter, void *user_data)
66 struct connman_technology *technology = user_data;
69 for (list = technology->device_list; list; list = list->next) {
70 struct connman_device *device = list->data;
73 path = connman_device_get_path(device);
77 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
82 static void devices_changed(struct connman_technology *technology)
84 connman_dbus_property_changed_array(technology->path,
85 CONNMAN_TECHNOLOGY_INTERFACE, "Devices",
86 DBUS_TYPE_OBJECT_PATH, device_list, technology);
89 static const char *get_name(enum connman_service_type type)
92 case CONNMAN_SERVICE_TYPE_UNKNOWN:
93 case CONNMAN_SERVICE_TYPE_SYSTEM:
94 case CONNMAN_SERVICE_TYPE_GPS:
95 case CONNMAN_SERVICE_TYPE_VPN:
97 case CONNMAN_SERVICE_TYPE_ETHERNET:
99 case CONNMAN_SERVICE_TYPE_WIFI:
101 case CONNMAN_SERVICE_TYPE_WIMAX:
103 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
105 case CONNMAN_SERVICE_TYPE_CELLULAR:
112 static DBusMessage *get_properties(DBusConnection *conn,
113 DBusMessage *message, void *user_data)
115 struct connman_technology *technology = user_data;
117 DBusMessageIter array, dict;
120 reply = dbus_message_new_method_return(message);
124 dbus_message_iter_init_append(reply, &array);
126 connman_dbus_dict_open(&array, &dict);
128 str = get_name(technology->type);
130 connman_dbus_dict_append_basic(&dict, "Name",
131 DBUS_TYPE_STRING, &str);
133 str = __connman_service_type2string(technology->type);
135 connman_dbus_dict_append_basic(&dict, "Type",
136 DBUS_TYPE_STRING, &str);
138 connman_dbus_dict_append_array(&dict, "Devices",
139 DBUS_TYPE_OBJECT_PATH, device_list, technology);
141 connman_dbus_dict_close(&array, &dict);
146 static GDBusMethodTable technology_methods[] = {
147 { "GetProperties", "", "a{sv}", get_properties },
151 static GDBusSignalTable technology_signals[] = {
152 { "PropertyChanged", "sv" },
156 static struct connman_technology *technology_find(enum connman_service_type type)
160 DBG("type %d", type);
162 for (list = technology_list; list; list = list->next) {
163 struct connman_technology *technology = list->data;
165 if (technology->type == type)
172 static struct connman_technology *technology_get(enum connman_service_type type)
174 struct connman_technology *technology;
177 DBG("type %d", type);
179 technology = technology_find(type);
180 if (technology != NULL) {
181 g_atomic_int_inc(&technology->refcount);
185 str = __connman_service_type2string(type);
189 technology = g_try_new0(struct connman_technology, 1);
190 if (technology == NULL)
193 technology->refcount = 1;
195 technology->type = type;
196 technology->path = g_strdup_printf("%s/technology/%s",
199 if (g_dbus_register_interface(connection, technology->path,
200 CONNMAN_TECHNOLOGY_INTERFACE,
201 technology_methods, technology_signals,
202 NULL, technology, NULL) == FALSE) {
203 connman_error("Failed to register %s", technology->path);
208 technology_list = g_slist_append(technology_list, technology);
210 technologies_changed();
213 DBG("technology %p", technology);
218 static void technology_put(struct connman_technology *technology)
220 DBG("technology %p", technology);
222 if (g_atomic_int_dec_and_test(&technology->refcount) == FALSE)
225 technology_list = g_slist_remove(technology_list, technology);
227 technologies_changed();
229 g_dbus_unregister_interface(connection, technology->path,
230 CONNMAN_TECHNOLOGY_INTERFACE);
232 g_free(technology->path);
236 static void unregister_device(gpointer data)
238 struct connman_technology *technology = data;
240 DBG("technology %p", technology);
242 technology_put(technology);
245 int __connman_technology_add_device(struct connman_device *device)
247 struct connman_technology *technology;
248 enum connman_service_type type;
250 DBG("device %p", device);
252 type = __connman_device_get_service_type(device);
254 technology = technology_get(type);
255 if (technology == NULL)
258 g_hash_table_insert(device_table, device, technology);
260 technology->device_list = g_slist_append(technology->device_list,
263 devices_changed(technology);
268 int __connman_technology_remove_device(struct connman_device *device)
270 struct connman_technology *technology;
272 DBG("device %p", device);
274 technology = g_hash_table_lookup(device_table, device);
275 if (technology == NULL)
278 technology->device_list = g_slist_remove(technology->device_list,
281 devices_changed(technology);
283 g_hash_table_remove(device_table, device);
288 int __connman_technology_init(void)
292 connection = connman_dbus_get_connection();
294 device_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
295 NULL, unregister_device);
300 void __connman_technology_cleanup(void)
304 g_hash_table_destroy(device_table);
306 dbus_connection_unref(connection);