From df1d0e73f8cee308dfde71061e1732f2fe5037ea Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Fri, 3 Apr 2020 13:22:28 +0800 Subject: [PATCH] wireless/wapi: add save_config/reconnect support Signed-off-by: chao.an --- include/wireless/wapi.h | 31 +++++++ wireless/wapi/src/driver_wext.c | 144 +++++++++++++++++++++++++++++--- wireless/wapi/src/util.c | 24 ++++-- wireless/wapi/src/wapi.c | 143 +++++++++++++++++++++++++++++++ 4 files changed, 322 insertions(+), 20 deletions(-) diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h index 6407590d4..af05e2d1f 100644 --- a/include/wireless/wapi.h +++ b/include/wireless/wapi.h @@ -747,6 +747,23 @@ int wpa_driver_wext_set_key_ext(int sockfd, FAR const char *ifname, enum wpa_alg_e alg, FAR const char *key, size_t key_len); +/**************************************************************************** + * Name: wpa_driver_wext_get_key_ext + * + * Description: + * + * Input Parameters: + * sockfd - Opened network socket + * ifname - Interface name + * + * Returned Value: + * + ****************************************************************************/ + +int wpa_driver_wext_get_key_ext(int sockfd, FAR const char *ifname, + enum wpa_alg_e *alg, FAR char *key, + size_t *req_len); + /**************************************************************************** * Name: wpa_driver_wext_associate * @@ -775,6 +792,20 @@ int wpa_driver_wext_associate(FAR struct wpa_wconfig_s *wconfig); int wpa_driver_wext_set_auth_param(int sockfd, FAR const char *ifname, int idx, uint32_t value); +/**************************************************************************** + * Name: wpa_driver_wext_get_auth_param + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +int wpa_driver_wext_get_auth_param(int sockfd, FAR const char *ifname, + int idx, uint32_t *value); + /**************************************************************************** * Name: wpa_driver_wext_disconnect * diff --git a/wireless/wapi/src/driver_wext.c b/wireless/wapi/src/driver_wext.c index 20e2b675b..6f473eca9 100644 --- a/wireless/wapi/src/driver_wext.c +++ b/wireless/wapi/src/driver_wext.c @@ -69,6 +69,76 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: wpa_driver_wext_get_key_ext + * + * Description: + * + * Input Parameters: + * sockfd - Opened network socket + * ifname - Interface name + * + * Returned Value: + * + ****************************************************************************/ + +int wpa_driver_wext_get_key_ext(int sockfd, FAR const char *ifname, + enum wpa_alg_e *alg, FAR char *key, + size_t *req_len) +{ + struct iw_encode_ext *ext; + struct iwreq iwr; + int ret; + + ext = malloc(sizeof(*ext) + *req_len); + if (ext == NULL) + { + return -1; + } + + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, ifname, IFNAMSIZ); + + iwr.u.encoding.pointer = (caddr_t) ext; + iwr.u.encoding.length = sizeof(*ext) + *req_len; + + ret = ioctl(sockfd, SIOCGIWENCODEEXT, (unsigned long)&iwr); + if (ret >= 0) + { + switch (ext->alg) + { + case IW_ENCODE_ALG_NONE: + *alg = WPA_ALG_NONE; + break; + + case IW_ENCODE_ALG_WEP: + *alg = WPA_ALG_WEP; + break; + + case IW_ENCODE_ALG_TKIP: + *alg = WPA_ALG_TKIP; + break; + + case IW_ENCODE_ALG_CCMP: + *alg = WPA_ALG_CCMP; + break; + + default: + free(ext); + return -1; + } + + if (key && ext->key_len < *req_len) + { + memcpy(key, ext->key, ext->key_len); + *req_len = ext->key_len; + } + } + + free(ext); + return ret; +} + /**************************************************************************** * Name: wpa_driver_wext_set_key_ext * @@ -82,7 +152,7 @@ * ****************************************************************************/ -int wpa_driver_wext_set_key_ext(int sockfd, FAR const char *ifname, +int wpa_driver_wext_set_key_ext(int sockfd, FAR const char *ifname, enum wpa_alg_e alg, FAR const char *key, size_t key_len) { @@ -208,16 +278,21 @@ int wpa_driver_wext_associate(FAR struct wpa_wconfig_s *wconfig) goto close_socket; } - ret = wpa_driver_wext_set_key_ext(sockfd, wconfig->ifname, wconfig->alg, - wconfig->passphrase, wconfig->phraselen); - if (ret < 0) + if (wconfig->phraselen > 0) { - nerr("ERROR: Fail set key: %d\n", ret); - ret = -1; - goto close_socket; + ret = wpa_driver_wext_set_key_ext(sockfd, wconfig->ifname, + wconfig->alg, + wconfig->passphrase, + wconfig->phraselen); + if (ret < 0) + { + nerr("ERROR: Fail set key: %d\n", ret); + goto close_socket; + } } - ret = wapi_set_essid(sockfd, wconfig->ifname, wconfig->ssid, WAPI_ESSID_ON); + ret = wapi_set_essid(sockfd, wconfig->ifname, wconfig->ssid, + WAPI_ESSID_ON); if (ret < 0) { nerr("ERROR: Fail set ssid: %d\n", ret); @@ -239,8 +314,11 @@ close_socket: * ****************************************************************************/ -int wpa_driver_wext_set_auth_param(int sockfd, FAR const char *ifname, - int idx, uint32_t value) +static int wpa_driver_wext_process_auth_param(int sockfd, + FAR const char *ifname, + int idx, + uint32_t *value, + bool set) { struct iwreq iwr; int errcode; @@ -251,9 +329,10 @@ int wpa_driver_wext_set_auth_param(int sockfd, FAR const char *ifname, memset(&iwr, 0, sizeof(iwr)); strncpy(iwr.ifr_name, ifname, IFNAMSIZ); iwr.u.param.flags = idx & IW_AUTH_INDEX; - iwr.u.param.value = value; + iwr.u.param.value = set ? *value : 0; - if (ioctl(sockfd, SIOCSIWAUTH, (unsigned long)&iwr) < 0) + if (ioctl(sockfd, set ? SIOCSIWAUTH : SIOCGIWAUTH, + (unsigned long)&iwr) < 0) { errcode = errno; if (errcode != EOPNOTSUPP) @@ -265,9 +344,50 @@ int wpa_driver_wext_set_auth_param(int sockfd, FAR const char *ifname, ret = errcode == EOPNOTSUPP ? -2 : -1; } + if (ret == 0 && !set) + { + *value = iwr.u.param.value; + } + return ret; } +/**************************************************************************** + * Name: wpa_driver_wext_set_auth_param + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +int wpa_driver_wext_set_auth_param(int sockfd, FAR const char *ifname, + int idx, uint32_t value) +{ + return wpa_driver_wext_process_auth_param(sockfd, ifname, + idx, &value, true); +} + +/**************************************************************************** + * Name: wpa_driver_wext_get_auth_param + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +int wpa_driver_wext_get_auth_param(int sockfd, FAR const char *ifname, + int idx, uint32_t *value) +{ + return wpa_driver_wext_process_auth_param(sockfd, ifname, + idx, value, false); +} + /**************************************************************************** * Name: wpa_driver_wext_disconnect * diff --git a/wireless/wapi/src/util.c b/wireless/wapi/src/util.c index 7b821efee..2a5125742 100644 --- a/wireless/wapi/src/util.c +++ b/wireless/wapi/src/util.c @@ -62,6 +62,12 @@ #define WAPI_IOCTL_COMMAND_NAMEBUFSIZ 24 +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static char g_ioctl_command_namebuf[WAPI_IOCTL_COMMAND_NAMEBUFSIZ]; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -135,7 +141,15 @@ static bool wapi_json_update(FAR cJSON *root, } else { - if (!strncmp(value, obj->valuestring, strlen(obj->valuestring))) + int len = strlen(obj->valuestring); + if (len > 0) + { + if (!strncmp(value, obj->valuestring, len)) + { + return false; + } + } + else if (len == 0 && value == NULL) { return false; } @@ -155,12 +169,6 @@ static bool wapi_json_update(FAR cJSON *root, } #endif /* CONFIG_WIRELESS_WAPI_INITCONF */ -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -static char g_ioctl_command_namebuf[WAPI_IOCTL_COMMAND_NAMEBUFSIZ]; - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -377,7 +385,7 @@ FAR void *wapi_load_config(FAR const char *ifname, conf->ifname = ifname; conf->ssidlen = strlen(conf->ssid); - conf->phraselen = strlen(conf->passphrase); + conf->phraselen = conf->passphrase ? strlen(conf->passphrase) : 0; return root; diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index e8a457750..eb7ebc78f 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -47,6 +47,8 @@ #include #include +#include "netutils/netlib.h" + #include "wireless/wapi.h" #include "util.h" @@ -91,6 +93,10 @@ static int wapi_bitrate_cmd (int sock, int argc, FAR char **argv); static int wapi_txpower_cmd (int sock, int argc, FAR char **argv); static int wapi_scan_results_cmd (int sock, int argc, FAR char **argv); static int wapi_scan_cmd (int sock, int argc, FAR char **argv); +#ifdef CONFIG_WIRELESS_WAPI_INITCONF +static int wapi_reconnect_cmd (int sock, int argc, FAR char **argv); +static int wapi_save_config_cmd (int sock, int argc, FAR char **argv); +#endif /**************************************************************************** * Private Data @@ -112,6 +118,10 @@ static const struct wapi_command_s g_wapi_commands[] = {"ap", 2, 2, wapi_ap_cmd}, {"bitrate", 3, 3, wapi_bitrate_cmd}, {"txpower", 3, 3, wapi_txpower_cmd}, +#ifdef CONFIG_WIRELESS_WAPI_INITCONF + {"reconnect", 1, 1, wapi_reconnect_cmd}, + {"save_config", 1, 1, wapi_save_config_cmd}, +#endif }; /**************************************************************************** @@ -739,6 +749,135 @@ static int wapi_scan_cmd(int sock, int argc, FAR char **argv) return wapi_scan_results_cmd(sock, 1, argv); } +#ifdef CONFIG_WIRELESS_WAPI_INITCONF + +/**************************************************************************** + * Name: wapi_reconnect_cmd + * + * Description: + * Reconnect the AP in the range using given ifname interface. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int wapi_reconnect_cmd(int sock, int argc, FAR char **argv) +{ + struct wpa_wconfig_s conf; + FAR void *load; + int ret; + + load = wapi_load_config(argv[0], NULL, &conf); + if (load == NULL) + { + return -1; + } + + ret = wpa_driver_wext_associate(&conf); + + wapi_unload_config(load); + + return ret; +} + +/**************************************************************************** + * Name: wapi_save_config_cmd + * + * Description: + * Scans available APs in the range using given ifname interface. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int wapi_save_config_cmd(int sock, int argc, FAR char **argv) +{ + char essid[WAPI_ESSID_MAX_SIZE + 1]; + enum wapi_essid_flag_e essid_flag; + struct wpa_wconfig_s conf; + uint8_t if_flags; + uint32_t value; + size_t psk_len; + char psk[32]; + int ret; + + ret = netlib_getifstatus(argv[0], &if_flags); + if (ret < 0) + { + return ret; + } + + if (!IFF_IS_RUNNING(if_flags)) + { + return -1; + } + + psk_len = sizeof(psk); + + memset(&conf, 0, sizeof(struct wpa_wconfig_s)); + ret = wapi_get_mode(sock, argv[0], &conf.sta_mode); + if (ret < 0) + { + return ret; + } + + memset(essid, 0, sizeof(essid)); + ret = wapi_get_essid(sock, argv[0], essid, &essid_flag); + if (ret < 0) + { + return ret; + } + + conf.ssid = essid; + conf.ssidlen = strnlen(essid, sizeof(essid)); + + memset(psk, 0, sizeof(psk)); + ret = wpa_driver_wext_get_key_ext(sock, + argv[0], + &conf.alg, + psk, + &psk_len); + if (ret == 0) + { + conf.passphrase = psk; + conf.phraselen = psk_len; + } + + ret = wpa_driver_wext_get_auth_param(sock, + argv[0], + IW_AUTH_WPA_VERSION, + &value); + if (ret < 0) + { + conf.auth_wpa = IW_AUTH_WPA_VERSION_WPA2; + } + else + { + conf.auth_wpa = value; + } + + ret = wpa_driver_wext_get_auth_param(sock, + argv[0], + IW_AUTH_CIPHER_PAIRWISE, + &value); + if (ret < 0) + { + if (conf.phraselen > 0) + conf.cipher_mode = IW_AUTH_CIPHER_CCMP; + else + conf.cipher_mode = IW_AUTH_CIPHER_NONE; + } + else + { + conf.cipher_mode = value; + } + + return wapi_save_config(argv[0], NULL, &conf); +} +#endif + /**************************************************************************** * Name: wapi_showusage * @@ -775,6 +914,10 @@ static void wapi_showusage(FAR const char *progname, int exitcode) progname); fprintf(stderr, "\t%s txpower \n", progname); +#ifdef CONFIG_WIRELESS_WAPI_INITCONF + fprintf(stderr, "\t%s reconnect \n", progname); + fprintf(stderr, "\t%s save_config \n", progname); +#endif fprintf(stderr, "\t%s help\n", progname); fprintf(stderr, "\nFrequency Flags:\n");