Recently, the upper layer has a requirement to start the SoftAp hotspot. If all the implementation processes are recorded.
Link to this article:< [Ruixin micro Rockchip Linux platform] SoftAp requirements implementation (1) process code implementation>
Links to this series of articles:
- <[Ruixin micro Rockchip Linux platform] SoftAp requirements implementation (1) process code implementation>
- Implementation of SoftAp requirements of [Ruixin micro Rockchip Linux platform] (2) modify SSID and password according to transmission parameters
1, SoftAp start command
In fact, these can be achieved by using commands,
-
The open command is as follows:
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 -
The closing command is as follows:
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 -
Other command configuration
2, SoftAp start command encapsulation implementation process
According to the requirements of the upper layer, encapsulate these commands into libraries and executable programs.
For this requirement, I choose to package it into executable program.
2.1 add system time before log
It mainly uses macro control to rewrite the printf function, so that get will be called before printing each log sentence_ cur_ Time gets the current system time, accurate to 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 check whether the process is running process_is_alive()
This is relatively simple. It mainly counts the number of processes through ps -A | grep dnsmasq | wc -l. if the number is greater than 1, it indicates that the current process is running.
This function returns the number of processes running.
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_ process()
Get the output information of the command through popen to parse the process number of the process, and then kill it.
Generally speaking, it is recommended to use kill -15 to kill the process. It will wait for the process to release relevant resources, which is not easy to solve the problem of resource leakage.
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("===>Kill backstage%s process(%d)(-%d) success\n",process, pid, level); } pclose(fp); } }
2.4 cycle to monitor the running status of relevant processes
In the main function, the main work is to start the hostapdf process, and then cycle to monitor the survival status of the hostapd and dnsmasq processes,
As long as any one of the processes has an exception, it will pay attention to the softap hotspot and release relevant resources.
int main(int argc, char *argv[]){ // 1. Kill the existing dnsmasq and hostapd before startup kill_all_process(); usleep(200000); // 2. Start hostapd system("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("===>Run command: dnsmasq -C /data/bin/dnsmasq_softap.conf --interface=wlan1\n"); system("dnsmasq -C /data/bin/dnsmasq_softap.conf --interface=wlan1"); printf_t("===>Run command: hostapd /data/bin/hostapd.conf -t -B\n"); system("hostapd /data/bin/hostapd.conf -t -B"); printf_t("===>Start cycle monitoring dnsmasq and hostapd -------\n"); while(keep_alive == 1){ sleep(1); if( process_is_alive("dnsmasq") == 0){ printf_t("===>dnsmasq Process exception, start shutdown hostap\n"); break; } if( process_is_alive("hostapd") == 0){ printf_t("===>hostapd Process exception, start shutdown hostap\n"); break; } } // 3. Restore the initial state 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("End of program operation-------------\n"); return 0; }
2.5 add exception handling function
Add a global variable keep_alive is used to confirm whether the current process needs to exit actively.
In the main function, register SIGINT, SIGABRT, SIGTERM and SIGKILL signals and bind the function sig_handler,
When the process is running and receives any of the four signals, it will enter sig_handler function, keep_ Live clears 0, ends the loop monitoring in the main function and releases relevant resources.
void sig_handler( int sig ) { if ( sig == SIGINT || sig == SIGABRT || sig == SIGTERM || sig == SIGKILL) { keep_alive = 0; printf_t("===>Stop signal received, keep_alive=%d\n", keep_alive); } } int main(int argc, char *argv[]){ // Register exception handler signal( SIGINT, sig_handler ); signal( SIGABRT, sig_handler ); signal( SIGTERM, sig_handler ); signal( SIGKILL, sig_handler ); }
3, Dnsmasq Conf file configuration
user=root # listen-address=127.0.0.1 except-interface=usb0 #interface=p2p-wlan0-0 # dhcp-option=p2p-wlan0-0,1,255.255.225.0 #Specify mask # dhcp-option=p2p-wlan0-0,3,192.168.50.1 #Specify gateway # dhcp-option=p2p-wlan0-0,6,192.168.50.1 #Specify dns dhcp-range=192.168.50.2,192.168.50.51 # log-queries # log-facility=/data/dnsmasq.log
4, Hostapd Conf file configuration
interface=wlan0 ctrl_interface=/var/run/hostapd driver=nl80211 ssid=soft-ap auth_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
5, Complete code
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <time.h> #include <unistd.h> #include <string.h> #ifdef __cplusplus extern "C" { #endif static 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("===>Stop signal received, 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("===>Kill backstage%s process(%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 -15 usleep(10000); //Check again after 10ms for success if( process_is_alive("dnsmasq") >= 1){ kill_process("dnsmasq", 9); // Violent shutdown kill -9 } } if( process_is_alive("hostapd") >= 1){ kill_process("hostapd", 15); // kill -15 sleep(1); //After 1ms, re check whether the focus is successful if( process_is_alive("hostapd") >= 1){ kill_process("hostapd", 9); // Violent shutdown kill -9 } } } int main(int argc, char *argv[]){ // Register exception handler signal( SIGINT, sig_handler ); signal( SIGABRT, sig_handler ); signal( SIGTERM, sig_handler ); signal( SIGKILL, sig_handler ); // 1. Kill the existing dnsmasq and hostapd before startup kill_all_process(); usleep(200000); // 2. Start hostapd system("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("===>Run command: dnsmasq -C /data/bin/dnsmasq_softap.conf --interface=wlan1\n"); system("dnsmasq -C /data/bin/dnsmasq_softap.conf --interface=wlan1"); printf_t("===>Run command: hostapd /data/bin/hostapd.conf -t -B\n"); system("hostapd /data/bin/hostapd.conf -t -B"); printf_t("===>Start cycle monitoring dnsmasq and hostapd -------\n"); while(keep_alive == 1){ sleep(1); if( process_is_alive("dnsmasq") == 0){ printf_t("===>dnsmasq Process exception, start shutdown hostap\n"); break; } if( process_is_alive("hostapd") == 0){ printf_t("===>hostapd Process exception, start shutdown hostap\n"); break; } } // 3. Restore the initial state 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("End of program operation-------------\n"); return 0; }