38
38
struct connman_provider {
39
39
struct connman_element element;
40
struct connman_service *vpn_service;
42
enum connman_provider_state state;
43
enum connman_provider_error error;
50
47
struct connman_provider_driver *driver;
54
static const char *state2string(enum connman_provider_state state)
57
case CONNMAN_PROVIDER_STATE_UNKNOWN:
59
case CONNMAN_PROVIDER_STATE_IDLE:
61
case CONNMAN_PROVIDER_STATE_CONNECT:
63
case CONNMAN_PROVIDER_STATE_READY:
65
case CONNMAN_PROVIDER_STATE_DISCONNECT:
67
case CONNMAN_PROVIDER_STATE_FAILURE:
73
static const char *error2string(enum connman_provider_error error)
76
case CONNMAN_PROVIDER_ERROR_UNKNOWN:
78
case CONNMAN_PROVIDER_ERROR_CONNECT_FAILED:
79
return "connect-failed";
85
static void append_path(gpointer key, gpointer value, gpointer user_data)
87
struct connman_provider *provider = value;
88
DBusMessageIter *iter = user_data;
90
DBG("add provider path");
91
if (provider->path == NULL)
94
dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
98
void __connman_provider_list(DBusMessageIter *iter, void *user_data)
100
g_hash_table_foreach(provider_hash, append_path, iter);
51
void __connman_provider_append_properties(struct connman_provider *provider,
52
DBusMessageIter *iter)
54
if (provider->host != NULL)
55
connman_dbus_dict_append_basic(iter, "Host",
56
DBUS_TYPE_STRING, &provider->host);
58
if (provider->domain != NULL)
59
connman_dbus_dict_append_basic(iter, "Domain",
60
DBUS_TYPE_STRING, &provider->domain);
62
if (provider->type != NULL)
63
connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING,
103
67
static struct connman_provider *connman_provider_lookup(const char *identifier)
192
static void state_changed(struct connman_provider *provider)
196
str = state2string(provider->state);
200
connman_dbus_property_changed_basic(provider->path,
201
CONNMAN_PROVIDER_INTERFACE, "State",
202
DBUS_TYPE_STRING, &str);
205
static void reply_pending(struct connman_provider *provider, int error)
207
if (provider->timeout > 0) {
208
g_source_remove(provider->timeout);
209
provider->timeout = 0;
212
if (provider->pending != NULL) {
216
reply = __connman_error_failed(provider->pending,
219
g_dbus_send_message(connection, reply);
221
g_dbus_send_reply(connection, provider->pending,
224
dbus_message_unref(provider->pending);
225
provider->pending = NULL;
229
static int connman_provider_disconnect(struct connman_provider *provider)
160
int __connman_provider_disconnect(struct connman_provider *provider)
233
164
DBG("provider %p", provider);
235
reply_pending(provider, ECONNABORTED);
237
166
if (provider->driver != NULL && provider->driver->disconnect != NULL)
238
167
err = provider->driver->disconnect(provider);
240
169
return -EOPNOTSUPP;
242
__connman_provider_indicate_state(provider,
243
CONNMAN_PROVIDER_STATE_DISCONNECT);
171
if (provider->vpn_service != NULL)
172
__connman_service_indicate_state(provider->vpn_service,
173
CONNMAN_SERVICE_STATE_DISCONNECT);
245
175
if (err != -EINPROGRESS)
254
int __connman_provider_indicate_state(struct connman_provider *provider,
255
enum connman_provider_state state)
257
DBG("provider %p state %d", provider, state);
259
if (provider == NULL)
262
if (provider->state == state)
265
if (provider->state == CONNMAN_PROVIDER_STATE_FAILURE &&
266
state == CONNMAN_PROVIDER_STATE_IDLE)
269
if (provider->state == CONNMAN_PROVIDER_STATE_IDLE &&
270
state == CONNMAN_PROVIDER_STATE_DISCONNECT)
273
if (state == CONNMAN_PROVIDER_STATE_IDLE &&
274
provider->state != CONNMAN_PROVIDER_STATE_DISCONNECT) {
275
provider->state = CONNMAN_PROVIDER_STATE_DISCONNECT;
276
state_changed(provider);
278
connman_provider_disconnect(provider);
281
provider->state = state;
282
state_changed(provider);
284
if (state == CONNMAN_PROVIDER_STATE_READY)
285
reply_pending(provider, 0);
287
if (state == CONNMAN_PROVIDER_STATE_FAILURE)
288
reply_pending(provider, EIO);
290
provider->error = CONNMAN_PROVIDER_ERROR_UNKNOWN;
295
int __connman_provider_indicate_error(struct connman_provider *provider,
296
enum connman_provider_error error)
298
DBG("provider %p error %d", provider, error);
300
if (provider == NULL)
303
provider->error = error;
305
return __connman_provider_indicate_state(provider,
306
CONNMAN_PROVIDER_STATE_FAILURE);
309
static gboolean connect_timeout(gpointer user_data)
311
struct connman_provider *provider = user_data;
313
DBG("provider %p", provider);
315
provider->timeout = 0;
317
if (provider->pending != NULL) {
320
reply = __connman_error_operation_timeout(provider->pending);
322
g_dbus_send_message(connection, reply);
324
dbus_message_unref(provider->pending);
325
provider->pending = NULL;
328
__connman_provider_indicate_error(provider,
329
CONNMAN_PROVIDER_ERROR_CONNECT_FAILED);
334
static connman_bool_t is_connecting(struct connman_provider *provider)
336
switch (provider->state) {
337
case CONNMAN_PROVIDER_STATE_UNKNOWN:
338
case CONNMAN_PROVIDER_STATE_IDLE:
339
case CONNMAN_PROVIDER_STATE_FAILURE:
340
case CONNMAN_PROVIDER_STATE_DISCONNECT:
341
case CONNMAN_PROVIDER_STATE_READY:
343
case CONNMAN_PROVIDER_STATE_CONNECT:
350
static int connman_provider_connect(struct connman_provider *provider)
184
int __connman_provider_connect(struct connman_provider *provider)
354
188
DBG("provider %p", provider);
356
if (provider->state == CONNMAN_PROVIDER_STATE_READY)
359
if (is_connecting(provider) == TRUE)
362
190
g_free(provider->element.ipv4.address);
191
g_free(provider->element.ipv4.peer);
363
192
g_free(provider->element.ipv4.netmask);
364
193
g_free(provider->element.ipv4.gateway);
365
194
g_free(provider->element.ipv4.broadcast);
366
195
g_free(provider->element.ipv4.pac);
368
197
provider->element.ipv4.address = NULL;
198
provider->element.ipv4.peer = NULL;
369
199
provider->element.ipv4.netmask = NULL;
370
200
provider->element.ipv4.gateway = NULL;
371
201
provider->element.ipv4.broadcast = NULL;
394
221
int __connman_provider_remove(const char *path)
396
223
struct connman_provider *provider;
398
227
DBG("path %s", path);
400
provider = g_hash_table_lookup(provider_hash, path);
401
if (provider == NULL) {
402
DBG("patch %s not found", path);
229
g_hash_table_iter_init(&iter, provider_hash);
230
while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
231
const char *srv_path;
234
if (provider->vpn_service == NULL)
237
srv_path = __connman_service_get_path(provider->vpn_service);
239
if (g_strcmp0(srv_path, path) == 0) {
240
DBG("Removing VPN %s", provider->identifier);
241
g_hash_table_remove(provider_hash,
242
provider->identifier);
406
g_hash_table_remove(provider_hash, path);
411
static DBusMessage *get_properties(DBusConnection *conn,
412
DBusMessage *msg, void *user_data)
414
struct connman_provider *provider = user_data;
416
DBusMessageIter array, dict;
417
dbus_bool_t required;
420
DBG("provider %p", provider);
422
reply = dbus_message_new_method_return(msg);
426
dbus_message_iter_init_append(reply, &array);
428
connman_dbus_dict_open(&array, &dict);
430
if (provider->name != NULL)
431
connman_dbus_dict_append_basic(&dict, "Name",
432
DBUS_TYPE_STRING, &provider->name);
435
connman_dbus_dict_append_basic(&dict, "Type",
439
str = state2string(provider->state);
441
connman_dbus_dict_append_basic(&dict, "State",
442
DBUS_TYPE_STRING, &str);
444
str = error2string(provider->error);
446
connman_dbus_dict_append_basic(&dict, "Error",
447
DBUS_TYPE_STRING, &str);
450
connman_dbus_dict_append_basic(&dict, "PassphraseRequired",
451
DBUS_TYPE_BOOLEAN, &required);
453
connman_dbus_dict_close(&array, &dict);
458
static GDBusMethodTable provider_methods[] = {
459
{ "GetProperties", "", "a{sv}", get_properties },
463
static GDBusSignalTable provider_signals[] = {
464
{ "PropertyChanged", "sv" },
468
int connman_provider_set_connected(struct connman_provider *provider,
469
connman_bool_t connected)
250
static int set_connected(struct connman_provider *provider,
251
connman_bool_t connected)
253
struct connman_service *service = provider->vpn_service;
471
258
if (connected == TRUE) {
472
259
enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
473
260
struct connman_element *element;
261
char *nameservers = NULL, *name = NULL;
266
__connman_service_indicate_state(provider->vpn_service,
267
CONNMAN_SERVICE_STATE_CONFIGURATION);
475
269
type = CONNMAN_ELEMENT_TYPE_IPV4;
477
271
element = connman_element_create(NULL);
478
if (element != NULL) {
479
element->type = type;
480
element->index = provider->element.index;
482
connman_provider_setup_vpn_ipv4(provider, element);
484
if (connman_element_register(element,
485
&provider->element) < 0)
486
connman_element_unref(element);
488
char *nameservers = NULL;
493
nameservers = g_strdup(provider->dns);
495
name = connman_inet_ifname(
496
provider->element.index);
498
char *next = strchr(value, ' ');
502
connman_resolver_append(name,
513
__connman_provider_indicate_state(provider,
514
CONNMAN_PROVIDER_STATE_READY);
275
element->type = type;
276
element->index = provider->element.index;
278
err = connman_provider_setup_vpn_ipv4(provider, element);
280
connman_element_unref(element);
282
__connman_service_indicate_state(service,
283
CONNMAN_SERVICE_STATE_FAILURE);
288
__connman_service_indicate_state(service,
289
CONNMAN_SERVICE_STATE_READY);
291
__connman_service_set_domainname(service, provider->domain);
293
name = connman_inet_ifname(provider->element.index);
295
nameservers = g_strdup(provider->dns);
297
second_ns = strchr(value, ' ');
300
__connman_service_append_nameserver(service, value);
304
char *next = strchr(value, ' ');
308
connman_resolver_append(name, provider->domain, value);
516
reply_pending(provider, ECONNABORTED);
517
316
connman_element_unregister_children(&provider->element);
518
__connman_provider_indicate_state(provider,
519
CONNMAN_PROVIDER_STATE_DISCONNECT);
317
__connman_service_indicate_state(service,
318
CONNMAN_SERVICE_STATE_IDLE);
525
static void provider_free(gpointer user_data)
324
int connman_provider_set_state(struct connman_provider *provider,
325
enum connman_provider_state state)
527
struct connman_provider *provider = user_data;
528
char *path = provider->path;
530
DBG("provider %p", provider);
532
reply_pending(provider, ENOENT);
533
provider->path = NULL;
536
g_dbus_unregister_interface(connection, path,
537
CONNMAN_PROVIDER_INTERFACE);
327
if (provider == NULL || provider->vpn_service == NULL)
331
case CONNMAN_PROVIDER_STATE_UNKNOWN:
333
case CONNMAN_PROVIDER_STATE_IDLE:
334
return set_connected(provider, FALSE);
335
case CONNMAN_PROVIDER_STATE_CONNECT:
336
return __connman_service_indicate_state(provider->vpn_service,
337
CONNMAN_SERVICE_STATE_ASSOCIATION);
338
case CONNMAN_PROVIDER_STATE_READY:
339
return set_connected(provider, TRUE);
340
case CONNMAN_PROVIDER_STATE_DISCONNECT:
341
return __connman_service_indicate_state(provider->vpn_service,
342
CONNMAN_SERVICE_STATE_DISCONNECT);
343
case CONNMAN_PROVIDER_STATE_FAILURE:
344
return __connman_service_indicate_state(provider->vpn_service,
345
CONNMAN_SERVICE_STATE_FAILURE);
541
g_free(provider->name);
542
g_free(provider->type);
543
g_free(provider->domain);
544
g_free(provider->identifier);
545
g_free(provider->dns);
548
351
static void unregister_provider(gpointer data)
550
353
struct connman_provider *provider = data;
354
struct connman_service *service = provider->vpn_service;
552
356
DBG("provider %p", provider);
554
connman_provider_disconnect(provider);
358
provider->vpn_service = NULL;
359
__connman_service_put(service);
556
361
connman_element_unregister(&provider->element);
557
362
connman_provider_unref(provider);
875
728
driver_list = g_slist_remove(driver_list, driver);
731
static void provider_remove(gpointer key, gpointer value,
734
struct connman_provider *provider = value;
736
g_hash_table_remove(provider_hash, provider->identifier);
739
static void provider_offline_mode(connman_bool_t enabled)
741
DBG("enabled %d", enabled);
744
g_hash_table_foreach(provider_hash, provider_remove, NULL);
748
static struct connman_notifier provider_notifier = {
750
.offline_mode = provider_offline_mode,
878
753
int __connman_provider_init(void)
882
759
connection = connman_dbus_get_connection();
884
761
provider_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
885
762
NULL, unregister_provider);
764
err = connman_notifier_register(&provider_notifier);
766
g_hash_table_destroy(provider_hash);
767
dbus_connection_unref(connection);
889
773
void __connman_provider_cleanup(void)
777
connman_notifier_unregister(&provider_notifier);
893
779
g_hash_table_foreach(provider_hash, clean_provider, NULL);
895
781
g_hash_table_destroy(provider_hash);