ipconfig: Removed obsolete parameter from __connman_ipconfig_set_config()
[platform/upstream/connman.git] / src / location.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  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 struct connman_location {
29         gint refcount;
30         struct connman_service *service;
31         enum connman_location_result result;
32
33         struct connman_location_driver *driver;
34         void *driver_data;
35 };
36
37 /**
38  * connman_location_ref:
39  * @location: Location structure
40  *
41  * Increase reference counter of location
42  */
43 struct connman_location *connman_location_ref(struct connman_location *location)
44 {
45         g_atomic_int_inc(&location->refcount);
46
47         return location;
48 }
49
50 /**
51  * connman_location_unref:
52  * @location: Location structure
53  *
54  * Decrease reference counter of location
55  */
56 void connman_location_unref(struct connman_location *location)
57 {
58         if (g_atomic_int_dec_and_test(&location->refcount) == FALSE)
59                 return;
60
61         if (location->driver) {
62                 location->driver->finish(location);
63                 location->driver = NULL;
64         }
65
66         g_free(location);
67 }
68
69 /**
70  * connman_location_get_type:
71  * @location: Location structure
72  *
73  * Get the service type of location
74  */
75 enum connman_service_type connman_location_get_type(struct connman_location *location)
76 {
77         if (location == NULL)
78                 return CONNMAN_SERVICE_TYPE_UNKNOWN;
79
80         return connman_service_get_type(location->service);
81 }
82
83 /**
84  * connman_location_get_interface:
85  * @location: location structure
86  *
87  * Get network interface of location
88  */
89 char *connman_location_get_interface(struct connman_location *location)
90 {
91         if (location == NULL)
92                 return NULL;
93
94         return connman_service_get_interface(location->service);
95 }
96
97 /**
98  * connman_location_get_data:
99  * @location: Location structure
100  *
101  * Get private location data pointer
102  */
103 void *connman_location_get_data(struct connman_location *location)
104 {
105         return location->driver_data;
106 }
107
108 /**
109  * connman_location_set_data:
110  * @location: Location structure
111  * @data: data pointer
112  *
113  * Set private location data pointer
114  */
115 void connman_location_set_data(struct connman_location *location, void *data)
116 {
117         location->driver_data = data;
118 }
119
120 static GSList *driver_list = NULL;
121
122 static gint compare_priority(gconstpointer a, gconstpointer b)
123 {
124         const struct connman_location_driver *driver1 = a;
125         const struct connman_location_driver *driver2 = b;
126
127         return driver2->priority - driver1->priority;
128 }
129
130 /**
131  * connman_location_driver_register:
132  * @driver: Location driver definition
133  *
134  * Register a new Location driver
135  *
136  * Returns: %0 on success
137  */
138 int connman_location_driver_register(struct connman_location_driver *driver)
139 {
140         DBG("driver %p name %s", driver, driver->name);
141
142         driver_list = g_slist_insert_sorted(driver_list, driver,
143                                                         compare_priority);
144
145         return 0;
146 }
147
148 /**
149  * connman_location_driver_unregister:
150  * @driver: Location driver definition
151  *
152  * Remove a previously registered Location driver
153  */
154 void connman_location_driver_unregister(struct connman_location_driver *driver)
155 {
156         DBG("driver %p name %s", driver, driver->name);
157
158         driver_list = g_slist_remove(driver_list, driver);
159 }
160
161 /**
162  * connman_location_report_result:
163  * @location: location structure
164  * @result: result information
165  *
166  * Report result of a location detection
167  */
168 void connman_location_report_result(struct connman_location *location,
169                                         enum connman_location_result result)
170 {
171         DBG("location %p result %d", location, result);
172
173         if (location == NULL)
174                 return;
175
176         if (location->result == result)
177                 return;
178
179         location->result = result;
180
181         switch (location->result) {
182         case CONNMAN_LOCATION_RESULT_UNKNOWN:
183                 return;
184         case CONNMAN_LOCATION_RESULT_PORTAL:
185                 __connman_service_request_login(location->service);
186                 break;
187         case CONNMAN_LOCATION_RESULT_ONLINE:
188                 __connman_service_indicate_state(location->service,
189                                                 CONNMAN_SERVICE_STATE_ONLINE);
190                 break;
191         }
192 }
193
194 struct connman_location *__connman_location_create(struct connman_service *service)
195 {
196         struct connman_location *location;
197
198         DBG("service %p", service);
199
200         if (service == NULL)
201                 return NULL;
202
203         location = g_try_new0(struct connman_location, 1);
204         if (location == NULL)
205                 return NULL;
206
207         DBG("location %p", location);
208
209         location->refcount = 1;
210
211         location->service = service;
212         location->result = CONNMAN_LOCATION_RESULT_UNKNOWN;
213
214         return location;
215 }
216
217 int __connman_location_detect(struct connman_service *service)
218 {
219         struct connman_location *location;
220         GSList *list;
221
222         DBG("service %p", service);
223
224         location = __connman_service_get_location(service);
225         if (location == NULL)
226                 return -EINVAL;
227
228         if (location->driver) {
229                 location->result = CONNMAN_LOCATION_RESULT_UNKNOWN;
230                 location->driver->finish(location);
231
232                 if (location->driver->detect(location) == 0)
233                         return 0;
234
235                 location->driver = NULL;
236         }
237
238         for (list = driver_list; list; list = list->next) {
239                 struct connman_location_driver *driver = list->data;
240
241                 DBG("driver %p name %s", driver, driver->name);
242
243                 if (driver->detect(location) == 0) {
244                         location->driver = driver;
245                         break;
246                 }
247         }
248
249         if (location->driver == NULL)
250                 connman_location_report_result(location,
251                                         CONNMAN_LOCATION_RESULT_ONLINE);
252
253         return 0;
254 }
255
256 int __connman_location_finish(struct connman_service *service)
257 {
258         struct connman_location *location;
259
260         DBG("service %p", service);
261
262         location = __connman_service_get_location(service);
263         if (location == NULL)
264                 return -EINVAL;
265
266         location->result = CONNMAN_LOCATION_RESULT_UNKNOWN;
267
268         if (location->driver) {
269                 location->driver->finish(location);
270                 location->driver = NULL;
271         }
272
273         return 0;
274 }
275
276 int __connman_location_init(void)
277 {
278         return 0;
279 }
280
281 void __connman_location_cleanup(void)
282 {
283 }