@ -19,6 +19,35 @@ extern void uuid_unparse(uuid_t uu, char *out);
jt_led_or_group_package_t tags ;
jt_led_or_group_package_t led_ctrl ;
// 灯光命令队列结构体 - 解决竞态条件问题
# define MAX_LIGHT_COMMANDS 32
typedef struct {
char deviceName [ 16 ] ; // 设备名称( 12位十六进制)
char fullTagId [ 16 ] ; // 完整的灯条ID
char taskId [ 64 ] ; // 任务ID
uint16_t tagCodeHead ; // 灯条ID头部
uint32_t tagCode ; // 灯条ID
uint8_t color ; // 颜色设置
uint8_t sound ; // 声音设置
uint8_t flash ; // 闪烁设置
int duration ; // 持续时间
int beep ; // 蜂鸣器状态
int flash_value ; // 闪烁值(用于上报)
int light_r ; // 红色
int light_g ; // 绿色
int light_b ; // 蓝色
bool is_valid ; // 命令是否有效
uint64_t sequence ; // 序列号,用于跟踪
} light_command_t ;
// 命令队列和相关变量
light_command_t light_commands [ MAX_LIGHT_COMMANDS ] ;
int light_command_head = 0 ;
int light_command_tail = 0 ;
pthread_mutex_t lightCommandMutex = PTHREAD_MUTEX_INITIALIZER ;
uint64_t command_sequence = 0 ;
// 函数声明
void light_status_report ( void ) ;
void update_app ( void ) ;
@ -128,7 +157,7 @@ int fd;
int UPCASE = 0 ;
int count_value = 0 ;
int getPayloadTime = 100 * 1000 ; //usecond
char softwareVersion [ 16 ] = " 2.1.2 6 " ;
char softwareVersion [ 16 ] = " 2.1.2 7 " ;
//char stationsn[16]="d126ei4lj4cc00";//TJ250995217957
//char productid[8]="10045";
//char appSecret[64]="s3izIliw0CF48Pcsi16rjOmoFRf5WEt8";
@ -169,6 +198,22 @@ char lightsn19[7]={0};
char lightsn20 [ 7 ] = { 0 } ;
char lightsn21 [ 7 ] = { 0 } ;
char lightsn22 [ 7 ] = { 0 } ;
// 【修复】添加全局变量保存当前设备的tagCode, 避免竞态条件
uint32_t g_current_tagCode = 0 ;
uint16_t g_current_tagCodeHead = 0 ;
// 【增强】添加设备特定的tagCode映射, 解决多设备并发问题
typedef struct {
char deviceName [ 16 ] ;
uint32_t tagCode ;
uint16_t tagCodeHead ;
uint64_t timestamp ; // 时间戳,用于清理过期映射
} device_tag_mapping_t ;
# define MAX_DEVICE_MAPPINGS 16
device_tag_mapping_t g_device_mappings [ MAX_DEVICE_MAPPINGS ] ;
pthread_mutex_t deviceMappingMutex = PTHREAD_MUTEX_INITIALIZER ;
char lightsn23 [ 7 ] = { 0 } ;
char lightsn24 [ 7 ] = { 0 } ;
char lightsn25 [ 7 ] = { 0 } ;
@ -194,6 +239,18 @@ void add_pending_light_task(uint16_t tagCodeHead, uint32_t tagCode, const char *
void report_light_success ( uint16_t tagCodeHead , uint32_t tagCode ) ;
void report_light_off ( uint16_t tagCodeHead , uint32_t tagCode ) ;
// 命令队列操作函数
int add_light_command ( const char * deviceName , const char * taskId , uint16_t tagCodeHead , uint32_t tagCode ,
uint8_t color , uint8_t sound , uint8_t flash , int duration ,
int beep , int flash_value , int r , int g , int b ) ;
int get_light_command ( light_command_t * cmd ) ;
void clear_light_command_queue ( void ) ;
// 【新增】设备映射管理函数
void add_device_mapping ( const char * deviceName , uint16_t tagCodeHead , uint32_t tagCode ) ;
int get_device_tag_mapping ( const char * deviceName , uint32_t * tagCode , uint16_t * tagCodeHead ) ;
void cleanup_expired_mappings ( void ) ;
/*================================================================================*/
// 上报灯条子设备登录
void report_lightbar_login ( uint16_t tagCodeHead , uint32_t tagCode ) {
@ -229,8 +286,8 @@ void report_lightbar_login(uint16_t tagCodeHead, uint32_t tagCode) {
" { \" password \" : \" %s \" , \" timestamp \" :%ld, \" signingAlgorithm \" : \" %s \" } " ,
password , timestamp , MQTT_ALGORITHM ) ;
LOG_I ( " Lightbar login report - topic: %s \n " , topic ) ;
LOG_I ( " Lightbar login report - payload: %s \n " , payload ) ;
//LOG_I("Lightbar login report - topic: %s\n", topic);
//LOG_I("Lightbar login report - payload: %s\n", payload);
// 发送MQTT消息
mqtt_utils_publish ( & mqtt_config , topic , 0 , payload , strlen ( payload ) ) ;
@ -407,6 +464,154 @@ void report_light_off(uint16_t tagCodeHead, uint32_t tagCode) {
LOG_I ( " No pending light task found for light-off report for tag %08X \n " , tagCode ) ;
}
/*================================================================================*/
// 命令队列操作函数实现
// 添加灯光命令到队列
int add_light_command ( const char * deviceName , const char * taskId , uint16_t tagCodeHead , uint32_t tagCode ,
uint8_t color , uint8_t sound , uint8_t flash , int duration ,
int beep , int flash_value , int r , int g , int b ) {
pthread_mutex_lock ( & lightCommandMutex ) ;
// 检查队列是否已满
int next_tail = ( light_command_tail + 1 ) % MAX_LIGHT_COMMANDS ;
if ( next_tail = = light_command_head ) {
LOG_I ( " Light command queue is full! \n " ) ;
pthread_mutex_unlock ( & lightCommandMutex ) ;
return - 1 ;
}
// 添加新命令
light_command_t * cmd = & light_commands [ light_command_tail ] ;
memset ( cmd , 0 , sizeof ( light_command_t ) ) ;
strncpy ( cmd - > deviceName , deviceName , sizeof ( cmd - > deviceName ) - 1 ) ;
strncpy ( cmd - > fullTagId , deviceName , sizeof ( cmd - > fullTagId ) - 1 ) ;
strncpy ( cmd - > taskId , taskId , sizeof ( cmd - > taskId ) - 1 ) ;
cmd - > tagCodeHead = tagCodeHead ;
cmd - > tagCode = tagCode ;
cmd - > color = color ;
cmd - > sound = sound ;
cmd - > flash = flash ;
cmd - > duration = duration ;
cmd - > beep = beep ;
cmd - > flash_value = flash_value ;
cmd - > light_r = r ;
cmd - > light_g = g ;
cmd - > light_b = b ;
cmd - > is_valid = true ;
cmd - > sequence = + + command_sequence ;
LOG_I ( " Added light command to queue - device: %s, seq: %llu, RGB: %d,%d,%d \n " ,
deviceName , cmd - > sequence , r , g , b ) ;
light_command_tail = next_tail ;
pthread_mutex_unlock ( & lightCommandMutex ) ;
return 0 ;
}
// 从队列获取灯光命令
int get_light_command ( light_command_t * cmd ) {
pthread_mutex_lock ( & lightCommandMutex ) ;
if ( light_command_head = = light_command_tail ) {
// 队列为空
pthread_mutex_unlock ( & lightCommandMutex ) ;
return - 1 ;
}
// 获取命令
* cmd = light_commands [ light_command_head ] ;
light_command_head = ( light_command_head + 1 ) % MAX_LIGHT_COMMANDS ;
LOG_I ( " Got light command from queue - device: %s, seq: %llu \n " ,
cmd - > deviceName , cmd - > sequence ) ;
pthread_mutex_unlock ( & lightCommandMutex ) ;
return 0 ;
}
// 清空命令队列
void clear_light_command_queue ( void ) {
pthread_mutex_lock ( & lightCommandMutex ) ;
light_command_head = 0 ;
light_command_tail = 0 ;
memset ( light_commands , 0 , sizeof ( light_commands ) ) ;
LOG_I ( " Light command queue cleared \n " ) ;
pthread_mutex_unlock ( & lightCommandMutex ) ;
}
// 【新增】设备映射管理函数实现
void add_device_mapping ( const char * deviceName , uint16_t tagCodeHead , uint32_t tagCode ) {
pthread_mutex_lock ( & deviceMappingMutex ) ;
// 查找是否已存在该设备的映射
int existing_index = - 1 ;
for ( int i = 0 ; i < MAX_DEVICE_MAPPINGS ; i + + ) {
if ( strcmp ( g_device_mappings [ i ] . deviceName , deviceName ) = = 0 ) {
existing_index = i ;
break ;
}
}
// 如果不存在,找一个空位
if ( existing_index = = - 1 ) {
for ( int i = 0 ; i < MAX_DEVICE_MAPPINGS ; i + + ) {
if ( strlen ( g_device_mappings [ i ] . deviceName ) = = 0 ) {
existing_index = i ;
break ;
}
}
}
// 如果找到位置,更新映射
if ( existing_index ! = - 1 ) {
strncpy ( g_device_mappings [ existing_index ] . deviceName , deviceName , sizeof ( g_device_mappings [ existing_index ] . deviceName ) - 1 ) ;
g_device_mappings [ existing_index ] . tagCodeHead = tagCodeHead ;
g_device_mappings [ existing_index ] . tagCode = tagCode ;
g_device_mappings [ existing_index ] . timestamp = time ( NULL ) * 1000 ; // 毫秒时间戳
LOG_I ( " Added/Updated device mapping: %s -> %08X \n " , deviceName , tagCode ) ;
} else {
LOG_I ( " Device mapping table full! \n " ) ;
}
pthread_mutex_unlock ( & deviceMappingMutex ) ;
}
int get_device_tag_mapping ( const char * deviceName , uint32_t * tagCode , uint16_t * tagCodeHead ) {
pthread_mutex_lock ( & deviceMappingMutex ) ;
for ( int i = 0 ; i < MAX_DEVICE_MAPPINGS ; i + + ) {
if ( strcmp ( g_device_mappings [ i ] . deviceName , deviceName ) = = 0 ) {
* tagCode = g_device_mappings [ i ] . tagCode ;
* tagCodeHead = g_device_mappings [ i ] . tagCodeHead ;
pthread_mutex_unlock ( & deviceMappingMutex ) ;
return 0 ; // 找到
}
}
pthread_mutex_unlock ( & deviceMappingMutex ) ;
return - 1 ; // 未找到
}
void cleanup_expired_mappings ( void ) {
pthread_mutex_lock ( & deviceMappingMutex ) ;
uint64_t current_time = time ( NULL ) * 1000 ;
uint64_t expire_time = 30 * 1000 ; // 30秒过期
for ( int i = 0 ; i < MAX_DEVICE_MAPPINGS ; i + + ) {
if ( strlen ( g_device_mappings [ i ] . deviceName ) > 0 ) {
if ( current_time - g_device_mappings [ i ] . timestamp > expire_time ) {
LOG_I ( " Cleaning up expired mapping: %s \n " , g_device_mappings [ i ] . deviceName ) ;
memset ( & g_device_mappings [ i ] , 0 , sizeof ( device_tag_mapping_t ) ) ;
}
}
}
pthread_mutex_unlock ( & deviceMappingMutex ) ;
}
/*================================================================================*/
// 上报灯条子设备登出
void report_lightbar_logout ( uint16_t tagCodeHead , uint32_t tagCode ) {
@ -487,7 +692,7 @@ void update_lightbar_heartbeat(uint16_t tagCodeHead, uint32_t tagCode) {
lightbarHeartbeat [ lightbarHeartbeatCount ] . lastHeartbeat = now ;
lightbarHeartbeat [ lightbarHeartbeatCount ] . isOnline = true ;
lightbarHeartbeatCount + + ;
LOG_I ( " New lightbar %04X%08X registered, total: %d \n " , tagCodeHead , tagCode , lightbarHeartbeatCount ) ;
//LOG_I("New lightbar %04X%08X registered, total: %d\n", tagCodeHead, tagCode, lightbarHeartbeatCount);
// 只有MQTT连接后才上报登录
if ( isMqttConnected ) {
report_lightbar_login ( tagCodeHead , tagCode ) ;
@ -1946,11 +2151,57 @@ void *thread_uart_recv_ack(void *arg){
if ( ret > 0 ) {
LOG_I ( " ack:%x \n " , parm_ack ) ;
if ( parm_ack = = 0x2323 ) {
// 【关键修改】从命令队列获取命令,而不是使用全局变量
light_command_t cmd ;
if ( get_light_command ( & cmd ) ! = 0 ) {
LOG_I ( " No light command in queue, using fallback global variables \n " ) ;
// 队列为空时的回退处理(保持兼容性)
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
strncpy ( cmd . deviceName , g_mqtt_deviceName , sizeof ( cmd . deviceName ) - 1 ) ;
cmd . color = changecolor ;
cmd . sound = changesound ;
cmd . flash = changeflash ;
// 【修复】明确设置RGB值, 确保熄灭命令检测正确工作
if ( changecolor = = 0 ) {
cmd . light_r = 0 ;
cmd . light_g = 0 ;
cmd . light_b = 0 ;
}
// 【增强】优先使用设备映射,解决多设备并发问题
uint32_t mapped_tagCode ;
uint16_t mapped_tagCodeHead ;
// 【修复】优先使用命令中保存的deviceName, 而不是可能被覆盖的全局变量
const char * target_deviceName = cmd . deviceName ;
if ( strlen ( target_deviceName ) = = 0 ) {
// 如果命令中没有deviceName, 才使用全局变量
target_deviceName = g_mqtt_deviceName ;
}
// 【新增】检查是否是熄灭命令,如果是,避免在多设备场景下处理
if ( cmd . light_r = = 0 & & cmd . light_g = = 0 & & cmd . light_b = = 0 ) {
LOG_I ( " Fallback detected OFF command for %s (RGB=0,0,0), skipping to avoid multi-device conflicts \n " , target_deviceName ) ;
continue ; // 直接跳过所有熄灭回退命令,避免干扰点亮命令
}
if ( get_device_tag_mapping ( target_deviceName , & mapped_tagCode , & mapped_tagCodeHead ) = = 0 ) {
cmd . tagCode = mapped_tagCode ;
cmd . tagCodeHead = mapped_tagCodeHead ;
LOG_I ( " Fallback: using device mapping for %s -> %08X \n " , target_deviceName , cmd . tagCode ) ;
} else {
// 回退到全局变量
cmd . tagCode = g_current_tagCode ;
cmd . tagCodeHead = g_current_tagCodeHead ;
LOG_I ( " Fallback: using global variables for %s -> %08X \n " , target_deviceName , cmd . tagCode ) ;
}
}
// 使用队列中的命令参数构建控制包
jt_led_or_group_package_t led_ctrl = {
. s . color = changecolor ,
. s . sound = changesound ,
. s . color = c md. color,
. s . sound = c md. sound,
. s . single = 0 ,
. s . flash = changeflash ,
. s . flash = c md. flash,
} ; //0xC1 11000001 flash高位
jt_led_or_group_package_t group = {
. group = groupno ,
@ -2005,40 +2256,19 @@ void *thread_uart_recv_ack(void *arg){
uint32_t tag9 = strtol ( " 014BEE " , NULL , 16 ) ;
uint32_t tag10 = strtol ( " 014BF0 " , NULL , 16 ) ;
# else
uint32_t tag1 = strtol ( lightsn1 , NULL , 16 ) ;
LOG_I ( " lightsn1=%s, tag1=%08X, tag_bytes: %02X %02X %02X \n " ,
lightsn1 , tag1 , ( tag1 > > 16 ) & 0xFF , ( tag1 > > 8 ) & 0xFF , tag1 & 0xFF ) ;
uint32_t tag2 = strtol ( lightsn2 , NULL , 16 ) ;
uint32_t tag3 = strtol ( lightsn3 , NULL , 16 ) ;
uint32_t tag4 = strtol ( lightsn4 , NULL , 16 ) ;
uint32_t tag5 = strtol ( lightsn5 , NULL , 16 ) ;
uint32_t tag6 = strtol ( lightsn6 , NULL , 16 ) ;
uint32_t tag7 = strtol ( lightsn7 , NULL , 16 ) ;
uint32_t tag8 = strtol ( lightsn8 , NULL , 16 ) ;
uint32_t tag9 = strtol ( lightsn9 , NULL , 16 ) ;
uint32_t tag10 = strtol ( lightsn10 , NULL , 16 ) ;
// 【关键修改】使用从队列获取的命令参数
uint32_t tag1 = cmd . tagCode ;
LOG_I ( " Using command from queue - device: %s, seq: %llu, tag1=%08X, RGB: %d,%d,%d \n " ,
cmd . deviceName , cmd . sequence , tag1 , cmd . light_r , cmd . light_g , cmd . light_b ) ;
# endif
uint32_t tag11 = strtol ( lightsn11 , NULL , 16 ) ;
uint32_t tag12 = strtol ( lightsn12 , NULL , 16 ) ;
uint32_t tag13 = strtol ( lightsn13 , NULL , 16 ) ;
uint32_t tag14 = strtol ( lightsn14 , NULL , 16 ) ;
uint32_t tag15 = strtol ( lightsn15 , NULL , 16 ) ;
uint32_t tag16 = strtol ( lightsn16 , NULL , 16 ) ;
uint32_t tag17 = strtol ( lightsn17 , NULL , 16 ) ;
uint32_t tag18 = strtol ( lightsn18 , NULL , 16 ) ;
uint32_t tag19 = strtol ( lightsn19 , NULL , 16 ) ;
uint32_t tag20 = strtol ( lightsn20 , NULL , 16 ) ;
uint32_t tag21 = strtol ( lightsn21 , NULL , 16 ) ;
uint32_t tag22 = strtol ( lightsn22 , NULL , 16 ) ;
uint32_t tag23 = strtol ( lightsn23 , NULL , 16 ) ;
uint32_t tag24 = strtol ( lightsn24 , NULL , 16 ) ;
uint32_t tag25 = strtol ( lightsn25 , NULL , 16 ) ;
uint32_t tag26 = strtol ( lightsn26 , NULL , 16 ) ;
uint32_t tag27 = strtol ( lightsn27 , NULL , 16 ) ;
uint32_t tag28 = strtol ( lightsn28 , NULL , 16 ) ;
uint32_t tag29 = strtol ( lightsn29 , NULL , 16 ) ;
uint32_t tag30 = strtol ( lightsn30 , NULL , 16 ) ;
// 【修复】在多设备场景下, 只发送给目标设备, 其他设备设为0
uint32_t tag2 = 0 , tag3 = 0 , tag4 = 0 , tag5 = 0 , tag6 = 0 , tag7 = 0 , tag8 = 0 , tag9 = 0 , tag10 = 0 ;
uint32_t tag11 = 0 , tag12 = 0 , tag13 = 0 , tag14 = 0 , tag15 = 0 ;
uint32_t tag16 = 0 , tag17 = 0 , tag18 = 0 , tag19 = 0 , tag20 = 0 ;
uint32_t tag21 = 0 , tag22 = 0 , tag23 = 0 , tag24 = 0 , tag25 = 0 ;
uint32_t tag26 = 0 , tag27 = 0 , tag28 = 0 , tag29 = 0 , tag30 = 0 ;
# endif
#if 0
@ -2129,7 +2359,9 @@ void *thread_uart_recv_ack(void *arg){
}
if ( isLightOnById ) {
uart_data_send_lighton_by_id ( & uartSend , 0x00 , 0xFF , 0x00000000 , 0xFFFFFFFF , led_ctrl , 0x0000 ) ;
// 【关键修改】使用从队列获取的命令参数
uart_data_send_lighton_by_id ( & uartSend , 0x00 , 0xFF , cmd . tagCode , cmd . tagCode , led_ctrl , 0x0000 ) ;
LOG_I ( " LightOnById: sent command for device %s, tagCode=%08X \n " , cmd . deviceName , cmd . tagCode ) ;
isLightOnById = false ;
}
@ -2556,6 +2788,7 @@ void *thread_remove_duplicate_tag(void *arg){
void * thread_mqtt_recv ( void * arg ) {
char payload [ 1024 ] = { 0 } ;
char deviceName [ 16 ] = { 0 } ; // 【新增】从队列获取的设备名称
char msg_items [ 1024 ] = { 0 } ;
char msg_item_value [ 1024 ] = { 0 } ;
char msg_colors [ 512 ] = { 0 } ;
@ -2566,7 +2799,20 @@ void *thread_mqtt_recv(void *arg){
int task_id = 0 ;
while ( 1 ) {
if ( isSendComEnd ) {
if ( GetDataFromMQueue ( payload ) = = 0 ) {
// 【修复】优先使用带设备名称的版本
if ( GetDataFromMQueueWithDevice ( payload , deviceName ) = = 0 ) {
// 如果获取到了设备名称,使用它;否则使用全局变量
if ( strlen ( deviceName ) > 0 ) {
strncpy ( g_mqtt_deviceName , deviceName , sizeof ( g_mqtt_deviceName ) - 1 ) ;
LOG_I ( " Using device from queue: %s \n " , g_mqtt_deviceName ) ;
}
} else if ( GetDataFromMQueue ( payload ) = = 0 ) {
// 回退到原来的版本(兼容性)
LOG_I ( " Using legacy queue without device name \n " ) ;
} else {
Sleep ( 100 ) ;
continue ;
}
// 调试用固定payload
//strcpy(payload, "{ \"Items\": [ { \"Beep\": true, \"Colors\": [ { \"B\": false, \"G\": false, \"R\": true } ], \"Flashing\": true, \"TagID\": \"AD1000014C17\" } ], \"Time\": 120 }");
@ -2596,6 +2842,7 @@ void *thread_mqtt_recv(void *arg){
// 解析params中的各个字段
char params_str [ 1024 ] = { 0 } ;
char params_json [ 1024 ] = { 0 } ; // 【修复】移到外面,扩大作用域
char color_json [ 512 ] = { 0 } ; // 提前声明color_json
int params_ret = get_string_from_json_string_by_key ( payload , " params " , params_str , sizeof ( params_str ) ) ;
LOG_I ( " get_string_from_json_string_by_key return: %d \n " , params_ret ) ;
@ -2605,6 +2852,13 @@ void *thread_mqtt_recv(void *arg){
if ( strlen ( params_str ) = = 0 ) {
LOG_I ( " params_str is empty, trying direct parse from payload \n " ) ;
// 直接从payload解析各个字段
// 【新增】解析LightSwitch字段
int light_switch = 1 ; // 默认为开灯
if ( get_int_from_json_string_by_key ( payload , " LightSwitch " , & light_switch ) = = 0 ) {
LOG_I ( " Direct parse LightSwitch = %d \n " , light_switch ) ;
}
int beep_enable = 0 ;
get_int_from_json_string_by_key ( payload , " beep " , & beep_enable ) ;
LOG_I ( " Direct parse Beep = %d \n " , beep_enable ) ;
@ -2638,10 +2892,15 @@ void *thread_mqtt_recv(void *arg){
LOG_I ( " color_json: %s \n " , color_json ) ;
} else {
// 包装params_str为有效的JSON对象
char params_json [ 1024 ] = { 0 } ;
snprintf ( params_json , sizeof ( params_json ) , " {%s} " , params_str ) ;
LOG_I ( " params_json: %s \n " , params_json ) ;
// 【新增】解析LightSwitch字段
int light_switch = 1 ; // 默认为开灯
if ( get_int_from_json_string_by_key ( params_json , " LightSwitch " , & light_switch ) = = 0 ) {
LOG_I ( " Parse LightSwitch = %d \n " , light_switch ) ;
}
int beep_enable = 0 ;
get_int_from_json_string_by_key ( params_json , " beep " , & beep_enable ) ;
LOG_I ( " Beep = %d \n " , beep_enable ) ;
@ -2693,8 +2952,24 @@ void *thread_mqtt_recv(void *arg){
LOG_I ( " RGB values: R=%d, G=%d, B=%d \n " , r_val , g_val , b_val ) ;
// 根据RGB值设置颜色( 0=不亮, 1=亮)
if ( r_val = = 0 & & g_val = = 0 & & b_val = = 0 ) {
changecolor = 0 ; // 不亮
// 【修复】先保存原始RGB值, 用于判断是否是关灯命令
bool is_off_command = false ;
// 如果LightSwitch=0, 标记为关灯命令
int light_switch = 1 ;
if ( strlen ( params_str ) > 0 ) {
get_int_from_json_string_by_key ( params_json , " LightSwitch " , & light_switch ) ;
} else {
get_int_from_json_string_by_key ( payload , " LightSwitch " , & light_switch ) ;
}
if ( light_switch = = 0 ) {
is_off_command = true ;
LOG_I ( " LightSwitch=0 detected, this is an OFF command \n " ) ;
}
if ( r_val = = 0 & & g_val = = 0 & & b_val = = 0 & & ! is_off_command ) {
changecolor = 0 ; // 不亮(非关灯命令时的默认值)
} else if ( r_val = = 1 & & g_val = = 0 & & b_val = = 0 ) {
changecolor = 4 ; // 红色
} else if ( r_val = = 0 & & g_val = = 1 & & b_val = = 0 ) {
@ -2709,8 +2984,10 @@ void *thread_mqtt_recv(void *arg){
changecolor = 3 ; // 青色
} else if ( r_val = = 1 & & g_val = = 1 & & b_val = = 1 ) {
changecolor = 7 ; // 白色
} else if ( is_off_command ) {
changecolor = 0 ; // 关灯命令强制设置为不亮
}
LOG_I ( " changecolor=%d \n " , changecolor ) ;
LOG_I ( " changecolor=%d (is_off_command=%d) \n " , changecolor , is_off_command ) ;
// 判断任务类型: 根据method字段判断是灯条任务还是OTA任务
char method [ 128 ] = { 0 } ;
@ -2729,18 +3006,25 @@ void *thread_mqtt_recv(void *arg){
LOG_I ( " Task ID: %s \n " , taskId ) ;
// 从topic解析出的deviceName获取设备ID
if ( strlen ( g_mqtt_deviceName ) > 0 ) {
LOG_I ( " Device ID from topic: %s \n " , g_mqtt_deviceName ) ;
LOG_I ( " Processing lightbar command, g_mqtt_deviceName: %s \n " , g_mqtt_deviceName ) ;
// 【关键修复】使用从队列获取的设备名称,而不是可能被覆盖的全局变量
if ( strlen ( deviceName ) > 0 ) {
// 【关键修复】立即保存deviceName到局部变量, 避免被其他并发MQTT消息覆盖
char current_deviceName [ 16 ] = { 0 } ;
strncpy ( current_deviceName , deviceName , sizeof ( current_deviceName ) - 1 ) ;
LOG_I ( " Device ID from queue: %s \n " , current_deviceName ) ;
// 将deviceName设置为灯条ID
memset ( mqtt_parm . msg_sn , 0 , sizeof ( mqtt_parm . msg_sn ) ) ;
strncpy ( mqtt_parm . msg_sn , g_mqtt_deviceName , sizeof ( mqtt_parm . msg_sn ) - 1 ) ;
strncpy ( mqtt_parm . msg_sn , curren t_deviceName, sizeof ( mqtt_parm . msg_sn ) - 1 ) ;
LOG_I ( " Set light bar ID: %s \n " , mqtt_parm . msg_sn ) ;
// 获取完整的12位设备ID
int len = strlen ( g_mqtt_deviceName ) ;
int len = strlen ( current_deviceName ) ;
LOG_I ( " Device name length: %d \n " , len ) ;
if ( len = = 12 ) {
char fullTagId [ 13 ] = { 0 } ;
strncpy ( fullTagId , g_mqt t_deviceName, 12 ) ;
strncpy ( fullTagId , curren t_deviceName, 12 ) ;
// 解析前4位作为tagCodeHead和后8位作为tagCode
uint16_t tagCodeHead = 0 ;
@ -2753,7 +3037,14 @@ void *thread_mqtt_recv(void *arg){
sscanf ( head , " %hx " , & tagCodeHead ) ;
sscanf ( tail , " %x " , & tagCode ) ;
// 获取后6位设置到lightsn1
// 【修复】更新全局变量, 保存当前设备的tagCode
g_current_tagCodeHead = tagCodeHead ;
g_current_tagCode = tagCode ;
// 【增强】添加设备映射,解决多设备并发问题
add_device_mapping ( current_deviceName , tagCodeHead , tagCode ) ;
// 获取后6位设置到lightsn1( 保留兼容性)
char * last6 = fullTagId + 6 ;
memset ( lightsn1 , 0 , sizeof ( lightsn1 ) ) ;
strncpy ( lightsn1 , last6 , 6 ) ;
@ -2765,7 +3056,26 @@ void *thread_mqtt_recv(void *arg){
if ( strlen ( taskId ) > 0 ) {
add_pending_light_task ( tagCodeHead , tagCode , taskId , changesound , flash_value , r_val , g_val , b_val , mqtt_parm . msg_duration ) ;
}
// 【关键修改】将命令添加到队列,而不是设置全局变量
// 这样可以避免快速连续命令时的竞态条件
if ( add_light_command ( current_deviceName , taskId , tagCodeHead , tagCode ,
changecolor , changesound , changeflash , mqtt_parm . msg_duration ,
changesound , flash_value , r_val , g_val , b_val ) = = 0 ) {
LOG_I ( " Light command added to queue successfully \n " ) ;
} else {
LOG_I ( " Failed to add light command to queue - queue full! \n " ) ;
}
} else {
LOG_I ( " Device name length is not 12 characters: %s (len=%d) \n " , current_deviceName , len ) ;
}
// 【新增】立即处理队列中的命令,确保不被其他消息干扰
// 这样可以确保每个MQTT消息都能立即触发UART处理
LOG_I ( " Immediately processing command queue for %s \n " , current_deviceName ) ;
} else {
LOG_I ( " g_mqtt_deviceName is empty or null \n " ) ;
}
} else {
// OTA任务或其他任务
@ -2908,7 +3218,7 @@ void *thread_mqtt_recv(void *arg){
}
}
usleep ( getPayloadTime ) ;
}
}
/*================================================================================*/
@ -2998,6 +3308,18 @@ int main(int argc, char *argv[])
char networktype [ 32 ] = { 0 } ;
LOG_I ( " version:%s \n " , softwareVersion ) ;
// 【新增】初始化命令队列
memset ( light_commands , 0 , sizeof ( light_commands ) ) ;
light_command_head = 0 ;
light_command_tail = 0 ;
command_sequence = 0 ;
LOG_I ( " Light command queue initialized \n " ) ;
// 【新增】初始化设备映射
memset ( g_device_mappings , 0 , sizeof ( g_device_mappings ) ) ;
LOG_I ( " Device mapping table initialized \n " ) ;
system ( " insmod /system/lib/modules/wk2xxx_spi.ko " ) ;
system ( " timedatectl set-timezone Asia/Shanghai " ) ;
uart_open ( & uartSend , " /dev/ttyS0 " ) ; //U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1