编译时需要 -lwpa_client

wifi.h

#ifndef __WIFI_H__
#define __WIFI_H__int wifi_run_cmd(char *cmd, char *result, unsigned int *len);
/* ack:* RSSI=-77* LINKSPEED=48* NOISE=9999* FREQUENCY=2437*/
struct wifi_signal_poll_result_t {char ack[1024];int rssi;int linkspeed;int noise;int frequency;
};int wifi_run_cmd_signal_poll(struct wifi_signal_poll_result_t *result);/** ack:* bssid=64:3e:8c:37:9e:40* freq=2437* ssid=HD-WLAN* id=0* mode=station* pairwise_cipher=TKIP* group_cipher=TKIP* key_mgmt=WPA-PSK* wpa_state=COMPLETED/DISCONNECTED/SCANNING* ip_address=172.16.2.196* address=08:e9:f6:10:39:5e* uuid=0889e912-d3e3-52c6-8ad3-4d8a24294f7b*/
struct wifi_status_result_t {char ack[1024];char bssid[18];int freq;char ssid[128];int id;char mode[16];char pairwise_cipher[16];char group_cipher[16];char key_mgmt[16];char wpa_state[32];char ip_address[16];char address[18];char uuid[64];
};int wifi_run_cmd_status(struct wifi_status_result_t *result);
void wifi_config(char *ssid, char *psk);
int wifi_get_config(char *ssid, char *psk);
#endif

wifi.c

/** Copyright (C) 2021, 2021  huohongpeng* Author: huohongpeng <1045338804@qq.com>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.* * Change logs:* Date        Author       Notes* 2021-10-21  huohongpeng   首次添加*/
#include <stddef.h>
#include <wpa_ctrl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "wifi.h"/** * 执行一条命令* @cmd: 需要执行命令* @result: 用于存储命令执行后返回的数据* @len: 传入result缓冲区大小, 传出命令执行后实际存储到result的数据大小* @return: 0-成功, 其他失败* 可以执行哪些命令参考: wpa_supplicant源码包中 wpa_supplicant-2.9/wpa_supplicant/wpa_cli.c: wpa_cli_commands[]* 常用的命令有:*  "STATUS"*  "STATUS-DRIVER"*  "STATUS-VERBOSE"*  "SIGNAL_POLL"*  ""*  */
int wifi_run_cmd(char *cmd, char *result, unsigned int *len)
{/** ctrl_path对应的文件路径必须在 /etc/wpa_supplicant.conf文件中的ctrl_interface指定的路径下的文件**   # ls -l /var/run/wpa_supplicant/wlan0 *   srwxrwx---    1 root     root             0 Oct 21 09:47 /var/run/wpa_supplicant/wlan0*/struct wpa_ctrl *wpa_ctrl = wpa_ctrl_open("/var/run/wpa_supplicant/wlan0");if (!wpa_ctrl) {printf("Err: wpa_ctrl_open()\n");return -1;}int ret = wpa_ctrl_request(wpa_ctrl, cmd, strlen(cmd), result, len, 0);result[*len] = 0;wpa_ctrl_close(wpa_ctrl);return ret;
}static int result_get(char *str, char *key, char *val, int val_len)
{char *s;if (!(s = strstr(str, key))) {return -1;}if (!(s = strchr(s, '='))) {return -1;}s++;while (*s != '\n' && *s != '\0' && val_len > 1) {*val++ = *s++;val_len--;}*val ='\0';return 0;
}/** 查询WIFI已连接AP的信号状态* @result: 查询结果* @ret: 0: 成功, -1: 失败*/
int wifi_run_cmd_signal_poll(struct wifi_signal_poll_result_t *result)
{int ret;char val[512];char *ack = result->ack;unsigned int len = sizeof(result->ack);char *cmd = "SIGNAL_POLL";memset(result, 0x00, sizeof(struct wifi_signal_poll_result_t));ret = wifi_run_cmd(cmd, ack, &len);if (ret < 0 || len == 0) {ret = -1;printf("Err: %s\n", cmd);goto ERROR;}if (strncmp(ack, "FAIL", 4) == 0) {printf("Err: %s (FAIL)\n", cmd);goto ERROR;}if (result_get(ack, "RSSI", val, sizeof(val)) == 0) {result->rssi = strtol(val, NULL, 10);}if (result_get(ack, "LINKSPEED", val, sizeof(val)) == 0) {result->linkspeed = strtol(val, NULL, 10);}if (result_get(ack, "FREQUENCY", val, sizeof(val)) == 0) {result->frequency = strtol(val, NULL, 10);}if (result_get(ack, "NOISE", val, sizeof(val)) == 0) {result->noise = strtol(val, NULL, 10);}ERROR:return ret;
}/** 查询WIFi当前工作状态信息* @result: 查询结果* @ret: 0: 查询成功, -1: 查询失败*/
int wifi_run_cmd_status(struct wifi_status_result_t *result)
{int ret;char val[512];char *ack = result->ack;unsigned int len = sizeof(result->ack);char *cmd = "STATUS";memset(result, 0x00, sizeof(struct wifi_status_result_t));ret = wifi_run_cmd(cmd, ack, &len);if (ret < 0 || len == 0) {ret = -1;printf("Err: %s\n", cmd);goto ERROR;}if (strncmp(ack, "FAIL", 4) == 0) {printf("Err: %s (FAIL)\n", cmd);goto ERROR;}result_get(ack, "bssid", result->bssid, sizeof(result->bssid));if (result_get(ack, "freq", val, sizeof(val)) == 0) {result->freq = strtol(val, NULL, 10);}result_get(ack, "ssid", result->ssid, sizeof(result->ssid));if (result_get(ack, "id", val, sizeof(val)) == 0) {result->id = strtol(val, NULL, 10);}result_get(ack, "mode", result->mode, sizeof(result->mode));result_get(ack, "pairwise_cipher", result->pairwise_cipher, sizeof(result->pairwise_cipher));result_get(ack, "group_cipher", result->group_cipher, sizeof(result->group_cipher));result_get(ack, "key_mgmt", result->key_mgmt, sizeof(result->key_mgmt));result_get(ack, "wpa_state", result->wpa_state, sizeof(result->wpa_state));result_get(ack, "ip_address", result->ip_address, sizeof(result->ip_address));result_get(ack, "address", result->address, sizeof(result->address));result_get(ack, "uuid", result->uuid, sizeof(result->uuid));ERROR:return ret;
}/** 修改wifi配置* @ssid: 需要连接ap的ssid* @psk: 需要连接ap的的密码* 注意: 此函数只修改配置不生效,如果生效需要,重启wifi*/
void wifi_set_config(char *ssid, char *psk)
{char buf[1024];int len;char *path = "/etc/wpa_supplicant.conf";int fd = open(path, O_CREAT | O_TRUNC | O_WRONLY);len = sprintf(buf, "ctrl_interface=/var/run/wpa_supplicant\nnetwork={\nssid=\"%s\"\npsk=\"%s\"\n}\n", ssid, psk);write(fd, buf, len);fsync(fd);close(fd);
}/** 获取wifi配置* @ssid: 需要连接ap的ssid* @psk: 需要连接ap的的密码* @ret: 0: 成功, -1*/
int wifi_get_config(char *ssid, char *psk)
{char buf[1024];char *path = "/etc/wpa_supplicant.conf";memset(buf, 0x00, sizeof(buf));int fd = open(path, O_RDONLY);if (fd < 0) {return -1;}read(fd, buf, 1024);close(fd);char val[512];if (result_get(buf, "ssid", val, sizeof(val)) < 0) {return -1;}strcpy(ssid, val + 1);ssid[strlen(ssid) - 1] = '\0';if (result_get(buf, "psk", val, sizeof(val)) < 0) {return -1;}strcpy(psk, val + 1);psk[strlen(psk) - 1] = '\0';return 0;
}void test_wifi_run_cmd_signal_poll(void)
{struct wifi_signal_poll_result_t result;wifi_run_cmd_signal_poll(&result);printf("%s: ack:\n%s", __FUNCTION__, result.ack);printf("%s: rssi: %d\n", __FUNCTION__, result.rssi);printf("%s: linkspeed: %d\n", __FUNCTION__, result.linkspeed);printf("%s frequency: %d\n", __FUNCTION__, result.frequency);printf("%s noise: %d\n", __FUNCTION__, result.noise);
}void test_wifi_run_cmd_status(void)
{struct wifi_status_result_t result;wifi_run_cmd_status(&result);printf("%s: ack:\n%s", __FUNCTION__, result.ack);printf("%s: bssid:%s\n", __FUNCTION__, result.bssid);printf("%s: freq:%d\n", __FUNCTION__, result.freq);printf("%s: ssid:%s\n", __FUNCTION__, result.ssid);printf("%s: id:%d\n", __FUNCTION__, result.id);printf("%s: mode:%s\n", __FUNCTION__, result.mode);printf("%s: pairwise_cipher:%s\n", __FUNCTION__, result.pairwise_cipher);printf("%s: group_cipher:%s\n", __FUNCTION__, result.group_cipher);printf("%s: key_mgmt:%s\n", __FUNCTION__, result.key_mgmt);printf("%s: wpa_state:%s\n", __FUNCTION__, result.wpa_state);printf("%s: ip_address:%s\n", __FUNCTION__, result.ip_address);printf("%s: address:%s\n", __FUNCTION__, result.address);printf("%s: uuid:%s\n", __FUNCTION__, result.uuid);
}void test_wifi(void)
{char ssid[128];char psk[128];if (wifi_get_config(ssid, psk) == 0) {printf("ssid: %s\n", ssid);printf("psk: %s\n", psk);}wifi_set_config("123456789", "123456789");sleep(5);test_wifi_run_cmd_signal_poll();test_wifi_run_cmd_status();
}

