Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@KISSMonX
Created April 26, 2018 03:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KISSMonX/4281c739152da9c1910ad32a43ea8e22 to your computer and use it in GitHub Desktop.
Save KISSMonX/4281c739152da9c1910ad32a43ea8e22 to your computer and use it in GitHub Desktop.
wifimanager.c 集服示例
/*****************************************************************************
** File Name: wifimanager.cpp
** Author: MingH
** Date: 25/04/2017
** Copyright: 2017 RoboSys, Incorporated. All Rights Reserved.
** Description: 新的配网方式, 采用上传 wifi 列表的方式
******************************************************************************/
#include <stdio.h>
#include <cJSON.h>
#include <string>
#include <fstream>
#include <streambuf>
#include "Wifimanager.h"
#include <iwlib.h>
#include <wireless.h>
#include <errno.h>
#include <stdlib.h>
#include "RobotManager.h"
#define LOG_TAG "wifimanager"
#include <log/log.h>
//===================================================================================================
// @Description : 当前无线网络的信息
// @param : skfd: connect to kernel net
// @param : ifname: interface name
// @param : info: write result to this struct
// @return : 0: success other: error code
// @Author: MingH
// NOTE: Master 模式的时候 iwconfig 无 Quality, 信号质量为 0
//===================================================================================================
static int getWirelessInfo(int skfd, char * ifname, struct wireless_info *info)
{
struct iwreq wrq;
memset((char *) info, 0, sizeof(struct wireless_info));
/* Get basic information */
if(iw_get_basic_config(skfd, ifname, &(info->b)) < 0) {
/* If no wireless name : no wireless extensions */
/* But let's check if the interface exists at all */
struct ifreq ifr;
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
return(-ENODEV);
}
else {
return(-ENOTSUP);
}
}
/* Get ranges */
if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0) {
info->has_range = 1;
}
/* Get AP address */
if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0) {
info->has_ap_addr = 1;
memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
}
/* Get bit rate */
if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0) {
info->has_bitrate = 1;
memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
}
/* Get Power Management settings */
wrq.u.power.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0) {
info->has_power = 1;
memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
}
/* Get stats */
if (iw_get_stats(skfd, ifname, &(info->stats), &info->range, info->has_range) >= 0) {
info->has_stats = 1;
}
#ifndef WE_ESSENTIAL
/* Get NickName */
wrq.u.essid.pointer = (caddr_t) info->nickname;
wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
wrq.u.essid.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0) {
if(wrq.u.data.length > 1) {
info->has_nickname = 1;
}
}
if ((info->has_range) && (info->range.we_version_compiled > 9)) {
/* Get Transmit Power */
if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0) {
info->has_txpower = 1;
memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
}
}
/* Get sensitivity */
if (iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0) {
info->has_sens = 1;
memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
}
if ((info->has_range) && (info->range.we_version_compiled > 10)) {
/* Get retry limit/lifetime */
if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0) {
info->has_retry = 1;
memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
}
}
/* Get RTS threshold */
if (iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0) {
info->has_rts = 1;
memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
}
/* Get fragmentation threshold */
if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0) {
info->has_frag = 1;
memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
}
#endif /* WE_ESSENTIAL */
return WIFI_MANAGER_OPERATION_SUCCESS;
}
//===================================================================================================
// @Description : 将当前的获取到的结果写入到自定义字段的结构体内
// @param : info: current wireless info (all)
// @param : iwconfInfoResult: write result to this struct
// @return : 0: success other: error code
// @Author: MingH
//===================================================================================================
static void setIwconfigInfo(struct wireless_info *info, iwconfigInfo_t *iwconfInfoResult)
{
char buffer[128]; /* Temporary buffer */
/* Set ESSID (extended network), if any */
if(info->b.has_essid) {
if(info->b.essid_on) {
sprintf(iwconfInfoResult->ESSID, "%s", info->b.essid);
}
}
/* Set the current mode of operation */
if(info->b.has_mode) {
sprintf(iwconfInfoResult->Mode, "%s", iw_operation_mode[info->b.mode]);
}
/* Set frequency / channel */
if(info->b.has_freq) {
double freq = info->b.freq; /* Frequency/channel */
int channel = -1; /* Converted to channel */
/* Some drivers insist of returning channel instead of frequency.
* This fixes them up. Note that, driver should still return
* frequency, because other tools depend on it. */
if(info->has_range && (freq < KILO)) {
channel = iw_channel_to_freq((int) freq, &freq, &info->range);
channel = channel;
}
iw_print_freq_value(buffer, sizeof(buffer), freq);
sprintf(iwconfInfoResult->Frequency, "%s", buffer);
}
/* Set the address of the current Access Point */
if(info->has_ap_addr) {
/* Oups ! No Access Point in Ad-Hoc mode */
if((info->b.has_mode) && (info->b.mode == IW_MODE_ADHOC)) {
sprintf(iwconfInfoResult->AccessPoint, "%s", "IW_MODE_ADHOC");
}
else {
sprintf(iwconfInfoResult->AccessPoint, "%s", iw_sawap_ntop(&info->ap_addr, buffer));
}
}
// AP 模式没有信号质量, STA 模式有信号质量
if(info->has_stats) {
// Quality=5/5
iwconfInfoResult->Quality = info->stats.qual.qual;
}
}
//===================================================================================================
// @Description : 逐个处理扫描到的无线网络事件类型
// @param : ...
// @return : 0: success other: error code
// @Author: MingH
//===================================================================================================
static inline void getScanningToken(
struct stream_descr * stream, /* Stream of events */
struct iw_event * event, /* Extracted token */
struct iwscan_state * state,
struct iw_range * iw_range, /* Range info */
int has_range,
iwlistScanInfo_t *iwScanInfo)
{
char buffer[128]; /* Temporary buffer */
// 解析事件类型获取指定的数值
switch (event->cmd) {
case SIOCGIWAP:
sprintf(iwScanInfo->Address, "%s", iw_saether_ntop(&event->u.ap_addr, buffer));
break;
case SIOCGIWNWID:
// NOTE: 2017年5月4日: 目前的小盒还不支持获取 NWID
break;
case SIOCGIWFREQ:
{
double freq; /* Frequency/channel */
int channel = -1; /* Converted to channel */
freq = iw_freq2float(&(event->u.freq));
/* Convert to channel if possible */
if (has_range) {
channel = iw_freq_to_channel(freq, iw_range);
}
iw_print_freq_value(buffer, sizeof(buffer), freq);
sprintf(iwScanInfo->Frequency, "%s", buffer);
if (channel >= 0) {
iwScanInfo->Channel = channel;
}
}
break;
case SIOCGIWMODE:
// TODO: 暂不需要, 直接 break
break;
case SIOCGIWNAME:
// TODO: 暂不需要, 直接 break
break;
case SIOCGIWESSID:
{
char essid[IW_ESSID_MAX_SIZE + 1];
memset(essid, '\0', sizeof(essid));
if ((event->u.essid.pointer) && (event->u.essid.length)) {
memcpy(essid, event->u.essid.pointer, event->u.essid.length);
}
if (event->u.essid.flags) {
/* Does it have an ESSID index ? */
// TODO: 有一种单一频率路由可以设置两个 SSID
if((event->u.essid.flags & IW_ENCODE_INDEX) > 1) {
sprintf(iwScanInfo->ESSID, "%s [%d]", essid, (event->u.essid.flags & IW_ENCODE_INDEX));
}
else {
sprintf(iwScanInfo->ESSID, "%s", essid);
}
}
else {
ALOGW("SSID 被隐藏或者关闭\n");
}
}
break;
case SIOCGIWENCODE:
{
unsigned char key[IW_ENCODING_TOKEN_MAX];
if(event->u.data.pointer) {
memcpy(key, event->u.data.pointer, event->u.data.length);
}
else {
event->u.data.flags |= IW_ENCODE_NOKEY;
}
if (event->u.data.flags & IW_ENCODE_DISABLED) {
sprintf(iwScanInfo->Encryption, "off");
}
else {
/* Display the key */
iw_print_key(buffer, sizeof(buffer), key, event->u.data.length, event->u.data.flags);
sprintf(iwScanInfo->Encryption, "%s", buffer);
/* Other info... */
if((event->u.data.flags & IW_ENCODE_INDEX) > 1) {
ALOGD(" [%d]", event->u.data.flags & IW_ENCODE_INDEX);
}
if(event->u.data.flags & IW_ENCODE_RESTRICTED) {
ALOGD(" Security mode:restricted");
}
if(event->u.data.flags & IW_ENCODE_OPEN) {
ALOGD(" Security mode:open");
}
}
}
break;
case SIOCGIWRATE:
// TODO: 暂不需要, 直接 break
break;
case SIOCGIWMODUL:
// TODO: 暂不需要, 直接 break
break;
case IWEVQUAL:
// 最大值是 5
iwScanInfo->Quality = event->u.qual.qual;
break;
#ifndef WE_ESSENTIAL
case IWEVGENIE:
// TODO: 暂不需要, 直接 break
break;
#endif /* WE_ESSENTIAL */
default:
ALOGE("(Unknown Wireless Token 0x%04X)\n", event->cmd);
} /* switch(event->cmd) */
}
//===================================================================================================
// @Description : 逐个处理扫描到的无线网络事件类型, 拼接成自己想要的
// @param : skfd: connect to kernel net
// @param : ifname: interface name
// @param : info: write result to this struct
// @param : listCnt: 扫描的结果数量
// @param : listMax: 最大扫描结果数量
// @return : 0: success other: error code
// @Author: MingH
//===================================================================================================
static int getScanningInfo(int skfd, char *ifname, iwlistScanInfo_t *iwScanList, int *listCnt, int listMax)
{
struct iwreq wrq;
int scanflags = 0; /* Flags for scan */
unsigned char * buffer = NULL; /* Results */
int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
struct iw_range range;
int has_range;
struct timeval tv; /* Select timeout */
int timeout = 15000000; /* 15s */
if (!iwScanList || !listCnt) {
ALOGE("[ERROR]getScanningInfo: param invalid. iwScanList = %p, listCnt = %p\n", iwScanList, listCnt);
return WIFI_MANAGER_PARAMETER_INVALID;
}
/* Get range stuff */
has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
/* Check if the interface could support scanning. */
if((!has_range) || (range.we_version_compiled < 14)) {
ALOGE("%-8.16s Interface doesn't support scanning.\n", ifname);
return WIFI_MANAGER_GET_RANGE_ERROR;
}
/* Init timeout value -> 250ms between set and first get */
tv.tv_sec = 0;
tv.tv_usec = 250000;
wrq.u.data.pointer = NULL;
wrq.u.data.flags = 0;
wrq.u.data.length = 0;
/* Initiate Scanning */
if (iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0) {
if((errno != EPERM) || (scanflags != 0)) {
fprintf(stderr, "%-8.16s Interface doesn't support scanning : %s\n\n", ifname, strerror(errno));
return WIFI_MANAGER_GET_WIFI_INFO_FAILED;
}
tv.tv_usec = 0;
}
timeout -= tv.tv_usec;
/* Forever */
while(1) {
fd_set rfds; /* File descriptors for select */
int last_fd; /* Last fd */
int ret;
/* Guess what ? We must re-generate rfds each time */
FD_ZERO(&rfds);
last_fd = -1;
/* In here, add the rtnetlink fd in the list */
/* Wait until something happens */
ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
/* Check if there was an error */
if (ret < 0) {
if(errno == EAGAIN || errno == EINTR) {
continue;
}
ALOGE("[ERROR] select() Unhandled signal - exiting...\n");
return WIFI_MANAGER_SCAN_SELECT_FAILED;
}
/* Check if there was a timeout */
if (ret == 0) {
unsigned char * newbuf;
REALLOC:
/* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
newbuf = (unsigned char *)realloc(buffer, buflen);
if (newbuf == NULL) {
if (buffer) {
free(buffer);
}
ALOGE("%s: Allocation failed\n", __FUNCTION__);
return WIFI_MANAGER_ALLOC_MEMORY_FAILED;
}
buffer = newbuf;
/* Try to read the results */
wrq.u.data.pointer = buffer;
wrq.u.data.flags = 0;
wrq.u.data.length = buflen;
if (iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0) {
/* Check if buffer was too small (WE-17 only) */
if ((errno == E2BIG) && (range.we_version_compiled > 16)) {
/* Some driver may return very large scan results, either
* because there are many cells, or because they have many
* large elements in cells (like IWEVCUSTOM). Most will
* only need the regular sized buffer. We now use a dynamic
* allocation of the buffer to satisfy everybody. Of course,
* as we don't know in advance the size of the array, we try
* various increasing sizes. Jean II */
/* Check if the driver gave us any hints. */
if(wrq.u.data.length > buflen) {
buflen = wrq.u.data.length;
}
else {
buflen *= 2;
}
/* Try again */
goto REALLOC;
}
/* Check if results not available yet */
if (errno == EAGAIN) {
/* Restart timer for only 100ms*/
tv.tv_sec = 0;
tv.tv_usec = 100000;
timeout -= tv.tv_usec;
if (timeout > 0) {
continue; /* Try again later */
}
}
/* Bad error */
free(buffer);
ALOGE("%-8.16s Failed to read scan data : %s\n\n", ifname, strerror(errno));
return WIFI_MANAGER_READ_SCANDATA_FAILED;
}
else {
/* We have the results, go to process them */
break;
}
}
/* In here, check if event and event type
* if scan event, read results. All errors bad & no reset timeout */
}
if (wrq.u.data.length) {
struct iw_event iwe;
struct stream_descr stream;
struct iwscan_state state = { .ap_num = 1, .val_index = 0 };
int ret;
int count = 0;
iwlistScanInfo_t tempScanInfo;
memset(&tempScanInfo, 0, sizeof(iwlistScanInfo_t));
iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
do {
// 读取: ssid, address, freq/channel, Encryption, quality
ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
if (ret > 0) {
getScanningToken(&stream, &iwe, &state, &range, has_range, &tempScanInfo);
}
// 当前的 wifi 所有需要的字段都要获取完整才能进行下一个
if ((strlen(tempScanInfo.Encryption) > 0) && (strlen(tempScanInfo.Address) > 0)
&& (strlen(tempScanInfo.Frequency) > 0) && (strlen(tempScanInfo.ESSID) > 0)
&& (tempScanInfo.Quality >= 1) && (tempScanInfo.Channel >= 1))
{
memcpy(&iwScanList[count], &tempScanInfo, sizeof(iwlistScanInfo_t));
memset(&tempScanInfo, 0, sizeof(iwlistScanInfo_t));
if (count++ >= listMax) {
*listCnt = listMax;
break;
}
*listCnt = count;
}
} while (ret > 0);
}
else {
ALOGW("%-8.16s 没有扫描到可用 WIFI.\n", ifname);
}
free(buffer);
return WIFI_MANAGER_OPERATION_SUCCESS;
}
//===================================================================================================
// @Description : 当前无线网络的统计及配置信息
// @param : skfd: connect to kernel net
// @param : ifname: interface name
// @param : iwconfInfoResult: write result to this struct
// @return : 0: success other: error code
// @Author: MingH
//===================================================================================================
static int getIWconfigInfo(int skfd, char *ifname, iwconfigInfo_t *iwconfInfoResult)
{
struct wireless_info info;
int rc;
if (!ifname || !iwconfInfoResult) {
ALOGE("ERROR: getIwconfigInfo param invalid. ifname = %p, iwconfInfoResult = %p\n",
ifname, iwconfInfoResult);
return WIFI_MANAGER_PARAMETER_INVALID;
}
rc = getWirelessInfo(skfd, ifname, &info);
if (!rc) {
setIwconfigInfo(&info, iwconfInfoResult);
}
else {
ALOGE("[ERROR] getWirelessInfo: getWirelessInfo failed.\n");
return WIFI_MANAGER_GET_WIFI_INFO_FAILED;
}
RobotManager *pRobotManager = NULL;
RobotManager_GetRobotManager(&pRobotManager);
RobotInfo *pRobotInfo = RobotManager_GetRobotInfo(pRobotManager);
sprintf(iwconfInfoResult->SN, "%s", pRobotInfo->sn);
return WIFI_MANAGER_OPERATION_SUCCESS;
}
//===================================================================================================
// @Description : 将结果序列化成 json
// @param : dest: 要写入的buf
// @param : ifname: interface name
// @param : iwconfInfoResult: iwconfig 的当前连接信息
// @param : iwScanList: 扫描到的结果
// @param : resultCount: 结果数量
// @return : 0: success other: error code
// @Author: MingH
// NOTE: Master 模式的时候 iwconfig 无 Quality, 信号质量为 0
//===================================================================================================
static int createResultJSON(char *dest, iwconfigInfo_t *iwconfInfoResult, iwlistScanInfo_t *iwScanList, int resultCount)
{
cJSON *pJSONRoot = NULL;
cJSON *pJSONArray = NULL;
if (!dest || !iwconfInfoResult || !iwScanList) {
ALOGE("[ERROR] createResultJSON param invalid. dest: %p, iwScanList: %p\n", dest, iwScanList);
return WIFI_MANAGER_PARAMETER_INVALID;
}
// 当前连接信息
pJSONRoot = cJSON_CreateObject();
cJSON_AddStringToObject(pJSONRoot, "SN", iwconfInfoResult->SN);
cJSON_AddStringToObject(pJSONRoot, "ESSID", iwconfInfoResult->ESSID);
cJSON_AddStringToObject(pJSONRoot, "AccessPoint", iwconfInfoResult->AccessPoint);
cJSON_AddStringToObject(pJSONRoot, "Mode", iwconfInfoResult->Mode);
cJSON_AddStringToObject(pJSONRoot, "Frequency", iwconfInfoResult->Frequency);
// NOTE: 连接信号质量, 仅 Managed 模式
if (!strcmp(iwconfInfoResult->Mode, "Managed")) {
cJSON_AddNumberToObject(pJSONRoot, "Quality", iwconfInfoResult->Quality);
}
// 扫描到的 wifi 列表
pJSONArray = cJSON_CreateArray();
cJSON_AddItemToObject(pJSONRoot, "Cells", pJSONArray);
for (int i = 0; i < resultCount; i++) {
cJSON *pArrayItem = cJSON_CreateObject();
cJSON_AddItemToArray(pJSONArray, pArrayItem);
cJSON_AddStringToObject(pArrayItem, "Address", iwScanList[i].Address);
cJSON_AddStringToObject(pArrayItem, "ESSID", iwScanList[i].ESSID);
cJSON_AddStringToObject(pArrayItem, "Frequency", iwScanList[i].Frequency);
cJSON_AddNumberToObject(pArrayItem, "Channel", iwScanList[i].Channel);
cJSON_AddNumberToObject(pArrayItem, "Quality", iwScanList[i].Quality);
cJSON_AddStringToObject(pArrayItem, "Encryption", iwScanList[i].Encryption);
cJSON_AddBoolToObject(pArrayItem, "Registered", iwScanList[i].Registered);
// NOTE: 加密了才会有密码, 这样设置的时候会将已经存在的密码覆盖
if (iwScanList[i].Registered) {
cJSON_AddStringToObject(pArrayItem, "Password", iwScanList[i].Password);
}
}
// 不格式化输出结果, 节省空间
char *result = cJSON_PrintUnformatted(pJSONRoot);
// char *result = cJSON_Print(pJSONRoot);
strcpy(dest, result);
free(result);
cJSON_Delete(pJSONRoot);
return WIFI_MANAGER_OPERATION_SUCCESS;
}
//===================================================================================================
// @Description : 将结果序列化成 json
// @param : resultJSON: 要写入的buf
// @param : ifname: interface name, default: wlan0
// @return : 0: success other: error code
// @Author: MingH
// NOTE: Master 模式的时候 iwconfig 无 Quality, 信号质量为 0
//===================================================================================================
int getWifiList(char *resultJSON, char *ifname)
{
int skfd = 0;
static iwconfigInfo_t iwconfInfoResult; // 当前连接的信息
int listCount = 0; // 读取到的无线网络数量, 最大 SCANNING_LIST_MAX_ITEM
FILE *tmpFd = NULL;
char *wpaContent = NULL;
// 分配空间给扫描到的无线网络
iwlistScanInfo_t *scanningListBuffer = (iwlistScanInfo_t *)malloc(SCANNING_LIST_MAX_ITEM * sizeof(iwlistScanInfo_t));
if (!scanningListBuffer) {
ALOGE("[ERROR] malloc scanningListBuffer failed.\n");
return WIFI_MANAGER_ALLOC_MEMORY_FAILED;
}
memset(&iwconfInfoResult, 0, sizeof(iwconfigInfo_t));
memset(scanningListBuffer, 0, SCANNING_LIST_MAX_ITEM * sizeof(scanningListBuffer));
// 创建 socket 与内核通信
if ((skfd = iw_sockets_open()) < 0) {
ALOGE("[ERROR]getWifiList: iw_sockets_open failed: %s\n", strerror(errno));
free(scanningListBuffer);
return WIFI_MANAGER_SOCKETS_OPEN_FAILED;
}
// 获取当前的连接信息
int ret = getIWconfigInfo(skfd, ifname, &iwconfInfoResult);
if (ret < 0) {
ALOGE("[ERROR] getIWconfigInfo: get iwconfig information failed.\n");
free(scanningListBuffer);
iw_sockets_close(skfd);
return ret;
}
// 获取扫描到的无线网络
ret = getScanningInfo(skfd, ifname, scanningListBuffer, &listCount, SCANNING_LIST_MAX_ITEM);
if (ret < 0) {
ALOGE("[ERROR] getIwlistInfo failed.\n");
free(scanningListBuffer);
iw_sockets_close(skfd);
return ret;
}
// 检查 wpa 文件是否存在
if (0 == access(WIFI_SAVED_FILE, (F_OK | R_OK | W_OK))) {
// 读取 wpa 文件内容进行分析
tmpFd = fopen(WIFI_SAVED_FILE, "r+");
if (NULL == tmpFd) {
ALOGE("[ERROR] read %s file failed.\n", WIFI_SAVED_FILE);
free(scanningListBuffer);
return WIFI_MANAGER_SOCKETS_OPEN_FAILED;
}
fseek(tmpFd, 0, SEEK_END);
long fsize = ftell(tmpFd);
fseek(tmpFd, 0, SEEK_SET); //same as rewind(f);
wpaContent = (char *)malloc(fsize + 1);
if (!wpaContent) {
ALOGE("[ERROR]malloc wpa_supplicant.conf file wpaContent buffer failed.\n");
free(scanningListBuffer);
iw_sockets_close(skfd);
fclose(tmpFd);
return WIFI_MANAGER_ALLOC_MEMORY_FAILED;
}
memset(wpaContent, 0, fsize + 1);
fread(wpaContent, sizeof(char), fsize, tmpFd);
char *wpaContentTemp = wpaContent;
bool isRegistered = false;
// 遍历 SSID 并获取密码
for (int i = 0; i < listCount; i++) {
isRegistered = false;
char *firstPos = strstr(wpaContentTemp, scanningListBuffer[i].ESSID);
// 存在 WIFI 名称
while (firstPos) {
char ssid[64] = {0};
for (int j = 0; *firstPos != '\"'; j++, firstPos++) {
ssid[j] = *firstPos;
}
// 匹配 SSID, 注意子串
if (!strcmp(ssid, scanningListBuffer[i].ESSID)) {
isRegistered = true;
char *psk = strstr(firstPos, "psk=");
// 提取 psk 密码
if (psk) {
psk = psk + 5;
for (int j = 0; *psk != '\"'; j++, psk++) {
scanningListBuffer[i].Password[j] = *psk;
}
}
break;
}
else {
// NOTE: 不符合就在当前位置偏移一些, 继续往下找.
wpaContentTemp = wpaContentTemp + 6;
firstPos = strstr(wpaContentTemp, scanningListBuffer[i].ESSID);
}
memset(ssid, 0, sizeof(ssid));
}
scanningListBuffer[i].Registered = isRegistered;
}
fclose(tmpFd);
free(wpaContent);
}
else {
// 没有 wpa 文件默认所有的扫描结果 registered 都为 false
for (int i = 0; i < listCount; i++) {
scanningListBuffer[i].Registered = false;
}
}
ret = createResultJSON(resultJSON, &iwconfInfoResult, scanningListBuffer, listCount);
if (ret < 0) {
ALOGE("[ERROR] createResultJSON: create Scanning Json failed.\n");
free(scanningListBuffer);
iw_sockets_close(skfd);
return ret;
}
free(scanningListBuffer);
iw_sockets_close(skfd);
return WIFI_MANAGER_OPERATION_SUCCESS;
}
//===================================================================================================
// @Description : 获取类似 iwconfig 的信息
// @param : iwconfig: 要写入的 struct
// @param : ifname: interface name, default: wlan0
// @return : 0: success other: error code
// @Author: MingH
// NOTE: Master 模式的时候 iwconfig 无 Quality, 信号质量为 0
//===================================================================================================
int getIwconfig(char *ifname, iwconfigInfo_t * iwconfig)
{
int skfd = 0;
struct wireless_info info;
int rc;
if (!ifname || !iwconfig) {
ALOGE("ERROR: getIwconfig param invalid. ifname = %p, iwconfig = %p\n",
ifname, iwconfig);
return WIFI_MANAGER_PARAMETER_INVALID;
}
// 创建 socket 与内核通信
if ((skfd = iw_sockets_open()) < 0) {
ALOGE("[ERROR]getIwconfig: iw_sockets_open failed: %s\n", strerror(errno));
return WIFI_MANAGER_SOCKETS_OPEN_FAILED;
}
rc = getWirelessInfo(skfd, ifname, &info);
if (!rc) {
setIwconfigInfo(&info, iwconfig);
}
else {
ALOGE("[ERROR] getIwconfig: getWirelessInfo failed.\n");
iw_sockets_close(skfd);
return WIFI_MANAGER_GET_WIFI_INFO_FAILED;
}
iw_sockets_close(skfd);
return WIFI_MANAGER_OPERATION_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment