Commit 6d565a90 authored by 学习的菜鸟's avatar 学习的菜鸟

加入mqtt切网络需要测试

parent 6d5a6a99
......@@ -2,5 +2,5 @@
#define PROJECT_VERSION_MINOR 1
#define PROJECT_VERSION_PATCH 7
#define GIT_HASH ""
#define BUILD_TIMESTAMP "2025-06-05T10:05:06"
#define BUILD_TIMESTAMP "2025-06-06T09:12:32"
#define BUILD_USER "orangepi"
No preview for this file type
......@@ -6,10 +6,11 @@
#define CMD_BUFFER_SIZE 256
#define MAX_WIFI_LIST 100
#define default_SSID jking
#define default_password 12345678
#define default_SSID "jking"
#define default_password "12345678"
#define WIFI_CONF_PATH "/home/orangepi/car/master/device_wifi.conf"
#define WIFI_CONF_DIR "/home/orangepi/car/master"
typedef struct {
char ssid[SSID_MAX_LEN];
......@@ -17,6 +18,7 @@ typedef struct {
} wifi_info_t;
void scan_wifi_json();//显示以连接WiFi名称和周围已有的WiFi和过滤信号强度低于50的WiFi
int wifi_change_sendmqtt_init();//wifi改变初始化,放在main开头,必须要等mqtt直播就绪才行
void wifi_change_recmqtt(cJSON *body);//接收到修改WiFi指令
int delete_wifi_by_ssid(const char* ssid);//忘记指定的WiFi的密码
#endif
\ No newline at end of file
......@@ -14,6 +14,7 @@
#include "judg.h"
#include "ads1115.h"
#include "audioplay.h"
#include "wifichange.h"
struct mosquitto *mosq;
......@@ -299,8 +300,11 @@ int device_message_receive(cJSON *json){//接收到的控制设备的mqtt消息
my_zlog_debug("进入查询WiFi");
break;
case 2004:
wifi_change_recmqtt(body);
my_zlog_debug("进入修改WiFi");
break;
case 2005:download_message(body);
case 2005:
download_message(body);
break;
default:
break;
......
......@@ -10,6 +10,7 @@
#include "common.h"
#include "device_exit.h"
#include "thread_main.h"
#include "wifichange.h"
pthread_t thread[6]; // 全局线程句柄数组(或传参)
......@@ -60,7 +61,8 @@ void *AppExit(void *arg) { //出现意外自动停止
void *Mqttbeat(void *arg) {
//printf("Mqttbeat start\n");
my_zlog_info("Mqttbeat start");
Delay_Ms(15,0);
Delay_Ms(5,0);
wifi_change_sendmqtt_init();
while(1) {
if( AppExit_pin_pwm == 202) Delay_Ms(0,45);
if( AppExit_pin_pwm != 202) Delay_Ms(0,100);
......
......@@ -6,21 +6,7 @@
char current_ssid[SSID_MAX_LEN] = {0};//用于存现在已连接WiFi
int find_ssid(wifi_info_t list[], int count, const char *ssid) {//找重复的WiFi名称
for (int i = 0; i < count; i++) {
if (strcmp(list[i].ssid, ssid) == 0) {
return i;
}
}
return -1;
}
int cmp_signal_desc(const void *a, const void *b) {//进行qsort前,此未降序操作
wifi_info_t *wa = (wifi_info_t *)a;
wifi_info_t *wb = (wifi_info_t *)b;
return wb->signal - wa->signal;
}
//获取当前连接wifi
void get_current_wifi() {
//显示已连接代码
FILE *fp = popen("nmcli -t -f ACTIVE,SSID dev wifi", "r");
......@@ -42,7 +28,23 @@ void get_current_wifi() {
pclose(fp);
}
void scan_wifi_json() { //显示以连接WiFi名称和周围已有的WiFi和过滤信号强度低于50的WiFi
//找重复的WiFi名称
int find_ssid(wifi_info_t list[], int count, const char *ssid) {
for (int i = 0; i < count; i++) {
if (strcmp(list[i].ssid, ssid) == 0) {
return i;
}
}
return -1;
}
//进行qsort前,此未降序操作
int cmp_signal_desc(const void *a, const void *b) {
wifi_info_t *wa = (wifi_info_t *)a;
wifi_info_t *wb = (wifi_info_t *)b;
return wb->signal - wa->signal;
}
//显示以连接WiFi名称和周围已有的WiFi和过滤掉信号强度低于50的WiFi
void scan_wifi_json() {
get_current_wifi();
char line[100];
......@@ -110,7 +112,8 @@ void scan_wifi_json() { //显示以连接WiFi名称和周围已有的WiFi和过
cJSON_Delete(root);
}
int connect_wifi(const char* ssid, const char* password) {//连接WiFi
//连接WiFi
int connect_wifi(const char* ssid, const char* password) {
char cmd[CMD_BUFFER_SIZE];
snprintf(cmd, sizeof(cmd), "nmcli dev wifi connect '%s' password '%s' 2>&1", ssid, password);
......@@ -140,8 +143,8 @@ int connect_wifi(const char* ssid, const char* password) {//连接WiFi
return -4;
}
}
int connect_wifi_with_fallback(const char* ssid, const char* password, const char* fallback_ssid) {//如果连接失败则回退
//如果连接失败则回退
int connect_wifi_with_fallback(const char* ssid, const char* password, const char* fallback_ssid) {
int ret = connect_wifi(ssid, password);
if (ret != 0 && fallback_ssid && fallback_ssid[0] != 0) {
my_zlog_warn("⚠️ 连接失败,尝试回退连接原Wi-Fi:%s", fallback_ssid);
......@@ -156,63 +159,50 @@ int connect_wifi_with_fallback(const char* ssid, const char* password, const cha
my_zlog_debug("✅ 回退连接成功:%s", fallback_ssid);
} else {
my_zlog_warn("❌ 回退连接失败:%s", output);
ret = -5;
}
} else {
my_zlog_error("❌ 无法执行回退连接命令。");
ret = -5;
}
}
return ret;
}
int change_wifi_connect(const char *wifi_ssid, const char *wifi_password) {//改变WiFi连接
//改变WiFi连接
int change_wifi_connect(const char *wifi_ssid,const char *wifi_password) {
get_current_wifi(current_ssid, sizeof(current_ssid));
int ret = connect_wifi_with_fallback(wifi_ssid, wifi_password, current_ssid);
my_zlog_notice("返回代码:%d", ret);
return ret;
}
int can_access_internet() {//测试网络是否连接成功
int ret = system("ping -c 1 -W 1 baidu.com > /dev/null 2>&1");
return ret == 0; // 返回 0 表示 ping 成功
// 连续尝试 2 次 ping,任意一次成功即认为联网成功
int can_access_internet() {
for (int i = 0; i < 4; ++i) {
int ret = system("ping -c 1 -W 1 baidu.com > /dev/null 2>&1");
if (ret == 0) {
return 0; // 有一次成功就返回 true
}
}
return 1; // 都失败
}
int delete_wifi_by_ssid(const char* ssid) {//删除对应wifi
//删除对应wifi
int delete_wifi_by_ssid(const char* ssid) {
if (ssid == NULL || strlen(ssid) == 0) {
fprintf(stderr, "SSID is empty.");
fprintf(stderr, "SSID is empty.\n");
return -1;
}
char command[256];
// 直接尝试删除这个名字的连接(假设连接名就是 SSID)
snprintf(command, sizeof(command), "nmcli connection delete \"%s\"", ssid);
// 构造 nmcli 删除连接命令
snprintf(command, sizeof(command), "nmcli -t -f NAME,TYPE connection show | grep '^%s:wifi$' | cut -d: -f1", ssid);
// 打开管道读取匹配到的连接名
FILE* fp = popen(command, "r");
if (!fp) {
perror("popen failed");
return -1;
}
char conn_name[128];
if (fgets(conn_name, sizeof(conn_name), fp) == NULL) {
my_zlog_debug("No matching WiFi connection found for SSID: %s", ssid);
pclose(fp);
return -1;
}
pclose(fp);
// 去除末尾换行符
conn_name[strcspn(conn_name, "\n")] = 0;
// 构造删除命令
snprintf(command, sizeof(command), "nmcli connection delete \"%s\"", conn_name);
int ret = system(command);
if (ret == 0) {
my_zlog_debug("Successfully deleted WiFi connection: %s", conn_name);
my_zlog_debug("Successfully deleted WiFi connection named: %s", ssid);
} else {
my_zlog_warn("Failed to delete WiFi connection: %s", conn_name);
my_zlog_warn("Failed to delete WiFi connection named: %s", ssid);
}
return ret;
......@@ -237,24 +227,83 @@ int check_or_create_wifi_conf() {
return 0;
}
// 写入 SSID 和密码到文件
int write_wifi_conf(const char *ssid, const char *password) {
// 执行命令并获取结果,通过此函数获取到WiFi密码
char *get_command_output(const char *cmd, char *buffer, size_t size) {
FILE *fp = popen(cmd, "r");
if (!fp) return NULL;
if (fgets(buffer, size, fp)) {
buffer[strcspn(buffer, "\n")] = '\0'; // 去除换行符
}
pclose(fp);
return buffer;
}
// 写入当前 WiFi SSID 和密码到配置文件
int write_wifi_conf() {
char ssid[128] = {0};
char cmd[256];
char password[128] = {0};
// 获取 SSID
if (!get_command_output("iwgetid -r", ssid, sizeof(ssid))) {
fprintf(stderr, "获取当前连接的 SSID 失败\n");
return -1;
}
// 从 NetworkManager 配置中获取密码
snprintf(cmd, sizeof(cmd),
"grep -r '^psk=' /etc/NetworkManager/system-connections/ | grep '%s' | head -n1 | cut -d'=' -f2",
ssid);
if (!get_command_output(cmd, password, sizeof(password))) {
fprintf(stderr, "获取 WiFi 密码失败(可能无权限或未使用 NetworkManager)\n");
return -1;
}
// 写入文件
FILE *fp = fopen(WIFI_CONF_PATH, "w");
if (!fp) {
perror("Failed to open device_wifi.conf for writing");
my_zlog_error("打开配置文件失败");
return -1;
}
fprintf(fp, "SSID=%s\n", ssid);
fprintf(fp, "PASSWORD=%s\n", password);
fclose(fp);
my_zlog_debug("已写入到配置文件: %s\n", WIFI_CONF_PATH);
return 0;
}
//删除对应的存在ssid的conf
void delete_wifi_conf() {
DIR *dir = opendir(WIFI_CONF_DIR);
if (!dir) {
my_zlog_warn("opendir failed");
return;
}
struct dirent *entry;
char full_path[1024];
while ((entry = readdir(dir)) != NULL) {
// 只查找文件名为 "device_wifi.conf"
if (strcmp(entry->d_name, "device_wifi.conf") == 0) {
snprintf(full_path, sizeof(full_path), "%s/%s", WIFI_CONF_DIR, entry->d_name);
if (unlink(full_path) == 0) {
my_zlog_debug("Deleted: %s\n", full_path);
} else {
my_zlog_warn("Failed to delete");
}
break; // 找到并删除就退出
}
}
closedir(dir);
}
// 从文件读取 SSID,比较当前连接的 WiFi 名称
int compare_ssid_with_file() {
char file_ssid[128] = {0};
get_current_wifi();
FILE *fp = fopen(WIFI_CONF_PATH, "r");
if (!fp) {
perror("Failed to open device_wifi.conf");
......@@ -271,17 +320,104 @@ int compare_ssid_with_file() {
}
fclose(fp);
get_current_wifi();
my_zlog_debug("File SSID: %s", file_ssid);
my_zlog_debug("Current SSID: %s", current_ssid);
if (strcmp(file_ssid, current_ssid) == 0) {
my_zlog_debug("WiFi matches the config file.");
return 1;
} else {
my_zlog_debug("WiFi does NOT match the config file.");
my_zlog_debug("wifi没有发生改变或其他问题");
return 0;
} else {
my_zlog_debug("wifi发生改变或其他问题");
return 1;
}
}
/*当wifi_status为1为修改成功,2是继续使用正常wifi,3是恢复到默认jking,4为wifi不存在
,5为密码错误,6为未知错误,7为回退失败*/
void wifichange_sendmqtt(int wifi_status) { //改WiFi发送
topic_middle_value();//指针中间函数
get_current_wifi();
cJSON *root = cJSON_CreateObject();
cJSON *body = cJSON_CreateObject();
cJSON *head = cJSON_CreateObject();
cJSON_AddNumberToObject(body, "wifi_status", wifi_status);//为0成功
cJSON_AddStringToObject(body, "wifi_ssid", current_ssid);//为0成功
cJSON_AddNumberToObject(head, "message_type",3004);
cJSON_AddItemToObject(root, "body", body);
cJSON_AddItemToObject(root, "head",head);
char *payload = cJSON_PrintUnformatted(root);
my_zlog_debug("%s",payload);
mosquitto_publish(mosq, NULL, TOPIC3, strlen(payload), payload, 0, false);
cJSON_Delete(root); // 释放 cJSON 对象
}
//默认连接jking
void connect_wifi_jking() {
if(check_or_create_wifi_conf() == 0) my_zlog_debug("文件已创建");
if(write_wifi_conf() == 0) my_zlog_debug("写入成功");
int ret=change_wifi_connect(default_SSID,default_password);
Delay_Ms(15,0);
if(can_access_internet()==0) {
//system("sudo reboot");//重启香橙派
my_zlog_debug("重启成功");
}
}
int wifi_change_sendmqtt_init(){//wifi改变初始化,放在main开头,必须要等mqtt直播就绪才行
int wififile_fd = compare_ssid_with_file();
if(wififile_fd==0){
wifichange_sendmqtt(1);
delete_wifi_conf();
} else if(wififile_fd==1){
if(can_access_internet()==0) {
wifichange_sendmqtt(2);//2是继续使用正常wifi
delete_wifi_conf();
} else {
wifichange_sendmqtt(3);//3是恢复到默认jking
delete_wifi_conf();
connect_wifi_jking();
}
}
return 0;
}
//接收mqtt消息
void wifi_change_recmqtt(cJSON *body){
cJSON *wifi_ssid = cJSON_GetObjectItem(body, "wifi_ssid");
cJSON *wifi_password = cJSON_GetObjectItem(body, "wifi_password");
cJSON *wifi_status = cJSON_GetObjectItem(body, "wifi_status");
if(cJSON_IsString(wifi_ssid) && cJSON_IsString(wifi_password)){
char *ssid = wifi_ssid->valuestring,*password=wifi_password->valuestring;
int wifi_statustemp = wifi_status->valueint;
if(check_or_create_wifi_conf() == 0) my_zlog_debug("文件已创建");
if(write_wifi_conf() == 0) my_zlog_debug("写入成功");
int ret = change_wifi_connect(ssid,password);
Delay_Ms(15,0);
if(can_access_internet()==0&&ret == 0){
delete_wifi_by_ssid(current_ssid);
my_zlog_debug("ssid:%S",current_ssid);
//system("sudo reboot");//重启香橙派
my_zlog_debug("重启成功");
}
if(ret == -1) {
wifichange_sendmqtt(4);
}else if(ret == -2){
wifichange_sendmqtt(5);
}else if(ret == -3){
wifichange_sendmqtt(6);
}else if(ret == -4 || ret == -5){
wifichange_sendmqtt(7);
//system("sudo reboot");//重启香橙派
my_zlog_debug("重启成功");
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment