/** ****************************************************************************** * @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; } }