Xiang Xiao 66dbaa4539 Replace self defined macros with NET_SOCK_[FAMILY|TYPE|PROTOCOL]
NET_SOCK_* is defined by nuttx/net/netconfig.h and then can be shared

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2021-12-20 16:04:29 -03:00

522 lines
12 KiB
C

/****************************************************************************
* apps/wireless/wapi/src/util.c
*
* Copyright (C) 2011, 2017Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for NuttX from WAPI:
*
* Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <netinet/ether.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <nuttx/net/netconfig.h>
#include "wireless/wapi.h"
#include "util.h"
#ifdef CONFIG_WIRELESS_WAPI_INITCONF
#include "netutils/cJSON.h"
#endif /* CONFIG_WIRELESS_WAPI_INITCONF */
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Size of the command buffer */
#define WAPI_IOCTL_COMMAND_NAMEBUFSIZ 24
/****************************************************************************
* Public Functions
****************************************************************************/
static char g_ioctl_command_namebuf[WAPI_IOCTL_COMMAND_NAMEBUFSIZ];
/****************************************************************************
* Private Functions
****************************************************************************/
#ifdef CONFIG_WIRELESS_WAPI_INITCONF
static FAR void *wapi_json_load(FAR const char *confname)
{
FAR cJSON *root = NULL;
struct stat sb;
FAR char *buf;
int fd = -1;
if (stat(confname, &sb) < 0)
{
return NULL;
}
buf = malloc(sb.st_size);
if (!buf)
{
goto errout;
}
fd = open(confname, O_RDONLY);
if (fd < 0)
{
goto errout;
}
if (read(fd, buf, sb.st_size) != sb.st_size)
{
goto errout;
}
root = cJSON_Parse(buf);
errout:
if (buf)
{
free(buf);
}
if (fd > 0)
{
close(fd);
}
return root;
}
static bool wapi_json_update(FAR cJSON *root,
FAR const char *key,
FAR void *value,
bool integer)
{
intptr_t intval = (intptr_t)value;
FAR cJSON *item;
FAR cJSON *obj;
obj = cJSON_GetObjectItem(root, key);
if (obj)
{
if (integer)
{
if (intval == obj->valueint)
{
return false;
}
item = cJSON_CreateNumber(intval);
}
else
{
int len = strlen(obj->valuestring);
if (len > 0)
{
if (!strncmp(value, obj->valuestring, len))
{
return false;
}
}
else if (len == 0 && value == NULL)
{
return false;
}
item = cJSON_CreateString(value);
}
cJSON_ReplaceItemInObject(root, key, item);
}
else
{
integer ? cJSON_AddNumberToObject(root, key, intval) :
cJSON_AddStringToObject(root, key, value);
}
return true;
}
#endif /* CONFIG_WIRELESS_WAPI_INITCONF */
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: wapi_make_socket
*
* Description:
* Creates an AF_INET socket to be used in ioctl() calls.
*
* Returned Value:
* Non-negative on success.
*
****************************************************************************/
int wapi_make_socket(void)
{
return socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
}
/****************************************************************************
* Name: wapi_ioctl_command_name
*
* Description:
* Return name string for IOCTL command
*
* Returned Value:
* Name string for IOCTL command
*
****************************************************************************/
FAR const char *wapi_ioctl_command_name(int cmd)
{
switch (cmd)
{
case SIOCADDRT:
return "SIOCADDRT";
case SIOCDELRT:
return "SIOCDELRT";
case SIOCGIFADDR:
return "SIOCGIFADDR";
case SIOCGIWAP:
return "SIOCGIWAP";
case SIOCGIWESSID:
return "SIOCGIWESSID";
case SIOCGIWFREQ:
return "SIOCGIWFREQ";
case SIOCGIWMODE:
return "SIOCGIWMODE";
case SIOCGIWRANGE:
return "SIOCGIWRANGE";
case SIOCGIWRATE:
return "SIOCGIWRATE";
case SIOCGIWSCAN:
return "SIOCGIWSCAN";
case SIOCGIWTXPOW:
return "SIOCGIWTXPOW";
case SIOCSIFADDR:
return "SIOCSIFADDR";
case SIOCSIWAP:
return "SIOCSIWAP";
case SIOCSIWESSID:
return "SIOCSIWESSID";
case SIOCSIWFREQ:
return "SIOCSIWFREQ";
case SIOCSIWMODE:
return "SIOCSIWMODE";
case SIOCSIWRATE:
return "SIOCSIWRATE";
case SIOCSIWSCAN:
return "SIOCSIWSCAN";
case SIOCSIWTXPOW:
return "SIOCSIWTXPOW";
default:
snprintf(g_ioctl_command_namebuf, WAPI_IOCTL_COMMAND_NAMEBUFSIZ,
"0x%x", cmd);
return g_ioctl_command_namebuf;
}
}
#ifdef CONFIG_WIRELESS_WAPI_INITCONF
/****************************************************************************
* Name: wapi_unload_config
*
* Description:
*
* Input Parameters:
* load - Config resource handler, allocate by wapi_load_config()
*
* Returned Value:
*
****************************************************************************/
void wapi_unload_config(FAR void *load)
{
if (load)
{
cJSON_Delete(load);
}
}
/****************************************************************************
* Name: wapi_load_config
*
* Description:
*
* Input Parameters:
*
* Returned Value:
* Return a pointer to the hold the config resource, NULL On error.
*
****************************************************************************/
FAR void *wapi_load_config(FAR const char *ifname,
FAR const char *confname,
FAR struct wpa_wconfig_s *conf)
{
FAR struct ether_addr *ap;
FAR cJSON *ifobj;
FAR cJSON *root;
FAR cJSON *obj;
if (ifname == NULL ||
conf == NULL)
{
return NULL;
}
if (confname == NULL)
{
confname = CONFIG_WIRELESS_WAPI_CONFIG_PATH;
}
root = wapi_json_load(confname);
if (!root)
{
return NULL;
}
/* Set up the network configuration */
ifobj = cJSON_GetObjectItem(root, ifname);
if (!ifobj)
{
goto errout;
}
memset(conf, 0, sizeof(*conf));
obj = cJSON_GetObjectItem(ifobj, "mode");
if (!obj)
{
goto errout;
}
conf->sta_mode = obj->valueint;
obj = cJSON_GetObjectItem(ifobj, "auth");
if (!obj)
{
goto errout;
}
conf->auth_wpa = obj->valueint;
obj = cJSON_GetObjectItem(ifobj, "cmode");
if (!obj)
{
goto errout;
}
conf->cipher_mode = obj->valueint;
obj = cJSON_GetObjectItem(ifobj, "alg");
if (!obj)
{
goto errout;
}
conf->alg = obj->valueint;
obj = cJSON_GetObjectItem(ifobj, "ssid");
if (!obj || !obj->valuestring)
{
goto errout;
}
conf->ssid = (FAR const char *)obj->valuestring;
obj = cJSON_GetObjectItem(ifobj, "bssid");
if (!obj || !obj->valuestring)
{
goto errout;
}
ap = ether_aton(obj->valuestring);
if (ap != NULL)
{
conf->bssid = (FAR const char *)ap->ether_addr_octet;
}
obj = cJSON_GetObjectItem(ifobj, "psk");
if (!obj || !obj->valuestring)
{
goto errout;
}
conf->passphrase = (FAR const char *)obj->valuestring;
conf->ifname = ifname;
conf->ssidlen = strlen(conf->ssid);
conf->phraselen = conf->passphrase ? strlen(conf->passphrase) : 0;
return root;
errout:
cJSON_Delete(root);
return NULL;
}
/****************************************************************************
* Name: wapi_save_config
*
* Description:
*
* Input Parameters:
*
* Returned Value:
*
****************************************************************************/
int wapi_save_config(FAR const char *ifname,
FAR const char *confname,
FAR const struct wpa_wconfig_s *conf)
{
FAR char *buf = NULL;
FAR cJSON *ifobj;
FAR cJSON *root;
int ret = -1;
int fd = -1;
bool update;
if (ifname == NULL || conf == NULL)
{
return ret;
}
if (confname == NULL)
{
confname = CONFIG_WIRELESS_WAPI_CONFIG_PATH;
}
root = wapi_json_load(confname);
if (!root)
{
root = cJSON_CreateObject();
if (root == NULL)
{
return ret;
}
}
ifobj = cJSON_GetObjectItem(root, ifname);
if (!ifobj)
{
ifobj = cJSON_CreateObject();
if (ifobj == NULL)
{
goto errout;
}
cJSON_AddItemToObject(root, ifname, ifobj);
}
update = wapi_json_update(ifobj, "mode",
(FAR void *)(intptr_t)conf->sta_mode, true);
update |= wapi_json_update(ifobj, "auth",
(FAR void *)(intptr_t)conf->auth_wpa, true);
update |= wapi_json_update(ifobj, "cmode",
(FAR void *)(intptr_t)conf->cipher_mode, true);
update |= wapi_json_update(ifobj, "alg",
(FAR void *)(intptr_t)conf->alg, true);
update |= wapi_json_update(ifobj, "ssid",
(FAR void *)conf->ssid, false);
update |= wapi_json_update(ifobj, "bssid",
(FAR void *)conf->bssid, false);
update |= wapi_json_update(ifobj, "psk",
(FAR void *)conf->passphrase, false);
if (!update)
{
ret = OK;
goto errout;
}
buf = cJSON_PrintUnformatted(root);
if (!buf)
{
goto errout;
}
fd = open(confname, O_RDWR | O_CREAT | O_TRUNC);
if (fd < 0)
{
goto errout;
}
ret = write(fd, buf, strlen(buf));
errout:
if (buf)
{
free(buf);
}
if (fd > 0)
{
close(fd);
}
cJSON_Delete(root);
return ret < 0 ? ret : OK;
}
#endif /* CONFIG_WIRELESS_WAPI_INITCONF */