Add support for Technologies and EnabledTechnologies properties
[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 "connman.h"
27
28 static GSList *notifier_list = NULL;
29
30 static gint compare_priority(gconstpointer a, gconstpointer b)
31 {
32         const struct connman_notifier *notifier1 = a;
33         const struct connman_notifier *notifier2 = b;
34
35         return notifier2->priority - notifier1->priority;
36 }
37
38 /**
39  * connman_notifier_register:
40  * @notifier: notifier module
41  *
42  * Register a new notifier module
43  *
44  * Returns: %0 on success
45  */
46 int connman_notifier_register(struct connman_notifier *notifier)
47 {
48         DBG("notifier %p name %s", notifier, notifier->name);
49
50         notifier_list = g_slist_insert_sorted(notifier_list, notifier,
51                                                         compare_priority);
52
53         return 0;
54 }
55
56 /**
57  * connman_notifier_unregister:
58  * @notifier: notifier module
59  *
60  * Remove a previously registered notifier module
61  */
62 void connman_notifier_unregister(struct connman_notifier *notifier)
63 {
64         DBG("notifier %p name %s", notifier, notifier->name);
65
66         notifier_list = g_slist_remove(notifier_list, notifier);
67 }
68
69 static void device_enabled(enum connman_device_type type,
70                                                 connman_bool_t enabled)
71 {
72         GSList *list;
73
74         DBG("type %d enabled %d", type, enabled);
75
76         for (list = notifier_list; list; list = list->next) {
77                 struct connman_notifier *notifier = list->data;
78
79                 if (notifier->device_enabled)
80                         notifier->device_enabled(type, enabled);
81         }
82 }
83
84 static void device_registered(enum connman_device_type type,
85                                                 connman_bool_t registered)
86 {
87         DBG("type %d registered %d", type, registered);
88 }
89
90 static const char *type2string(enum connman_device_type type)
91 {
92         switch (type) {
93         case CONNMAN_DEVICE_TYPE_UNKNOWN:
94         case CONNMAN_DEVICE_TYPE_MBM:
95         case CONNMAN_DEVICE_TYPE_HSO:
96         case CONNMAN_DEVICE_TYPE_NOZOMI:
97         case CONNMAN_DEVICE_TYPE_HUAWEI:
98         case CONNMAN_DEVICE_TYPE_NOVATEL:
99         case CONNMAN_DEVICE_TYPE_VENDOR:
100                 break;
101         case CONNMAN_DEVICE_TYPE_ETHERNET:
102                 return "ethernet";
103         case CONNMAN_DEVICE_TYPE_WIFI:
104                 return "wifi";
105         case CONNMAN_DEVICE_TYPE_WIMAX:
106                 return "wimax";
107         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
108                 return "bluetooth";
109         case CONNMAN_DEVICE_TYPE_GPS:
110                 return "gps";
111         }
112
113         return NULL;
114 }
115
116 static volatile gint registered[20];
117 static volatile gint enabled[20];
118
119 void __connman_notifier_device_type_list(gboolean powered,
120                                                 DBusMessageIter *iter)
121 {
122         int i;
123
124         for (i = 0; i < 10; i++) {
125                 const char *type = type2string(i);
126                 gint count;
127
128                 if (type == NULL)
129                         continue;
130
131                 if (powered == TRUE)
132                         count = g_atomic_int_get(&enabled[i]);
133                 else
134                         count = g_atomic_int_get(&registered[i]);
135
136                 if (count > 0)
137                         dbus_message_iter_append_basic(iter,
138                                                 DBUS_TYPE_STRING, &type);
139         }
140 }
141
142 void __connman_notifier_device_type_register(enum connman_device_type type)
143 {
144         DBG("type %d", type);
145
146         switch (type) {
147         case CONNMAN_DEVICE_TYPE_UNKNOWN:
148         case CONNMAN_DEVICE_TYPE_MBM:
149         case CONNMAN_DEVICE_TYPE_HSO:
150         case CONNMAN_DEVICE_TYPE_NOZOMI:
151         case CONNMAN_DEVICE_TYPE_HUAWEI:
152         case CONNMAN_DEVICE_TYPE_NOVATEL:
153         case CONNMAN_DEVICE_TYPE_VENDOR:
154                 return;
155         case CONNMAN_DEVICE_TYPE_ETHERNET:
156         case CONNMAN_DEVICE_TYPE_WIFI:
157         case CONNMAN_DEVICE_TYPE_WIMAX:
158         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
159         case CONNMAN_DEVICE_TYPE_GPS:
160                 if (g_atomic_int_exchange_and_add(&registered[type], 1) == 0)
161                         device_registered(type, TRUE);
162                 break;
163         }
164 }
165
166 void __connman_notifier_device_type_unregister(enum connman_device_type type)
167 {
168         DBG("type %d", type);
169
170         switch (type) {
171         case CONNMAN_DEVICE_TYPE_UNKNOWN:
172         case CONNMAN_DEVICE_TYPE_MBM:
173         case CONNMAN_DEVICE_TYPE_HSO:
174         case CONNMAN_DEVICE_TYPE_NOZOMI:
175         case CONNMAN_DEVICE_TYPE_HUAWEI:
176         case CONNMAN_DEVICE_TYPE_NOVATEL:
177         case CONNMAN_DEVICE_TYPE_VENDOR:
178                 return;
179         case CONNMAN_DEVICE_TYPE_ETHERNET:
180         case CONNMAN_DEVICE_TYPE_WIFI:
181         case CONNMAN_DEVICE_TYPE_WIMAX:
182         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
183         case CONNMAN_DEVICE_TYPE_GPS:
184                 if (g_atomic_int_dec_and_test(&registered[type]) == TRUE)
185                         device_registered(type, FALSE);
186                 break;
187         }
188 }
189
190 void __connman_notifier_device_type_increase(enum connman_device_type type)
191 {
192         DBG("type %d", type);
193
194         switch (type) {
195         case CONNMAN_DEVICE_TYPE_UNKNOWN:
196         case CONNMAN_DEVICE_TYPE_MBM:
197         case CONNMAN_DEVICE_TYPE_HSO:
198         case CONNMAN_DEVICE_TYPE_NOZOMI:
199         case CONNMAN_DEVICE_TYPE_HUAWEI:
200         case CONNMAN_DEVICE_TYPE_NOVATEL:
201         case CONNMAN_DEVICE_TYPE_VENDOR:
202                 return;
203         case CONNMAN_DEVICE_TYPE_ETHERNET:
204         case CONNMAN_DEVICE_TYPE_WIFI:
205         case CONNMAN_DEVICE_TYPE_WIMAX:
206         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
207         case CONNMAN_DEVICE_TYPE_GPS:
208                 if (g_atomic_int_exchange_and_add(&enabled[type], 1) == 0)
209                         device_enabled(type, TRUE);
210                 break;
211         }
212 }
213
214 void __connman_notifier_device_type_decrease(enum connman_device_type type)
215 {
216         DBG("type %d", type);
217
218         switch (type) {
219         case CONNMAN_DEVICE_TYPE_UNKNOWN:
220         case CONNMAN_DEVICE_TYPE_MBM:
221         case CONNMAN_DEVICE_TYPE_HSO:
222         case CONNMAN_DEVICE_TYPE_NOZOMI:
223         case CONNMAN_DEVICE_TYPE_HUAWEI:
224         case CONNMAN_DEVICE_TYPE_NOVATEL:
225         case CONNMAN_DEVICE_TYPE_VENDOR:
226                 return;
227         case CONNMAN_DEVICE_TYPE_ETHERNET:
228         case CONNMAN_DEVICE_TYPE_WIFI:
229         case CONNMAN_DEVICE_TYPE_WIMAX:
230         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
231         case CONNMAN_DEVICE_TYPE_GPS:
232                 if (g_atomic_int_dec_and_test(&enabled[type]) == TRUE)
233                         device_enabled(type, FALSE);
234                 break;
235         }
236 }
237
238 void __connman_notifier_offline_mode(connman_bool_t enabled)
239 {
240         GSList *list;
241
242         DBG("enabled %d", enabled);
243
244         for (list = notifier_list; list; list = list->next) {
245                 struct connman_notifier *notifier = list->data;
246
247                 if (notifier->offline_mode)
248                         notifier->offline_mode(enabled);
249         }
250 }
251
252 int __connman_notifier_init(void)
253 {
254         DBG("");
255
256         return 0;
257 }
258
259 void __connman_notifier_cleanup(void)
260 {
261         DBG("");
262 }