【瑞芯微Rockchip Linux平台】SoftAp需求实现(1)进程代码实现

  • 一、SoftAp启动命令
  • 二、SoftAp启动命令封装实现过程
    • 2.1 在log前添加系统时间
    • 2.2 查看进程是否正在运行 process_is_alive()
    • 2.3 杀死进程 kill_process()
    • 2.4 循环监控相关进程的运行状态
    • 2.5 添加异常处理函数
  • 三、dnsmasq.conf 文件配置
  • 四、hostapd.conf 文件配置
  • 五、完整代码

最近上层有个需求,需要实现启动SoftAp热点,如果记录下所有的实现过程。

本文链接:《【瑞芯微Rockchip Linux平台】SoftAp需求实现(1)进程代码实现》

本系列文章链接:

  1. 《【瑞芯微Rockchip Linux平台】SoftAp需求实现(1)进程代码实现》
  2. 《【瑞芯微Rockchip Linux平台】SoftAp需求实现(2)根据传参修改SSID和密码,SSID以wifi MAC地址后四位对结尾》
  3. 《【瑞芯微Rockchip Linux平台】SoftAp需求实现(3)动态获取BT Mac地址并更新beacon帧中的mac信息》

一、SoftAp启动命令

其实这些,使用命令就能够实现,

  1. 打开命令如下:
    iw phy0 interface add wlan1 type managed
    ifconfig wlan1 up
    ifconfig wlan1 192.168.50.1 netmask 255.255.255.0
    route add default gw 192.168.50.1 wlan1
    dnsmasq -C /data/bin/dnsmasq_softap.conf --interface=wlan1
    hostapd /data/bin/hostapd.conf -t -B

  2. 关闭命令如下:
    kill -15 dnsmasq
    kill -15 hostapd
    route del -net 192.168.50.0 netmask 255.255.255.0 dev wlan1
    ifconfig wlan1 down
    iw dev wlan1 del

  3. 其他命令配置

二、SoftAp启动命令封装实现过程

根据上层的需求,将前面的这些命令进行封装,封装成库和都可执行程序都行。
本需求,我选择的是封装成可执行程序。

2.1 在log前添加系统时间

主要是利用宏控来重写printf函数,这样,在打印每一句log前都会调用get_cur_time获取下当前的系统时间,精确到ms。

#include <time.h>static char *get_cur_time(void){static char s[50]={0};char s_ms[10]={0};time_t t;struct tm *ltime;struct timeval tv; time(&t);ltime = localtime(&t);gettimeofday(&tv,NULL);  //tv.tv_sec * 1000 + tv.tv_usec / 1000;  strftime(s, 50, "%Y-%m-%d %H:%M:%S", ltime);sprintf(s_ms, ".%03d", tv.tv_usec / 1000);strcat(s, s_ms);return s;
}#define printf_t(fmt, ...) printf("[%s][Dongle_Soft_ap] "fmt, get_cur_time(), ##__VA_ARGS__)

2.2 查看进程是否正在运行 process_is_alive()

这个比较简单,主要是通过ps -A | grep dnsmasq | wc -l 来对进程数量进行统计,如果数量大于等1,则说明当前进程正在运行。
该函数返回的是进程运行的数量。

int process_is_alive(const char *process)
{FILE *fp = NULL;int pid = 0;char buff_tmp[100]={0};sprintf(buff_tmp, "ps -A | grep %s | wc -l", process);fp = popen(buff_tmp, "r");if(fp){memset(buff_tmp, 0, 100);fgets(buff_tmp, sizeof(buff_tmp)-1, fp);pclose(fp);if(buff_tmp != NULL){pid = atoi(buff_tmp);return pid;}}    return -1;
}

2.3 杀死进程 kill_process()

通过 popen来获取命令的输出信息来解析到进程的进程号,然后再kill 掉。
一般来说,建议使用 kill -15 来杀进程,它会等待进程释放相关的资源,不容易出来资源泄漏的问题。

void kill_process(const char *process, int level)
{FILE *fp = NULL;int pid = 0;char buff_tmp[100]={0}, *p_buff=NULL, *p_buff1=NULL;sprintf(buff_tmp, "ps -A | grep %s", process);fp = popen(buff_tmp, "r");if(fp){memset(buff_tmp, 0, 100);while(fgets(buff_tmp, sizeof(buff_tmp)-1, fp) >0){p_buff = buff_tmp;while(p_buff!=NULL && *p_buff!='\0' && *p_buff==' ') p_buff++;p_buff1 = p_buff;while(p_buff1!=NULL && *p_buff1!='\0' && *p_buff1!=' ') p_buff1++;*p_buff1 = '\0';pid = atoi(p_buff);if( kill(pid, level) == 0)     // kill(pid, 15)printf_t("===>杀死后台%s进程(%d)(-%d) success\n",process,  pid, level);}pclose(fp);}
}

2.4 循环监控相关进程的运行状态

main函数中,主要工作 就是启动hostapdf进程,然后,循环监控hostapddnsmasq 进程的存活状态,
只要其中有任何一个进程出现异常,都会关注 softap热点,然后释放相关资源。

int main(int argc, char *argv[]){// 1. 启动前杀死现有的 dnsmasq 和 hostapdkill_all_process();usleep(200000);// 2. 启动 hostapdsystem("iw phy0 interface add wlan1 type managed");system("ifconfig wlan1 up");sleep(1);system("ifconfig wlan1 192.168.50.1 netmask 255.255.255.0");system("route add default gw  192.168.50.1 wlan1");printf_t("===>运行命令:dnsmasq -C /data/bin/dnsmasq_softap.conf  --interface=wlan1\n");system("dnsmasq -C /data/bin/dnsmasq_softap.conf  --interface=wlan1");printf_t("===>运行命令:hostapd /data/bin/hostapd.conf -t -B\n");system("hostapd /data/bin/hostapd.conf -t -B");printf_t("===>开始循环监控dnsmasq 和 hostapd -------\n");while(keep_alive == 1){sleep(1);if( process_is_alive("dnsmasq") == 0){printf_t("===>dnsmasq进程异常,开始关闭hostap\n");break;}if( process_is_alive("hostapd") == 0){printf_t("===>hostapd进程异常,开始关闭hostap\n");break;}}// 3. 恢复初始状态kill_all_process();printf_t("===>route del -net 192.168.50.0 netmask 255.255.255.0 dev wlan1\n");system("route del -net 192.168.50.0 netmask 255.255.255.0 dev wlan1");printf_t("===>ifconfig wlan1 down\n");system("ifconfig wlan1 down");system("iw dev wlan1 del");printf_t("程序运行结束-------------\n");return 0;
}

2.5 添加异常处理函数

添加一个全局变量keep_alive 用于确认当前进程是否需要主动退出。

main函数中,注册SIGINT、SIGABRT、SIGTERM、SIGKILL四个信号,绑定函数sig_handler
当过程在运行过程中,收到这四个信号中的任何一个,都会进入sig_handler函数,将keep_alive清0,结束main函数中的循环监控,释放相关的资源。

void sig_handler( int sig )
{if ( sig == SIGINT ||  sig == SIGABRT ||  sig == SIGTERM ||  sig == SIGKILL){keep_alive = 0;printf_t("===>收到停止信号, keep_alive=%d\n", keep_alive);}
}int main(int argc, char *argv[]){// 注册异常处理函数signal( SIGINT, sig_handler );signal( SIGABRT, sig_handler );signal( SIGTERM, sig_handler );signal( SIGKILL, sig_handler );
}

三、dnsmasq.conf 文件配置

user=root
# listen-address=127.0.0.1except-interface=usb0#interface=p2p-wlan0-0
# dhcp-option=p2p-wlan0-0,1,255.255.225.0     #指定掩码
# dhcp-option=p2p-wlan0-0,3,192.168.50.1     #指定网关
# dhcp-option=p2p-wlan0-0,6,192.168.50.1     #指定dns
dhcp-range=192.168.50.2,192.168.50.51# log-queries
# log-facility=/data/dnsmasq.log

四、hostapd.conf 文件配置

interface=wlan0
ctrl_interface=/var/run/hostapd
driver=nl80211
ssid=soft-apauth_algs=1
wpa=2
wpa_passphrase=12345678
wpa_key_mgmt=WPA-PSK
#wpa_pairwise=TKIP
rsn_pairwise=CCMP# 5G 149
channel=149
hw_mode=a
ieee80211ac=1
ignore_broadcast_ssid=0# 2.4G  6
#channel=6
#hw_mode=g
#ieee80211n=1
#ignore_broadcast_ssid=0

五、完整代码

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <string.h>#ifdef __cplusplus
extern "C" {#endifstatic int keep_alive = 1;static char *get_cur_time(void){static char s[50]={0};char s_ms[10]={0};time_t t;struct tm *ltime;struct timeval tv; time(&t);ltime = localtime(&t);gettimeofday(&tv,NULL);  //tv.tv_sec * 1000 + tv.tv_usec / 1000;  strftime(s, 50, "%Y-%m-%d %H:%M:%S", ltime);sprintf(s_ms, ".%03d", tv.tv_usec / 1000);strcat(s, s_ms);return s;
}
#define printf_t(fmt, ...) printf("[%s][Dongle_Soft_ap] "fmt, get_cur_time(), ##__VA_ARGS__)void sig_handler( int sig )
{if ( sig == SIGINT ||  sig == SIGABRT ||  sig == SIGTERM ||  sig == SIGKILL){keep_alive = 0;printf_t("===>收到停止信号, keep_alive=%d\n", keep_alive);}
}int process_is_alive(const char *process)
{FILE *fp = NULL;int pid = 0;char buff_tmp[100]={0};sprintf(buff_tmp, "ps -A | grep %s | wc -l", process);fp = popen(buff_tmp, "r");if(fp){memset(buff_tmp, 0, 100);fgets(buff_tmp, sizeof(buff_tmp)-1, fp);pclose(fp);if(buff_tmp != NULL){pid = atoi(buff_tmp);return pid;}}    return -1;
}void kill_process(const char *process, int level)
{FILE *fp = NULL;int pid = 0;char buff_tmp[100]={0}, *p_buff=NULL, *p_buff1=NULL;sprintf(buff_tmp, "ps -A | grep %s", process);fp = popen(buff_tmp, "r");if(fp){memset(buff_tmp, 0, 100);while(fgets(buff_tmp, sizeof(buff_tmp)-1, fp) >0){p_buff = buff_tmp;while(p_buff!=NULL && *p_buff!='\0' && *p_buff==' ') p_buff++;p_buff1 = p_buff;while(p_buff1!=NULL && *p_buff1!='\0' && *p_buff1!=' ') p_buff1++;*p_buff1 = '\0';pid = atoi(p_buff);if( kill(pid, level) == 0)     // kill(pid, 15)printf_t("===>杀死后台%s进程(%d)(-%d) success\n",process,  pid, level);}pclose(fp);}
}void kill_all_process(void)
{if( process_is_alive("dnsmasq") >= 1){kill_process("dnsmasq", 15);     // kill -15usleep(10000);       //10ms 后重新检测是否关注成功if( process_is_alive("dnsmasq") >= 1){kill_process("dnsmasq", 9); // 暴力关闭 kill -9}}if( process_is_alive("hostapd") >= 1){kill_process("hostapd", 15);     // kill -15sleep(1);        //1ms 后重新检测是否关注成功if( process_is_alive("hostapd") >= 1){kill_process("hostapd", 9); // 暴力关闭 kill -9}}
}int main(int argc, char *argv[]){// 注册异常处理函数signal( SIGINT, sig_handler );signal( SIGABRT, sig_handler );signal( SIGTERM, sig_handler );signal( SIGKILL, sig_handler );// 1. 启动前杀死现有的 dnsmasq 和 hostapdkill_all_process();usleep(200000);// 2. 启动 hostapdsystem("iw phy0 interface add wlan1 type managed");system("ifconfig wlan1 up");sleep(1);system("ifconfig wlan1 192.168.50.1 netmask 255.255.255.0");system("route add default gw  192.168.50.1 wlan1");printf_t("===>运行命令:dnsmasq -C /data/bin/dnsmasq_softap.conf  --interface=wlan1\n");system("dnsmasq -C /data/bin/dnsmasq_softap.conf  --interface=wlan1");printf_t("===>运行命令:hostapd /data/bin/hostapd.conf -t -B\n");system("hostapd /data/bin/hostapd.conf -t -B");printf_t("===>开始循环监控dnsmasq 和 hostapd -------\n");while(keep_alive == 1){sleep(1);if( process_is_alive("dnsmasq") == 0){printf_t("===>dnsmasq进程异常,开始关闭hostap\n");break;}if( process_is_alive("hostapd") == 0){printf_t("===>hostapd进程异常,开始关闭hostap\n");break;}}// 3. 恢复初始状态kill_all_process();printf_t("===>route del -net 192.168.50.0 netmask 255.255.255.0 dev wlan1\n");system("route del -net 192.168.50.0 netmask 255.255.255.0 dev wlan1");printf_t("===>ifconfig wlan1 down\n");system("ifconfig wlan1 down");system("iw dev wlan1 del");printf_t("程序运行结束-------------\n");return 0;
}

【瑞芯微Rockchip Linux平台】SoftAp需求实现(1)进程代码实现相关推荐

  1. 【瑞芯微Rockchip Linux平台】SoftAp需求实现(3)动态获取BT Mac地址并更新beacon帧中的mac信息

    [瑞芯微Rockchip Linux平台]SoftAp需求实现(3)动态获取BT Mac地址并更新beacon帧中的mac信息 1. 获取本机的蓝牙mac地址 __get_bt_mac_addr() ...

  2. 【瑞芯微Rockchip Linux平台】SoftAp需求实现(2)根据传参修改SSID和密码,SSID以wifi MAC地址后四位对结尾

    [瑞芯微Rockchip Linux平台]SoftAp需求实现(2)根据传参修改SSID和密码 1. main 函数实现 2. set_hostap_ssid 函数,配置修改hostapd.conf文 ...

  3. 基于瑞芯微3399的嵌入式linux,瑞芯微x3399 linux QT平台WIFI移植详解

    原标题:瑞芯微x3399 linux QT平台WIFI移植详解 第1章 内核配置 硬件平台:x3399开发板或ibox3399卡片电脑 操作系统:linux4.4.5+ QT5.6 WIFI型号:AP ...

  4. 华北工控EMB3581 瑞芯微Rockchip RK3568,python部署rknn_toolkit_lite2

    EMB-3581 瑞芯微Rockchip RK3568 处理器,2LAN,4USB3.0,4USB2.0,7COM,3.5寸板 ◆ 支持瑞芯微Rockchip RK3568处理器 ◆ 板载4GB LP ...

  5. 瑞芯微 Rockchip RKNN-Toolkit 环境搭建

    瑞芯微 Rockchip RKNN-Toolkit 环境搭建 flyfish RKNN-Toolkit介绍 RKNN-Toolkit是一个软件开发工具包,为用户提供在 PC 和 Rockchip NP ...

  6. Banana Pi BPI-R2 Pro 开源路由器采用瑞芯微Rockchip RK3568芯片方案设计

    Banana Pi BPI-R2 Pro 开源路由器采用Rockchip RK3568芯片方案设计, 板载2GB LPDDR4内存和16GB eMMC存储,支持2个USB 3.0接口,5千兆网口.M. ...

  7. 瑞芯微rockchip PX30触摸屏调试记录

    系列文章目录 瑞芯微rockchip PX30 串口调试记录 瑞芯微rockchip PX30 显示屏调试 瑞芯微rockchip PX30触摸屏调试记录 瑞芯微rockchip PX30 QT环境搭 ...

  8. 瑞芯微Rockchip出品的驱动安装助手DriverAssitant v4.6

    关键词: 瑞芯微 Rockchip  RK3308  RK3399  驱动安装  DriverAssitant  V4.6  MASKROM  LOADER 驱动安装比较简单,直接点击"驱动 ...

  9. 基于瑞芯微RV1109 Linux触摸屏GT911驱动调试心得(二)-设备树刷厂商给的触摸屏固件...

    之前调试触摸屏的文章如下: 基于瑞芯微RV1109 Linux触摸屏GT911驱动调试心得_Bruce.yang的嵌入式之旅-CSDN博客 由于之前调触摸屏一直都对不上点,然后厂商又给了我新的驱动代码 ...

最新文章

  1. GIS+=地理信息+云计算技术——Spark集群部署
  2. 刘偲:AI+艺术 | 青源 Talk 第 11 期
  3. git 拉取远程分支到本地
  4. Spring面试问题
  5. 简明Python3教程 16.标准库
  6. 显示客户端接收什么服务器,什么是显示服务器,用来做什么?
  7. 常用位操作以及相关原理
  8. 文件读入简单操作(C#)
  9. nmap命令教程详解
  10. python isupper_一日一技:python中的string.isupper方法
  11. swagger knife4j 解决接口下载文件响应乱码问题
  12. USACO-Tea Time
  13. bycompare 工具使用
  14. MATLAB中classify函数的使用
  15. ISO9001质量体系认证办理流程有哪些
  16. flutter混淆编译生成releaseAPK文件
  17. SpringBoot系列(三)----某程序猿竟然因为“日志”问题一夜秃头
  18. Doxygen + Graphviz windows+Windows Help Workshop下安装配置(图解)
  19. Java简历石投大海了无音讯,是否是互联网寒冬所致?
  20. 比起银隆大股东,这才是董明珠多年来最大的敌人

热门文章

  1. 树莓派Pi Pico套件 MicroPython编程
  2. 学习JavaScript周总结
  3. 共创共建共享,2023北京老博会陪伴企业成长宣传计划开启
  4. mac安装ohmyzsh
  5. vux 选择器_Picker 组件使用教程 - VUX 中文文档
  6. 2023 最新zibi子比转盘抽奖插件 开源
  7. 网传大众收购华为自动驾驶业务的背后:早有合作渊源,欲与特斯拉“硬刚”?...
  8. 研华EKI-2728交换机拆解 BCM53118 RTL8380M
  9. 【模糊理论】模糊矩阵的合成、并交补运算代码
  10. Solaris 9 x86 u7 for vmware 安装指南