Use one common service type to string conversion routine
[platform/upstream/connman.git] / src / notifier.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <gdbus.h>
27
28 #include "connman.h"
29
30 static DBusConnection *connection = NULL;
31
32 static GSList *notifier_list = NULL;
33
34 static gint compare_priority(gconstpointer a, gconstpointer b)
35 {
36         const struct connman_notifier *notifier1 = a;
37         const struct connman_notifier *notifier2 = b;
38
39         return notifier2->priority - notifier1->priority;
40 }
41
42 /**
43  * connman_notifier_register:
44  * @notifier: notifier module
45  *
46  * Register a new notifier module
47  *
48  * Returns: %0 on success
49  */
50 int connman_notifier_register(struct connman_notifier *notifier)
51 {
52         DBG("notifier %p name %s", notifier, notifier->name);
53
54         notifier_list = g_slist_insert_sorted(notifier_list, notifier,
55                                                         compare_priority);
56
57         return 0;
58 }
59
60 /**
61  * connman_notifier_unregister:
62  * @notifier: notifier module
63  *
64  * Remove a previously registered notifier module
65  */
66 void connman_notifier_unregister(struct connman_notifier *notifier)
67 {
68         DBG("notifier %p name %s", notifier, notifier->name);
69
70         notifier_list = g_slist_remove(notifier_list, notifier);
71 }
72
73 #define MAX_TECHNOLOGIES 10
74
75 static volatile gint registered[MAX_TECHNOLOGIES];
76 static volatile gint enabled[MAX_TECHNOLOGIES];
77 static volatile gint connected[MAX_TECHNOLOGIES];
78
79 void __connman_notifier_list_registered(DBusMessageIter *iter)
80 {
81         int i;
82
83         for (i = 0; i < 10; i++) {
84                 const char *type = __connman_service_type2string(i);
85
86                 if (type == NULL)
87                         continue;
88
89                 if (g_atomic_int_get(&registered[i]) > 0)
90                         dbus_message_iter_append_basic(iter,
91                                                 DBUS_TYPE_STRING, &type);
92         }
93 }
94
95 void __connman_notifier_list_enabled(DBusMessageIter *iter)
96 {
97         int i;
98
99         for (i = 0; i < 10; i++) {
100                 const char *type = __connman_service_type2string(i);
101
102                 if (type == NULL)
103                         continue;
104
105                 if (g_atomic_int_get(&enabled[i]) > 0)
106                         dbus_message_iter_append_basic(iter,
107                                                 DBUS_TYPE_STRING, &type);
108         }
109 }
110
111 void __connman_notifier_list_connected(DBusMessageIter *iter)
112 {
113         int i;
114
115         for (i = 0; i < 10; i++) {
116                 const char *type = __connman_service_type2string(i);
117
118                 if (type == NULL)
119                         continue;
120
121                 if (g_atomic_int_get(&connected[i]) > 0)
122                         dbus_message_iter_append_basic(iter,
123                                                 DBUS_TYPE_STRING, &type);
124         }
125 }
126
127 static void technology_registered(enum connman_service_type type,
128                                                 connman_bool_t registered)
129 {
130         DBusMessage *signal;
131         DBusMessageIter entry, value, iter;
132         const char *key = "AvailableTechnologies";
133
134         DBG("type %d registered %d", type, registered);
135
136         signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
137                                 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
138         if (signal == NULL)
139                 return;
140
141         dbus_message_iter_init_append(signal, &entry);
142
143         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
144
145         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
146                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
147                                                                 &value);
148
149         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
150                                         DBUS_TYPE_STRING_AS_STRING, &iter);
151         __connman_notifier_list_registered(&iter);
152         dbus_message_iter_close_container(&value, &iter);
153
154         dbus_message_iter_close_container(&entry, &value);
155
156         g_dbus_send_message(connection, signal);
157 }
158
159 static void technology_enabled(enum connman_service_type type,
160                                                 connman_bool_t enabled)
161 {
162         GSList *list;
163         DBusMessage *signal;
164         DBusMessageIter entry, value, iter;
165         const char *key = "EnabledTechnologies";
166
167         DBG("type %d enabled %d", type, enabled);
168
169         signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
170                                 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
171         if (signal == NULL)
172                 goto done;
173
174         dbus_message_iter_init_append(signal, &entry);
175
176         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
177
178         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
179                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
180                                                                 &value);
181
182         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
183                                         DBUS_TYPE_STRING_AS_STRING, &iter);
184         __connman_notifier_list_enabled(&iter);
185         dbus_message_iter_close_container(&value, &iter);
186
187         dbus_message_iter_close_container(&entry, &value);
188
189         g_dbus_send_message(connection, signal);
190
191 done:
192         for (list = notifier_list; list; list = list->next) {
193                 struct connman_notifier *notifier = list->data;
194
195                 if (notifier->service_enabled)
196                         notifier->service_enabled(type, enabled);
197         }
198 }
199
200 static void technology_connected(enum connman_service_type type,
201                                                 connman_bool_t connected)
202 {
203         DBusMessage *signal;
204         DBusMessageIter entry, value, iter;
205         const char *key = "ConnectedTechnologies";
206
207         DBG("type %d connected %d", type, connected);
208
209         signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
210                                 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
211         if (signal == NULL)
212                 return;
213
214         dbus_message_iter_init_append(signal, &entry);
215
216         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
217
218         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
219                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
220                                                                 &value);
221
222         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
223                                         DBUS_TYPE_STRING_AS_STRING, &iter);
224         __connman_notifier_list_connected(&iter);
225         dbus_message_iter_close_container(&value, &iter);
226
227         dbus_message_iter_close_container(&entry, &value);
228
229         g_dbus_send_message(connection, signal);
230 }
231
232 void __connman_notifier_register(enum connman_service_type type)
233 {
234         DBG("type %d", type);
235
236         switch (type) {
237         case CONNMAN_SERVICE_TYPE_UNKNOWN:
238                 return;
239         case CONNMAN_SERVICE_TYPE_ETHERNET:
240         case CONNMAN_SERVICE_TYPE_WIFI:
241         case CONNMAN_SERVICE_TYPE_WIMAX:
242         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
243         case CONNMAN_SERVICE_TYPE_CELLULAR:
244                 break;
245         }
246
247         if (g_atomic_int_exchange_and_add(&registered[type], 1) == 0)
248                 technology_registered(type, TRUE);
249 }
250
251 void __connman_notifier_unregister(enum connman_service_type type)
252 {
253         DBG("type %d", type);
254
255         switch (type) {
256         case CONNMAN_SERVICE_TYPE_UNKNOWN:
257                 return;
258         case CONNMAN_SERVICE_TYPE_ETHERNET:
259         case CONNMAN_SERVICE_TYPE_WIFI:
260         case CONNMAN_SERVICE_TYPE_WIMAX:
261         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
262         case CONNMAN_SERVICE_TYPE_CELLULAR:
263                 break;
264         }
265
266         if (g_atomic_int_dec_and_test(&registered[type]) == TRUE)
267                 technology_registered(type, FALSE);
268 }
269
270 void __connman_notifier_enable(enum connman_service_type type)
271 {
272         DBG("type %d", type);
273
274         switch (type) {
275         case CONNMAN_SERVICE_TYPE_UNKNOWN:
276                 return;
277         case CONNMAN_SERVICE_TYPE_ETHERNET:
278         case CONNMAN_SERVICE_TYPE_WIFI:
279         case CONNMAN_SERVICE_TYPE_WIMAX:
280         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
281         case CONNMAN_SERVICE_TYPE_CELLULAR:
282                 break;
283         }
284
285         if (g_atomic_int_exchange_and_add(&enabled[type], 1) == 0)
286                 technology_enabled(type, TRUE);
287 }
288
289 void __connman_notifier_disable(enum connman_service_type type)
290 {
291         DBG("type %d", type);
292
293         switch (type) {
294         case CONNMAN_SERVICE_TYPE_UNKNOWN:
295                 return;
296         case CONNMAN_SERVICE_TYPE_ETHERNET:
297         case CONNMAN_SERVICE_TYPE_WIFI:
298         case CONNMAN_SERVICE_TYPE_WIMAX:
299         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
300         case CONNMAN_SERVICE_TYPE_CELLULAR:
301                 break;
302         }
303
304         if (g_atomic_int_dec_and_test(&enabled[type]) == TRUE)
305                 technology_enabled(type, FALSE);
306 }
307
308 void __connman_notifier_connect(enum connman_service_type type)
309 {
310         DBG("type %d", type);
311
312         switch (type) {
313         case CONNMAN_SERVICE_TYPE_UNKNOWN:
314                 return;
315         case CONNMAN_SERVICE_TYPE_ETHERNET:
316         case CONNMAN_SERVICE_TYPE_WIFI:
317         case CONNMAN_SERVICE_TYPE_WIMAX:
318         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
319         case CONNMAN_SERVICE_TYPE_CELLULAR:
320                 break;
321         }
322
323         if (g_atomic_int_exchange_and_add(&connected[type], 1) == 0)
324                 technology_connected(type, TRUE);
325 }
326
327 void __connman_notifier_disconnect(enum connman_service_type type)
328 {
329         DBG("type %d", type);
330
331         switch (type) {
332         case CONNMAN_SERVICE_TYPE_UNKNOWN:
333                 return;
334         case CONNMAN_SERVICE_TYPE_ETHERNET:
335         case CONNMAN_SERVICE_TYPE_WIFI:
336         case CONNMAN_SERVICE_TYPE_WIMAX:
337         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
338         case CONNMAN_SERVICE_TYPE_CELLULAR:
339                 break;
340         }
341
342         if (g_atomic_int_dec_and_test(&connected[type]) == TRUE)
343                 technology_connected(type, FALSE);
344 }
345
346 static void offlinemode_changed(dbus_bool_t enabled)
347 {
348         DBusMessage *signal;
349         DBusMessageIter entry, value;
350         const char *key = "OfflineMode";
351
352         DBG("enabled %d", enabled);
353
354         signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
355                                 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
356         if (signal == NULL)
357                 return;
358
359         dbus_message_iter_init_append(signal, &entry);
360
361         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
362
363         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
364                                         DBUS_TYPE_BOOLEAN_AS_STRING, &value);
365         dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &enabled);
366         dbus_message_iter_close_container(&entry, &value);
367
368         g_dbus_send_message(connection, signal);
369 }
370
371 void __connman_notifier_offlinemode(connman_bool_t enabled)
372 {
373         GSList *list;
374
375         DBG("enabled %d", enabled);
376
377         __connman_profile_changed(FALSE);
378
379         offlinemode_changed(enabled);
380
381         for (list = notifier_list; list; list = list->next) {
382                 struct connman_notifier *notifier = list->data;
383
384                 if (notifier->offline_mode)
385                         notifier->offline_mode(enabled);
386         }
387 }
388
389 connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type)
390 {
391         DBG("type %d", type);
392
393         switch (type) {
394         case CONNMAN_SERVICE_TYPE_UNKNOWN:
395                 return FALSE;
396         case CONNMAN_SERVICE_TYPE_ETHERNET:
397         case CONNMAN_SERVICE_TYPE_WIFI:
398         case CONNMAN_SERVICE_TYPE_WIMAX:
399         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
400         case CONNMAN_SERVICE_TYPE_CELLULAR:
401                 break;
402         }
403
404         if (g_atomic_int_get(&enabled[type]) > 0)
405                 return TRUE;
406
407         return FALSE;
408 }
409
410 int __connman_notifier_init(void)
411 {
412         DBG("");
413
414         connection = connman_dbus_get_connection();
415
416         return 0;
417 }
418
419 void __connman_notifier_cleanup(void)
420 {
421         DBG("");
422
423         dbus_connection_unref(connection);
424 }