Files
BR_YKC/Core/User/Driver/drv_air724.c

260 lines
7.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file User\Driver\drv_air724.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 4G模块(AIR724)驱动
******************************************************************************
*
* 协议55 AA mainCmd subCmd [payload] AA 55
*
* STM32 → 4G:
* 0x03 01 channel 连接请求
* 0x03 02 channel 断开请求
* 0x04 00 ip+port 设置服务器
* 0x05 01|02|03 查询ICCID/IMSI/IMEI
* 0x06 00 查询信号
* 0x07 00 查询链路
*
* 4G → STM32 (0x83):
* 0x83 01 channel 00 已连接
* 0x83 02 channel 00 已断开
* 0x83 03 channel 01 连接失败
*/
#include "drv_air724.h"
#include "drv_usart.h"
Air724_Info_t g_air724_info = {0};
/**
* @brief send_cmd发送命令帧函数
* @note none
* @param main_cmd 主命令 主命令字节
* @param sub_cmd 子命令 子命令字节
* @param payload 数据 数据指针
* @param payload_len 数据长度 数据长度
* @retval none
*/
static void drv_air724_send_cmd(uint8_t main_cmd, uint8_t sub_cmd,
const uint8_t *payload, uint16_t payload_len)
{
uint8_t frame[256];
uint16_t idx = 0;
frame[idx++] = 0x55;
frame[idx++] = 0xAA;
frame[idx++] = main_cmd;
frame[idx++] = sub_cmd;
if (payload && payload_len > 0) {
memcpy(&frame[idx], payload, payload_len);
idx += payload_len;
}
frame[idx++] = 0xAA;
frame[idx++] = 0x55;
Air724_Message_Send(frame, idx);
}
/**
* @brief set_server设置服务器函数
* @note none
* @param ip 服务器IP地址 字符串指针
* @param port 服务器端口 十进制整数
* @retval none
*/
void drv_air724_set_server(const char *ip, uint16_t port)
{
if (!ip) return;
uint8_t payload[128];
uint8_t ip_len = (uint8_t)strlen(ip);
if (ip_len > 100) ip_len = 100;
payload[0] = ip_len;
memcpy(&payload[1], ip, ip_len);
payload[1 + ip_len] = (uint8_t)((port >> 8) & 0xFF);
payload[2 + ip_len] = (uint8_t)(port & 0xFF);
drv_air724_send_cmd(0x04, 0, payload, 3 + ip_len);
}
/**
* @brief connect_channel连接通道函数
* @note none
* @param channel 通道号 通道-1-6
* @retval none
*/
void drv_air724_connect_channel(uint8_t channel)
{
if (channel < 1 || channel > AIR724_SOCKET_MAX) {
printf("[ 4G ] 通道 %d 无效 \r\n", channel);
return;
}
drv_air724_send_cmd(0x03, 0x01, &channel, 1);
printf("[ 4G ] 通道 %d 连接请求已发送 \r\n", channel);
}
/**
* @brief disconnect_channel断开通道函数
* @note none
* @param channel 通道号 通道-1-6
* @retval none
*/
void drv_air724_disconnect_channel(uint8_t channel)
{
if (channel < 1 || channel > AIR724_SOCKET_MAX) {
printf("[ 4G ] 通道 %d 无效\r\n", channel);
return;
}
drv_air724_send_cmd(0x03, 0x02, &channel, 1);
printf("[ 4G ] 通道 %d 断开请求已发送\r\n", channel);
}
/**
* @brief query_iccid查询ICCID函数
* @note none
* @retval none
*/
void drv_air724_query_iccid(void)
{
drv_air724_send_cmd(0x05, 0x01, NULL, 0);
}
/**
* @brief query_imsi查询IMSI函数
* @note none
* @retval none
*/
void drv_air724_query_imsi(void)
{
drv_air724_send_cmd(0x05, 0x02, NULL, 0);
}
/**
* @brief query_imei查询IMEI函数
* @note none
* @retval none
*/
void drv_air724_query_imei(void)
{
drv_air724_send_cmd(0x05, 0x03, NULL, 0);
}
/**
* @brief query_signal查询信号函数
* @note none
* @retval none
*/
void drv_air724_query_signal(void)
{
drv_air724_send_cmd(0x06, 0x00, NULL, 0);
}
/**
* @brief query_link_status查询链路函数
* @note none
* @retval none
*/
void drv_air724_query_link_status(void)
{
drv_air724_send_cmd(0x07, 0x00, NULL, 0);
}
/**
* @brief parse_response解析响应帧函数
* @note none
* @param frame 响应帧 响应帧指针
* @param len 响应帧长度 响应帧长度
* @retval none
*/
void drv_air724_parse_response(const uint8_t *frame, uint16_t len)
{
if (!frame || len < 7) return;
uint8_t main_cmd = frame[2];
uint8_t sub_cmd = frame[3];
switch (main_cmd) {
/* ── 0x83: 连接/断开/失败通知 ── */
case 0x83:
if (len >= 7) {
uint8_t socket_id = frame[4];
if (socket_id < 1 || socket_id > AIR724_SOCKET_MAX) break;
switch (sub_cmd) {
case 0x01:
g_air724_info.socket_connected[socket_id - 1] = 1;
printf("[ 4G ] 通道 %d 连接成功\r\n", socket_id);
break;
case 0x02:
g_air724_info.socket_connected[socket_id - 1] = 0;
printf("[ 4G ] 通道 %d 已断开\r\n", socket_id);
break;
case 0x03:
g_air724_info.socket_connected[socket_id - 1] = 0;
printf("[ 4G ] 通道 %d 连接失败\r\n", socket_id);
break;
}
}
break;
/* ── 0x84: SIM信息响应 ── */
case 0x84: {
if (len < 5) break;
uint8_t data_len = frame[4];
if (data_len == 0 || len < (uint16_t)(5 + data_len)) break;
switch (sub_cmd) {
case 0x01:
memcpy(g_air724_info.iccid, &frame[5], data_len < 23 ? data_len : 23);
g_air724_info.iccid[data_len < 23 ? data_len : 23] = '\0';
printf("[ 4G ] ICCID=%s\r\n", g_air724_info.iccid);
break;
case 0x02:
memcpy(g_air724_info.imsi, &frame[5], data_len < 15 ? data_len : 15);
g_air724_info.imsi[data_len < 15 ? data_len : 15] = '\0';
printf("[ 4G ] IMSI=%s\r\n", g_air724_info.imsi);
break;
case 0x03:
memcpy(g_air724_info.imei, &frame[5], data_len < 15 ? data_len : 15);
g_air724_info.imei[data_len < 15 ? data_len : 15] = '\0';
printf("[ 4G ] IMEI=%s\r\n", g_air724_info.imei);
break;
}
break;
}
/* ── 0x85: 信号强度响应 ── */
case 0x85:
if (len >= 7) {
g_air724_info.csq = frame[4];
g_air724_info.ber = frame[5];
printf("[ 4G ] CSQ=%d, BER=%d\r\n", g_air724_info.csq, g_air724_info.ber);
}
break;
/* ── 0x86: 链路状态响应 ── */
case 0x86: {
uint8_t count = (len - 6) < AIR724_SOCKET_MAX ? (len - 6) : AIR724_SOCKET_MAX;
for (uint8_t i = 0; i < count; i++) {
g_air724_info.socket_connected[i] = frame[4 + i];
}
printf("[ 4G ] 链路[");
for (uint8_t i = 0; i < AIR724_SOCKET_MAX; i++) {
printf("%d", g_air724_info.socket_connected[i]);
}
printf("]\r\n");
break;
}
/* ── 0x87: 服务器配置结果 ── */
case 0x87:
if (len >= 6) {
printf("[ 4G ] 服务器配置%s\r\n", frame[4] == 0 ? "成功" : "失败");
}
break;
}
}