2025-12-03 10:44:14 +08:00
|
|
|
|
#include "task_func.h"
|
|
|
|
|
|
#include "./nvs/nvs.h"
|
2025-12-02 16:25:20 +08:00
|
|
|
|
#include "timer.h"
|
|
|
|
|
|
#include "system/includes.h"
|
|
|
|
|
|
|
|
|
|
|
|
// 包含BLE HID相关的API
|
|
|
|
|
|
#include "earphone.h" // 宏定义 EARPHONE_STATE_...
|
|
|
|
|
|
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
// 宏定义与日志
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
#define RC_LOG_ENABLE 1
|
|
|
|
|
|
#if RC_LOG_ENABLE
|
|
|
|
|
|
#define rc_log(format, ...) printf("[RC_APP] " format, ##__VA_ARGS__)
|
|
|
|
|
|
#else
|
|
|
|
|
|
#define rc_log(format, ...)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
// 外部函数声明
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
extern void TYPE_V_EVENT(char* uid);
|
2025-12-03 10:44:14 +08:00
|
|
|
|
extern void TYPE_A_EVENT(char* uid);
|
2025-12-02 16:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
// 静态函数声明
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
static RFID_Device_Type_t get_rfid_device_type(const u8* uid);
|
|
|
|
|
|
|
|
|
|
|
|
// BLE 状态转换的辅助函数
|
|
|
|
|
|
static void rc_ble_state_set_connecting(void);
|
|
|
|
|
|
static void rc_ble_state_set_connected(void);
|
|
|
|
|
|
static void rc_ble_state_set_disconnected(void);
|
|
|
|
|
|
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
// 全局变量
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
static RC_Context_t g_rc_context; // 全局上下文实例
|
|
|
|
|
|
static u16 g_rfid_timer_id = 0; // RFID 定时器ID
|
|
|
|
|
|
static u16 g_ble_timer_id = 0; // BLE 定时器ID
|
2025-12-03 10:44:14 +08:00
|
|
|
|
extern const struct ble_client_operation_t client_operation;
|
2025-12-02 16:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
// 核心回调函数 (Core Callback Handlers)
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief RFID回调处理函数 (由定时器周期性调用)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void rc_rfid_callback_handler(void *priv)
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 uid[UID_LENGTH] = {0};
|
|
|
|
|
|
|
2025-12-03 10:44:14 +08:00
|
|
|
|
//读id卡
|
|
|
|
|
|
// TYPE_V_EVENT((char *)uid);
|
|
|
|
|
|
TYPE_A_EVENT((char *)uid);
|
|
|
|
|
|
|
|
|
|
|
|
//是否有rfid卡靠近
|
2025-12-02 16:25:20 +08:00
|
|
|
|
u8 is_new_data = 0;
|
|
|
|
|
|
for (int i = 0; i < UID_LENGTH; i++) {
|
|
|
|
|
|
if (uid[i] != 0x00) {
|
|
|
|
|
|
is_new_data = 1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!is_new_data) {
|
2025-12-03 10:44:14 +08:00
|
|
|
|
return; //没有rfid卡靠近,返回
|
2025-12-02 16:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rc_log("New RFID card detected.\n");
|
|
|
|
|
|
|
|
|
|
|
|
RFID_Device_Type_t device_type = get_rfid_device_type(uid);
|
|
|
|
|
|
|
|
|
|
|
|
switch (device_type) {
|
2025-12-03 10:44:14 +08:00
|
|
|
|
case RFID_DEVICE_TYPE_MAIN_BOARD: //船主板上的rfid卡
|
2025-12-02 16:25:20 +08:00
|
|
|
|
rc_log("Device is Main Board. Storing MAC...\n");
|
|
|
|
|
|
if (ble_hid_is_connected()) {
|
|
|
|
|
|
// 先停止扫描和连接尝试,实现断开
|
|
|
|
|
|
EARPHONE_STATE_CANCEL_PAGE_SCAN();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 将新的MAC地址写入Flash
|
|
|
|
|
|
nvs_write_main_board_mac(uid);
|
|
|
|
|
|
// 重新启动扫描,以连接到新的主板
|
|
|
|
|
|
EARPHONE_STATE_SET_PAGE_SCAN_ENABLE();
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case RFID_DEVICE_TYPE_REMOTE_CONTROL:
|
|
|
|
|
|
rc_log("Device is another Remote Control.\n");
|
|
|
|
|
|
if (g_rc_context.state == RC_STATE_CONNECTED) {
|
|
|
|
|
|
rc_log("Sending teaming request to main board...\n");
|
|
|
|
|
|
// report_id 1 通常用于标准键盘/消费者报告
|
|
|
|
|
|
ble_hid_data_send(1, uid, UID_LENGTH);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
rc_log("Not connected to main board, ignoring teaming request.\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
rc_log("Unknown RFID device type.\n");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief BLE回调处理函数 (由定时器周期性调用)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void rc_ble_callback_handler(void *priv)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool is_connected = ble_hid_is_connected();
|
|
|
|
|
|
|
|
|
|
|
|
// 状态机转换
|
|
|
|
|
|
if (is_connected && g_rc_context.state != RC_STATE_CONNECTED) {
|
|
|
|
|
|
rc_ble_state_set_connected();
|
|
|
|
|
|
} else if (!is_connected && g_rc_context.state != RC_STATE_DISCONNECTED) {
|
|
|
|
|
|
rc_ble_state_set_disconnected();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 状态机行为
|
|
|
|
|
|
switch (g_rc_context.state) {
|
|
|
|
|
|
case RC_STATE_DISCONNECTED:
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 target_mac[MAC_ADDR_LENGTH] = {0};
|
|
|
|
|
|
// 检查Flash中是否有已配对的MAC
|
|
|
|
|
|
if (nvs_read_main_board_mac(target_mac) > 0) {
|
|
|
|
|
|
rc_log("Found paired MAC. Start scanning...\n");
|
|
|
|
|
|
// 启动扫描和连接。SDK的HID实现会自动连接到已配对的设备。
|
|
|
|
|
|
EARPHONE_STATE_SET_PAGE_SCAN_ENABLE();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
rc_log("No paired MAC found. Waiting for RFID pairing...\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case RC_STATE_CONNECTING:
|
|
|
|
|
|
// 在这个状态下,我们只是等待 is_connected 变为 true
|
|
|
|
|
|
rc_log("Waiting for connection result...\n");
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case RC_STATE_CONNECTED:
|
|
|
|
|
|
// 已连接,目前无需周期性操作
|
|
|
|
|
|
// rc_log("BLE is connected.\n");
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 根据UID前缀判断设备类型
|
|
|
|
|
|
*/
|
|
|
|
|
|
static RFID_Device_Type_t get_rfid_device_type(const u8* uid)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (uid == NULL) {
|
|
|
|
|
|
return RFID_DEVICE_TYPE_UNKNOWN;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据 RC_app_main.h 中定义的UID前缀进行判断
|
|
|
|
|
|
if (uid[0] == UID_PREFIX_MAIN_BOARD) {
|
|
|
|
|
|
return RFID_DEVICE_TYPE_MAIN_BOARD;
|
|
|
|
|
|
} else if (uid[0] == UID_PREFIX_REMOTE_CONTROL) {
|
|
|
|
|
|
return RFID_DEVICE_TYPE_REMOTE_CONTROL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return RFID_DEVICE_TYPE_UNKNOWN;
|
|
|
|
|
|
}
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
// 辅助函数 (Helper Functions)
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 进入 CONNECTING 状态的逻辑
|
|
|
|
|
|
*/
|
|
|
|
|
|
static void rc_ble_state_set_connecting(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
rc_log("State transition to -> CONNECTING\n");
|
|
|
|
|
|
g_rc_context.state = RC_STATE_CONNECTING;
|
|
|
|
|
|
// 可以在这里控制LED灯效,例如黄灯呼吸闪烁
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 进入 CONNECTED 状态的逻辑
|
|
|
|
|
|
*/
|
|
|
|
|
|
static void rc_ble_state_set_connected(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
rc_log("State transition to -> CONNECTED\n");
|
|
|
|
|
|
g_rc_context.state = RC_STATE_CONNECTED;
|
|
|
|
|
|
// 停止扫描以省电
|
|
|
|
|
|
EARPHONE_STATE_CANCEL_PAGE_SCAN();
|
|
|
|
|
|
|
|
|
|
|
|
// 发送指令,要求主板连接遥控器的经典蓝牙
|
|
|
|
|
|
u8 classic_conn_req_payload[] = {0x01, 0x02, 0x03};
|
|
|
|
|
|
rc_log("Sending request for classic BT connection.\n");
|
|
|
|
|
|
ble_hid_data_send(0xFE, classic_conn_req_payload, sizeof(classic_conn_req_payload));
|
|
|
|
|
|
|
|
|
|
|
|
// 在这里控制LED灯效,例如蓝灯呼吸闪烁三次后熄灭
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 进入 DISCONNECTED 状态的逻辑
|
|
|
|
|
|
*/
|
|
|
|
|
|
static void rc_ble_state_set_disconnected(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
rc_log("State transition to -> DISCONNECTED\n");
|
|
|
|
|
|
g_rc_context.state = RC_STATE_DISCONNECTED;
|
|
|
|
|
|
// 在这里控制LED灯效,例如黄灯呼吸闪烁
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化函数 (Initialization Function)
|
|
|
|
|
|
// =================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 遥控器应用主初始化函数
|
|
|
|
|
|
*/
|
|
|
|
|
|
void rc_app_main_init(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
rc_log("Initializing Remote Control App...\n");
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 初始化全局上下文
|
|
|
|
|
|
memset(&g_rc_context, 0, sizeof(RC_Context_t));
|
|
|
|
|
|
g_rc_context.state = RC_STATE_DISCONNECTED; // 初始状态为未连接
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 检查并启动RFID处理定时器
|
|
|
|
|
|
if (g_rfid_timer_id == 0) {
|
|
|
|
|
|
g_rfid_timer_id = sys_timer_add(NULL, rc_rfid_callback_handler, RC_RFID_CALLBACK_INTERVAL_MS);
|
|
|
|
|
|
rc_log("RFID handler timer started (ID: %d).\n", g_rfid_timer_id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 检查并启动BLE处理定时器
|
|
|
|
|
|
if (g_ble_timer_id == 0) {
|
|
|
|
|
|
g_ble_timer_id = sys_timer_add(NULL, rc_ble_callback_handler, RC_BLE_CALLBACK_INTERVAL_MS);
|
|
|
|
|
|
rc_log("BLE handler timer started (ID: %d).\n", g_ble_timer_id);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|