summaryrefslogtreecommitdiff
path: root/plugins/ethernet.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ethernet.c')
-rw-r--r--plugins/ethernet.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index 9e157467..6702cd38 100644
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
@@ -53,6 +53,11 @@
#include <connman/mesh.h>
#endif
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+#include <connman/option.h>
+#include <gsupplicant/gsupplicant.h>
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
static bool eth_tethering = false;
struct ethernet_data {
@@ -60,6 +65,9 @@ struct ethernet_data {
unsigned flags;
unsigned int watch;
struct connman_network *network;
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ GSupplicantInterface *interface;
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
};
@@ -142,6 +150,123 @@ static void eth_network_remove(struct connman_network *network)
DBG("network %p", network);
}
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static struct connman_network *g_network = NULL;
+
+void handle_eap_signal(GSupplicantInterface *interface, bool status)
+{
+ DBG("captured EAP signal");
+
+ if (!g_network)
+ return;
+
+ if (g_strcmp0("wired", g_supplicant_interface_get_driver(interface)))
+ return;
+
+ if (!connman_network_check_validity(g_network))
+ return;
+
+ DBG("network is valid");
+
+ g_supplicant_unregister_eap_callback();
+
+ if (!status) {
+ // Should we mark service as non favorite or make autoconnect as false?
+
+ g_supplicant_interface_remove(interface, NULL, NULL);
+ connman_network_set_error(g_network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+ g_network = NULL;
+ return;
+ }
+
+ connman_network_set_connected(g_network, status);
+ g_network = NULL;
+}
+
+static void interface_create_callback(int result,
+ GSupplicantInterface *interface, void *user_data)
+{
+ struct ethernet_data *ethernet = user_data;
+
+ if (result < 0 || !interface || !ethernet)
+ return;
+
+ DBG("result %d ifname %s, ethernet %p", result,
+ g_supplicant_interface_get_ifname(interface),
+ ethernet);
+
+ ethernet->interface = interface;
+ g_supplicant_interface_set_data(interface, ethernet);
+}
+
+static int eth_network_connect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ struct connman_service *service = connman_service_lookup_from_network(network);
+
+ if (service && __connman_service_get_use_eapol(service)) {
+ struct connman_device *device = connman_network_get_device(network);
+ struct ethernet_data *ethernet = connman_device_get_data(device);
+ const char *driver = "wired";
+ int index = connman_network_get_index(network);
+ char *ifname = connman_inet_ifname(index);;
+ char *config_file = NULL;
+
+ g_supplicant_register_eap_callback(handle_eap_signal);
+ g_network = network;
+
+ if (asprintf(&config_file, "/opt/usr/data/network/%s-eapol.conf", ifname) < 0)
+ return -ENOMEM;
+
+ DBG("config_file %s", config_file);
+
+ g_supplicant_replace_config_file(ifname, config_file);
+ free(config_file);
+
+ /*
+ * TODO: RemoveInterface if already present because
+ * already created interface will not start EAP handshake.
+ */
+ g_supplicant_interface_create(ifname, driver, NULL,
+ interface_create_callback, ethernet);
+
+ g_free(ifname);
+
+ return 0;
+ }
+
+ connman_network_set_connected(network, true);
+
+ return 0;
+}
+
+static int eth_network_disconnect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ struct connman_service *service = connman_service_lookup_from_network(network);
+
+ if (service && __connman_service_get_use_eapol(service)) {
+ struct connman_device *device = connman_network_get_device(network);
+ struct ethernet_data *ethernet = connman_device_get_data(device);
+
+ g_network = NULL;
+ g_supplicant_unregister_eap_callback();
+ g_supplicant_interface_remove(ethernet->interface, NULL, NULL);
+ connman_network_set_associating(network, false);
+ connman_network_set_connected(network, false);
+
+ return 0;
+ }
+
+ connman_network_set_connected(network, false);
+
+ return 0;
+}
+
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
static int eth_network_connect(struct connman_network *network)
{
DBG("network %p", network);
@@ -160,6 +285,8 @@ static int eth_network_disconnect(struct connman_network *network)
return 0;
}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
static struct connman_network_driver eth_network_driver = {
.name = "cable",
.type = CONNMAN_NETWORK_TYPE_ETHERNET,
@@ -281,6 +408,9 @@ static int eth_dev_probe(struct connman_device *device)
ethernet->index = connman_device_get_index(device);
ethernet->flags = 0;
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ ethernet->interface = NULL;
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
ethernet->watch = connman_rtnl_add_newlink_watch(ethernet->index,
ethernet_newlink, device);
@@ -296,6 +426,10 @@ static void eth_dev_remove(struct connman_device *device)
connman_device_set_data(device, NULL);
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ g_supplicant_interface_remove(ethernet->interface, NULL, NULL);
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
connman_rtnl_remove_watch(ethernet->watch);
remove_network(device, ethernet);