wireless/wapi: add save_config/reconnect support

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2020-04-03 13:22:28 +08:00 committed by Abdelatif Guettouche
parent 6bafe90db4
commit df1d0e73f8
4 changed files with 322 additions and 20 deletions

View File

@ -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
*

View File

@ -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
*

View File

@ -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;

View File

@ -47,6 +47,8 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#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 <ifname> <txpower> <index/flag>\n",
progname);
#ifdef CONFIG_WIRELESS_WAPI_INITCONF
fprintf(stderr, "\t%s reconnect <ifname>\n", progname);
fprintf(stderr, "\t%s save_config <ifname>\n", progname);
#endif
fprintf(stderr, "\t%s help\n", progname);
fprintf(stderr, "\nFrequency Flags:\n");