Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
car-controlserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wenzhongjian
car-controlserver
Commits
6d565a90
Commit
6d565a90
authored
Jun 06, 2025
by
学习的菜鸟
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
加入mqtt切网络需要测试
parent
6d5a6a99
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
213 additions
and
69 deletions
+213
-69
version.h
build/include/version.h
+1
-1
main
build/main
+0
-0
wifichange.h
include/wifichange.h
+5
-4
mqtt.c
src/mqtt.c
+5
-1
thread_main.c
src/thread_main.c
+3
-1
wifichange.c
src/wifichange.c
+199
-62
No files found.
build/include/version.h
View file @
6d565a90
...
...
@@ -2,5 +2,5 @@
#define PROJECT_VERSION_MINOR 1
#define PROJECT_VERSION_PATCH 7
#define GIT_HASH ""
#define BUILD_TIMESTAMP "2025-06-0
5T10:05:06
"
#define BUILD_TIMESTAMP "2025-06-0
6T09:12:32
"
#define BUILD_USER "orangepi"
build/main
View file @
6d565a90
No preview for this file type
include/wifichange.h
View file @
6d565a90
...
...
@@ -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
src/mqtt.c
View file @
6d565a90
...
...
@@ -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
;
...
...
src/thread_main.c
View file @
6d565a90
...
...
@@ -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
);
...
...
src/wifichange.c
View file @
6d565a90
...
...
@@ -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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment