diff options
Diffstat (limited to 'plugins/ethernet.c')
-rw-r--r-- | plugins/ethernet.c | 134 |
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); |