/* 广播数据(信标) 基站协议V0.95 section2.3设置发信息信标 键盘协议V0.99-11 section 2.4 广播信息信标 */ #include "base_core_user.h" #include "string.h" #include "function.h" #include "function_interface.h" #define SLOT_MAX 255//128 //Max is 0xff from protocol!! struct content_STR{ //2.3.2发送的内容 unsigned char dcmd; unsigned char slotmax; // unsigned char slotn; unsigned char data[SLOT_MAX][16]; //128,Max=0xff }; struct broadcast_STR{ //2.3.1发送参数 unsigned char type; unsigned char times; unsigned char slots; //2.3.2发送的内容 struct content_STR content[2]; //2.3.3启动发送和结果 unsigned char id_sn_broad; unsigned char id_sn[6]; unsigned char startup_dcmd; //user var unsigned char on_off_flag; unsigned char execute_times; unsigned char slot_seq; unsigned char cur_type; //keypad request unsigned char keypad_request_step; unsigned char data_pos; }; struct broadcast_STR broadcast={ .data_pos =0, }; /* -------------------------------------------------------- 基站保存来自sdk的广播数据 */ void broadcast_config(const unsigned char *rx_pc) { unsigned char type;//题型 // unsigned char ack_flag=1; unsigned char ack_buf[20]={1}; unsigned char ack_buf_len=1; switch(rx_pc[3]){ case 11: memcpy(&broadcast.type,rx_pc+4,3); break; case 12: //20200811,增加sdk从基站读回题型数据。基站部分V0.96 section2.3.2 //if( (rx_pc[4] !=1) && (rx_pc[4] !=2) ) break; if( (rx_pc[4] ==1) || (rx_pc[4] ==2) ) { if( rx_pc[6] >=SLOT_MAX) break;//防止数组溢出 type=rx_pc[4]-1; broadcast.content[type].dcmd = rx_pc[4]; broadcast.cur_type =type; broadcast.content[type].slotmax =rx_pc[5]; memcpy(&broadcast.content[type].data[rx_pc[6]] ,rx_pc+7,16); } else if(rx_pc[4] &0x80){ //sdk读题型数据 if( rx_pc[6] >=SLOT_MAX) break;//防止数组溢出 type=(rx_pc[4]&~0x80) -1; ack_buf[1] =broadcast.content[type].slotmax; //byte5 ack_buf[2] =rx_pc[6]; memcpy(ack_buf+3,&broadcast.content[type].data[rx_pc[6]] ,16); ack_buf_len =19; } break; case 13: memcpy(&broadcast.id_sn_broad,rx_pc+4,8); break; default:ack_buf_len=0;break; }//sw if(ack_buf_len) user__pc_cmd_ack(0x60,rx_pc[3],ack_buf,ack_buf_len); } //unsigned char broad_cast_cnt; /*--------------------------------------------- 发送广播信标子函数 input: type -题型 seq -数据包号 */ static void base_broadcast_sub(unsigned char type,unsigned char seq) { unsigned char tmp[32+1]; tmp[0] = 32;//31; base_core.get_match_code(tmp+1); tmp[5] = ( base_core.get_log_mode() <=3)?0x31:0x32; //id or SN tmp[6] = 0x00; tmp[7] = 0x00; //byte8-11 Keypad SN // tmp[12] = broadcast.content[type].dcmd | (broadcast.data_pos <<4); //DCMD,High 4bit is datapos tmp[12] = (broadcast.content[type].dcmd&0x0f) | (base_core.get_vote_datapos() <<4); //DCMD,High 4bit is datapos tmp[13] = 0; tmp[14] =broadcast.content[type].slotmax ;//slotMax tmp[15] = seq; //broadcast.content[type].slotn ; //slot_seq memcpy(tmp+16,broadcast.content[type].data[seq],16); tmp[32] =crc16(tmp+5,27)&0xff; //CRC //broad_cast_cnt++; #ifdef _DEBUG_CORE_ SEGGER_RTT_printf(0,"pd:%02x,seq:%d\n",tmp[12],tmp[15]); #endif base_core.send_rf_data(tmp,base_core.get_mainRF_hard_id()); } /* 启动广播的条件 a,监测到 测验题-多题型; 表决器V0.99-11 section2.2.13 b,接收到 键盘没有收齐数据的 请求; 教育新版-表决器V0.99-11 section3.2.6 */ void startup_broadcast(void) { if( !function.BROADCAST__SW) return; if(broadcast.on_off_flag==1) return; //如果正在进行广播信息,就不要再启动了!!!! base_core.switch_send_beacon(0);// turn off send beacon broadcast.data_pos++; broadcast.on_off_flag =1; broadcast.execute_times = 0; broadcast.slot_seq =0; // broadcast.cur_type =0;//由进入的模式决定debug only } /* //2021.05.10 客诉描述:多题型模式下,重新拔插基站后导致键盘无法开机--其实是键盘显示白屏; 原因:多题型模式下,题型内容不保存,拔插基站后题型内容丢失;但是还是在多题型模式下。 解决办法:在开始广播多题型时,增加判断是否存在题型内容;如果没有就强制退出并切换到空闲模式下。 */ unsigned char det_blank_content(void) { if( (broadcast.content[0].slotmax==0) &&(broadcast.content[1].slotmax==0) ){ //force exit multi content,exit sysmode0; broadcast.on_off_flag =0; base_core.force_sysmode0(); base_core.switch_send_beacon(1); return 1; } return 0; } /*---------------------------------------------------------- * 特殊处理 来自键盘的“广播信息不完整”的请求; * 基站收到键盘请求后,需要按正常周期给键盘ack,然后才开始启动广播发送; * 当然如果当前正在发广播信号,就不必再启动发送了!! *具体做法:在发送基础/投票信标时(此时基站一定是已经发送了对键盘请求的ack)判断是如果收到了键盘请求,就开启广播模式; * input:request =1 ,接收键盘申请输入参数;other:startup * return */ unsigned char process_keypad_broadcast_requst(unsigned char request) { if( !function.BROADCAST__SW) return 0; if( request ==1){ if(det_blank_content() ) return 0; broadcast.keypad_request_step = request; } else{ if(broadcast.keypad_request_step){ broadcast.keypad_request_step=0; startup_broadcast(); return 1; } } return 0; } unsigned char led_cnt;//debug only /* called by 2.5ms and turn off send beacon!! */ void base_broadcast_process_2ms5(void) { if( !function.BROADCAST__SW) return; if( !broadcast.on_off_flag) return; if(broadcast.slot_seq >= SLOT_MAX) return; base_broadcast_sub(broadcast.cur_type,broadcast.slot_seq); // if(++led_cnt>=3){//debug only // led_cnt=0; // operation_debug_io(5);//debug only // } if(++broadcast.slot_seq >= broadcast.content[broadcast.cur_type].slotmax ){ //发送完一个周期了; broadcast.slot_seq =0; if(++broadcast.execute_times >=10){ broadcast.on_off_flag=0; base_core.switch_send_beacon(1); } } }