*
* Connection Manager
*
- * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "connman.h"
+/*
+ * How many times to send RS with the purpose of
+ * refreshing RDNSS entries before they actually expire.
+ * With a value of 1, one RS will be sent, with no retries.
+ */
+#define RS_REFRESH_COUNT 1
+
+/*
+ * Value in seconds to wait for RA after RS was sent.
+ * After this time elapsed, we can send another RS.
+ */
+#define RS_REFRESH_TIMEOUT 3
+
static GSList *network_list = NULL;
static GSList *driver_list = NULL;
char *path;
int index;
int router_solicit_count;
+ int router_solicit_refresh_count;
struct connman_network_driver *driver;
void *driver_data;
return NULL;
}
-connman_bool_t __connman_network_has_driver(struct connman_network *network)
-{
- if (network == NULL || network->driver == NULL)
- return FALSE;
-
- return TRUE;
-}
-
static gboolean match_driver(struct connman_network *network,
struct connman_network_driver *driver)
{
connman_network_unref(network);
}
+static void receive_refresh_rs_reply(struct nd_router_advert *reply,
+ unsigned int length, void *user_data)
+{
+ struct connman_network *network = user_data;
+
+ DBG("reply %p", reply);
+
+ if (reply == NULL) {
+ /*
+ * Router solicitation message seem to get lost easily so
+ * try to send it again.
+ */
+ if (network->router_solicit_refresh_count > 1) {
+ network->router_solicit_refresh_count--;
+ DBG("re-send router solicitation %d",
+ network->router_solicit_refresh_count);
+ __connman_inet_ipv6_send_rs(network->index,
+ RS_REFRESH_TIMEOUT,
+ receive_refresh_rs_reply,
+ network);
+ return;
+ }
+ }
+
+ /* RS refresh not in progress anymore */
+ network->router_solicit_refresh_count = 0;
+
+ connman_network_unref(network);
+ return;
+}
+
+int __connman_refresh_rs_ipv6(struct connman_network *network, int index)
+{
+ int ret = 0;
+
+ DBG("network %p index %d", network, index);
+
+ /* Send only one RS for all RDNSS entries which are about to expire */
+ if (network->router_solicit_refresh_count > 0) {
+ DBG("RS refresh already started");
+ return 0;
+ }
+
+ network->router_solicit_refresh_count = RS_REFRESH_COUNT;
+
+ connman_network_ref(network);
+
+ ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT,
+ receive_refresh_rs_reply, network);
+ return ret;
+}
+
static void autoconf_ipv6_set(struct connman_network *network)
{
struct connman_service *service;
int connman_network_connect_hidden(struct connman_network *network,
char *identity, char* passphrase)
{
+ int err = 0;
struct connman_service *service;
DBG("");
__connman_service_set_agent_identity(service, identity);
if (passphrase != NULL)
- __connman_service_add_passphrase(service, passphrase);
+ err = __connman_service_add_passphrase(service, passphrase);
- return __connman_service_connect(service);
+ if (err == -ENOKEY) {
+ __connman_service_indicate_error(service,
+ CONNMAN_SERVICE_ERROR_INVALID_KEY);
+ return err;
+ } else {
+ __connman_service_set_hidden(service);
+ __connman_service_set_userconnect(service, TRUE);
+ return __connman_service_connect(service);
+ }
}
/**