Linux下获取WIFI状态信息(c语言)相关推荐

  1. Linux下获取xml调试信息等级

    Linux下获取XML调试信息等级 #ifndef _LOG_H_ #define _LOG_H_#include <stdio.h> #include <string.h> ...

  2. .net core在Linux下获取AD域信息

    .net core在Linux下获取AD域信息 .net Core 2.1.4 .net core现在System.DirectoryServices只支持Windows平台下使用. 参考: http ...

  3. Linux下获取设备IPMI信息常用工具

    1.asu (1)概述 asu是IBM官方提供的一个命令行工具,全称IBM Advanced Settings Utility,可以对IMM进行操作. (2)安装 从官网上下载asu对应的RPM安装包 ...

  4. Linux下获取详细硬件信息的工具:Dmidecode命令详解

    Dmidecode 这款软件允许你在 Linux 系统下获取有关硬件方面的信息.Dmidecode 遵循 SMBIOS/DMI 标准,其输出的信息包括 BIOS.系统.主板.处理器.内存.缓存等等.偶 ...

  5. 汇总 Linux下获取详细硬件信息的工具:Dmidecode命令详解

    Dmidecode 这款软件允许你在 Linux 系统下获取有关硬件方面的信息.Dmidecode 遵循 SMBIOS/DMI 标准,其输出的信息包括 BIOS.系统.主板.处理器.内存.缓存等等.偶 ...

  6. linux 读取 gateway ip socket,linux下获取本地IP信息(没看代码)

    #include #include #include #include //#include #include //#include #include #include #include #inclu ...

  7. u盘linux需要多大内存,linux下获取硬盘、内存、U盘大小及使用大小

    /* * 获取硬盘大小;内存大小;usb大小 */ #ifndef SYSINFOGET_H #define SYSINFOGET_H #include //磁盘信息 #include #includ ...

  8. linux 获取文件夹下文件信息,linux下获取文件夹下子文件列表

    linux下获取文件夹下子文件列表 预置条件: 1.只遍历当前目前,不遍历当前目录的子文件夹 2.根据用户提供的开始时间戳以及持续时间,返回在这个时间区间内被修改过的文件列表. 相关知识: 1.str ...

  9. Linux :: 时间日历指令【1】:date 指令:格式化显示时间信息、Linux 下获取时间

    前言:本篇是 Linux 基本操作篇章的内容! 笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit. 学习集: C++ 入门到入土!!!学习合集 Linux 从命令到网络再到内核!学习 ...

最新文章

  1. mysql布隆过滤器源码_布隆过滤器(Bloom Filter)的原理和实现
  2. 密码学研究-玩转密钥
  3. 方法功能从无参方法、含参方法到重载方法
  4. iOS-获取子视图父控制器
  5. Redis学习-sorted set数据类型
  6. 关于DNS服务中查询域名的命令
  7. Spring上传时报Invalid CSRF Token错误解决方案
  8. python语音识别框架_横评:五款免费开源的语音识别工具
  9. java .net 3des_Java.net3DES差异及互通
  10. threading.Event
  11. 遇到Io阻塞时会切换任务之【爬虫版】
  12. Linux文件夹设置共享
  13. 用奈式第一准则判断是否有码间干扰
  14. axios.js下载
  15. Windows动态链接库DLL和静态库的原理以及创建方法
  16. hdmi接口有什么用_当贝投影仪HDMI(ARC)接口是什么意思?
  17. 棕色和褐色的区别及联系
  18. 计算一点绕另一点旋转n度后的坐标
  19. 谈网页游戏外挂之用python模拟游戏(热血三国2)登陆
  20. 照片的体积怎么缩小?教你快速缩小图片体积的方法

热门文章

  1. QMessageBox 调整大小
  2. 如何简单的提取图片中的文字
  3. Java面向对象之线程相关概念 和 线程基本使用
  4. 川普撞脸希拉里(基于 OpenCV 的面部特征交换)-2
  5. 点击“换一换”切换商品,使用jquery slice()实现无缝连接切换
  6. JIL Mobile Widget 初步认识
  7. 计算机地图制图成图方法,第五章 地图成图方法.ppt
  8. java8安装包打不开_Win7系统下安装JDK提示“无法打开此安装包请确认该程序包存在”怎么办?...
  9. 网络流量监控 v3.0 下载
  10. java -- jre 精简,为桌面小工具开发瘦身