#include "sys_config.h" #if PRODUCT_SY #include "sys_processor.h" #include "UWater_eeprom_driver.h" #include "UWater_rtcc_app.h" #include "UWater_power_app.h" #include "UWater_gp22_app.h" #include "UWater_pt_app.h" #include "UWater_DataTools_App.h" #include "UWater_SY_Store_App.h" #include "SOE.h" #include "UWater_frame_func_ReplyNB.h" #include "UWater_frame_func_ReplySYNB.h" static STRUCT_FRAME_SY frame_struct_SY; //沈阳规约信息 static u8 *new_message_data_rev_sy; static u8 up_deal_stat_sy = UP_DEAL_S0; static u8 s_sy_eep_complete=0; static u8 task_complete_sy = PTL_PACK_BUSY; static u8 g_frame_temp_send_buf_sy[UP_BUF_SIZE]; //数据部分缓冲区 static u16 g_frame_temp_len_sy=0; static u8 *temp_send_start_p; static u8 *temp_send_end_p; static u8 *temp_send_end_p1; static u8 temp_check_addr[7]; static u8 upload_serial_num_sy=0; static u8 temp_upload_step=0; static u8 upload_frame_retry_times = 0; //上报周期数据获取 static TYP_STATE_SY upload_frame_stat_sy=SY_STATE_S0; static u8 task_complete_upload_sy = PTL_PACK_BUSY; static u8 task_complete_warning_sy = PTL_PACK_BUSY; static u8 SY_CircleUploadPackets=0; //需要上报的总包数 static u8 SY_CircleThisPacketNum=0;//当前包序号 static u8 SY_CircleThisUploadPacket_Index=0;//当前要上报的数据位置 static u8 SY_CiecleThisUploadPacket_Cnt=0;//当前要上报的数据包数据条数 static u8 SY_CircleUploadBuf[400];//10+16x24=394//周期上报数据缓存 static u16 SY_UploadDataLen=0; static STRUCT_FRAME_SY temp_struct_upload_SY; //上报报警数据获取 static TYP_STATE_SY step_UploadWarningSY = SY_STATE_S0; static u8* temp_warning_start_p; static u8* temp_warning_end_p; //水表向平台端主动发送数据规约 //上传冻结数据(101,应答1) 上报未冻结数据、水表状态、报警等信息 void frame_func_reply_SYNB_UploadFrozenData(void) { task_complete_sy = PTL_PACK_FAIL;//这是上报应答帧,返回错误,表计不应答 } //上报周期数据(102,应答2) 上报周期采集的数据 void frame_func_reply_SYNB_UploadCycleData(void) { if(*(new_message_data_rev_sy + 14) == upload_serial_num_sy) //判断序列号是否正确 { if(*(new_message_data_rev_sy + 19) == 0) //上报是否成功 { FrameSetMsgApp(MsgShenYang_NbUplaod_AckOk); } } task_complete_sy = PTL_PACK_FAIL;//这是上报应答帧,返回错误,表计不应答 } //突发报警上传(103,应答3) 在发生报警等级为1的报警事件时随时上传 void frame_func_reply_SYNB_SuddenAlarmUpload(void) { if(*(new_message_data_rev_sy + 14) == upload_serial_num_sy) //判断序列号是否正确 { if(*(new_message_data_rev_sy + 19) == 0) //上报是否成功 { FrameSetMsgApp(MsgShenYang_NbUplaod_AckOk); } } task_complete_sy = PTL_PACK_FAIL;//这是上报应答帧,返回错误,表计不应答 } //冻结数据查询(8,应答108) 查询日冻结数据、年冻结数据、月冻结数据 void frame_func_reply_SYNB_ACK_FrozenDataQuery(void) { static u8 num_get,num_to_get,num_to_read,totalnum,totalPackts,curPackt,send_totalPackts; static u8 temp_all_num=0; static u8 check_num=0; static UNION_SY_STORE_FROZEN temp_read_frozen_data;//冻结数据读取缓存 static u16 temp_frozen_addr=EEP_ADDR_SY_STORE_FROZEN_DAILY; switch(up_deal_stat_sy) { case UP_DEAL_S0: { temp_send_start_p = g_frame_temp_send_buf_sy; temp_send_end_p = g_frame_temp_send_buf_sy; temp_send_end_p1 = g_frame_temp_send_buf_sy; if(*(new_message_data_rev_sy + 19) == 0)//日 { num_to_read = get_SY_StorePara(SY_StoreCurIndex_Daily);//日冻结当前存储指针 temp_all_num = 7;//最大读取条数7天 temp_frozen_addr=EEP_ADDR_SY_STORE_FROZEN_DAILY; } else if(*(new_message_data_rev_sy + 19) == 1)//月 { num_to_read = get_SY_StorePara(SY_StoreCurIndex_Month); temp_all_num = 18;//18月 temp_frozen_addr=EEP_ADDR_SY_STORE_FROZEN_MONTH; } else if(*(new_message_data_rev_sy + 19) == 2)//年 { num_to_read = get_SY_StorePara(SY_StoreCurIndex_Year); temp_all_num = 6;//6年 temp_frozen_addr=EEP_ADDR_SY_STORE_FROZEN_YEAR; } totalnum = 0; num_get = 0; num_to_get = *(new_message_data_rev_sy + 20);//需要读取条数 totalPackts = *(new_message_data_rev_sy + 21);//总包数 curPackt = *(new_message_data_rev_sy + 22);//当前包 *temp_send_end_p++ = 0;//返回总包数 *temp_send_end_p++ = 0;//返回当前包 *temp_send_end_p++ = 0;//返回数据条数 up_deal_stat_sy = UP_DEAL_S1; } break; case UP_DEAL_S1: { if(totalnum >= temp_all_num)//最大读取条数temp_all_num { send_totalPackts = totalPackts; up_deal_stat_sy = UP_DEAL_S3; break; } if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM { if(num_to_read > temp_all_num) //防止指针跑飞了 { num_to_read = temp_all_num; } if(num_to_read == 0) { num_to_read = temp_all_num; } totalnum++; num_to_read--; EepRead(temp_frozen_addr + num_to_read*STORE_SIZE_DATA_FROZEN, &temp_read_frozen_data.data_buf[0], STORE_SIZE_DATA_FROZEN, &s_sy_eep_complete); up_deal_stat_sy = UP_DEAL_S2; } } break; case UP_DEAL_S2: { if(TASK_IDLE == EepIfIdle())//读完了 { check_num = 0; for(int i = 0; i<(STORE_SIZE_DATA_FROZEN-1); i++) { check_num += temp_read_frozen_data.data_buf[i]; } if(check_num == temp_read_frozen_data.Data.CheckSum) { temp_read_frozen_data.Data.FrozenDataTime.s.year = BCD2HEX(temp_read_frozen_data.Data.FrozenDataTime.s.year); temp_read_frozen_data.Data.FrozenDataTime.s.month = BCD2HEX(temp_read_frozen_data.Data.FrozenDataTime.s.month); temp_read_frozen_data.Data.FrozenDataTime.s.day = BCD2HEX(temp_read_frozen_data.Data.FrozenDataTime.s.day); temp_read_frozen_data.Data.FrozenDataTime.s.hour = BCD2HEX(temp_read_frozen_data.Data.FrozenDataTime.s.hour); temp_read_frozen_data.Data.FrozenDataTime.s.minute= BCD2HEX(temp_read_frozen_data.Data.FrozenDataTime.s.minute); temp_read_frozen_data.Data.FrozenDataTime.s.second= BCD2HEX(temp_read_frozen_data.Data.FrozenDataTime.s.second); num_get++; if(num_get >= num_to_get)//达到了要获取的条数 { for(int i = 0; i<(STORE_SIZE_DATA_FROZEN-2); i++) { *temp_send_end_p++ = temp_read_frozen_data.data_buf[i]; } up_deal_stat_sy = UP_DEAL_S3; break; } else { if(curPackt==1) { if(num_get<=9)//超过9条数据,开始拆分成两包 { for(int i = 0; i<(STORE_SIZE_DATA_FROZEN-2); i++) { *temp_send_end_p++ = temp_read_frozen_data.data_buf[i]; } totalPackts =1; } else { totalPackts = 2;//总包数为2 if(num_get>0) { num_get--; } up_deal_stat_sy = UP_DEAL_S3; break; } } else if(curPackt==2) { if(num_get>9)//超过9条数据,开始拆分成两包 { for(int i = 0; i<(STORE_SIZE_DATA_FROZEN-2); i++) { *temp_send_end_p++ = temp_read_frozen_data.data_buf[i]; } } } else { totalPackts = 0; up_deal_stat_sy = UP_DEAL_S3; break; } } } up_deal_stat_sy = UP_DEAL_S1; } } break; case UP_DEAL_S3: { send_totalPackts = totalPackts; *temp_send_end_p1++ = send_totalPackts;//总包数 *temp_send_end_p1++ = curPackt;//当前包 if(num_get>9) { num_get = num_get - 9; } *temp_send_end_p1++ = num_get;//数据条数 g_frame_temp_len_sy = (temp_send_end_p - temp_send_start_p);//需要发送数据的长度 up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_SUCCESS; } break; default: { up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_FAIL; } break; } } //周期数据查询(9,应答109) void frame_func_reply_SYNB_ACK_CycleDataQuery(void) { static u8 temp_data_cnt=0;//要读取包的数据条数 static u8 temp_packet_cnt=0;//总包数 static u8 curPacket; static u8 packet_index_buf[6]; static u8 curPacketIndex=0;//要读取包的索引 u8 readDays=0;//要读取的天数 switch(up_deal_stat_sy) { case UP_DEAL_S0: { g_frame_temp_len_sy = 0; temp_send_start_p = g_frame_temp_send_buf_sy; temp_send_end_p = g_frame_temp_send_buf_sy; readDays = *(new_message_data_rev_sy + 19); //查询天数 curPacket = *(new_message_data_rev_sy + 21);//当前包号 temp_packet_cnt = getSY_CircleDataPackets(readDays, packet_index_buf);//获取总包数和包号 *temp_send_end_p++ = temp_packet_cnt;//总包数 //当前包序号 if((curPacket > temp_packet_cnt)||(curPacket == 0))//要读取的当前包无效 { *temp_send_end_p++ = 0; up_deal_stat_sy = UP_DEAL_S2; } else { *temp_send_end_p++ = curPacket; up_deal_stat_sy = UP_DEAL_S1; } } break; case UP_DEAL_S1: { if(TASK_IDLE == EepIfIdle()) { DateTime temp_time; curPacketIndex = packet_index_buf[curPacket-1]; //计算数据条数 temp_data_cnt = SY_GetCircleReadStartEnd(curPacketIndex,1) - SY_GetCircleReadStartEnd(curPacketIndex,0); //起始日期时间 SY_GetCircleDateTime(&temp_time,curPacketIndex, 1);//起始时间日期 *temp_send_end_p++ = BCD2HEX(temp_time.s.year);//年 *temp_send_end_p++ = BCD2HEX(temp_time.s.month);//月 *temp_send_end_p++ = BCD2HEX(temp_time.s.day);//日 *temp_send_end_p++ = BCD2HEX(temp_time.s.hour); //时 *temp_send_end_p++ = BCD2HEX(temp_time.s.minute);//分 *temp_send_end_p++ = BCD2HEX(temp_time.s.second);//秒 //时间间隔 *temp_send_end_p++ = 6;//30分钟 //数据条数 *temp_send_end_p++ = temp_data_cnt; //读取间隔数据 u16 temp_ee_addr=0; temp_ee_addr = EEP_ADDR_SY_STORE_CIRCLE + curPacketIndex*16*24 + SY_GetCircleReadStartEnd(curPacketIndex,0)*16; EepRead(temp_ee_addr, temp_send_end_p, 16*temp_data_cnt, &s_sy_eep_complete); temp_send_end_p += 16*temp_data_cnt; up_deal_stat_sy = UP_DEAL_S2; } } break; case UP_DEAL_S2: { if(TASK_IDLE == EepIfIdle())//读完了 { g_frame_temp_len_sy = (temp_send_end_p - temp_send_start_p);//需要发送数据的长度 up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_SUCCESS; } } break; default: { up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_FAIL; } break; } } //报警历史数据查询(10,应答110) 查询历史报警数据 void frame_func_reply_SYNB_ACK_AlarmHistoryDataQuery(void) { static u8 *new_message_data_rev_ies; static u8 num_get,num_to_get,num_to_read,totalnum; static mtype16_ temp_soe_type; static ONE_SOE soe_event_read; static DateTime_noweek start_time; static DateTime_noweek end_time; static u8 *temp_alarm_cnt; static u8 *temp_all_packets_p; static u8 all_packets, cur_packet; switch(up_deal_stat_sy) { case UP_DEAL_S0: { DateTime tempDataTime; new_message_data_rev_ies = (new_message_data_rev_sy + 19); temp_send_start_p = g_frame_temp_send_buf_sy; temp_send_end_p = g_frame_temp_send_buf_sy; temp_all_packets_p = g_frame_temp_send_buf_sy; totalnum = 0; num_get = 0; RtccGetDateTime(&tempDataTime);//获取当前时间 num_to_read = Sys_data_object.P4.Point_SOE_write; temp_soe_type.to_uint16 = SOE_ALL_TYPE; start_time = getBackDateTimeNoWeek(*(new_message_data_rev_ies + 0));//获取起始时间 all_packets = *(new_message_data_rev_ies + 1);//总包数 cur_packet = *(new_message_data_rev_ies + 2);//当前包,最大值 4 (7*25条=175字节一包,4包100条) //结束时间 end_time.s.year = tempDataTime.s.year; end_time.s.month = tempDataTime.s.month; end_time.s.day = tempDataTime.s.day; end_time.s.hour = tempDataTime.s.hour; end_time.s.minute = tempDataTime.s.minute; end_time.s.second = tempDataTime.s.second; //读取数量 if((0 == cur_packet)||(cur_packet > 4)) { up_deal_stat_sy = UP_DEAL_S3; } num_to_get = 25;//25条一个分包 { *temp_send_end_p++ = all_packets;//总包数(站位) *temp_send_end_p++ = cur_packet;//当前包 temp_alarm_cnt = temp_send_end_p++; //报警数量,需要后面计算 up_deal_stat_sy = UP_DEAL_S1; } } break; case UP_DEAL_S1://读取一条SOE { if(totalnum >= TOTAL_NUM_SOE)//总共读TOTAL_NUM_SOE次 强制退出不能再读了 { all_packets = (num_get/25); if(num_get%25) { all_packets++; } *temp_all_packets_p = all_packets; up_deal_stat_sy = UP_DEAL_S3; break; } if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM { totalnum++; if(num_to_read > TOTAL_NUM_SOE) //防止指针跑飞了 { num_to_read = TOTAL_NUM_SOE; } if(num_to_read == 0) { num_to_read = TOTAL_NUM_SOE; } num_to_read--; EepRead(EEP_ADDR_SOE_BASE + (u16)num_to_read*LENGTH_ONE_SOE,(u8*)&soe_event_read,LENGTH_ONE_SOE, &s_sy_eep_complete); up_deal_stat_sy = UP_DEAL_S2; } } break; case UP_DEAL_S2: { if(TASK_IDLE == EepIfIdle())//读完了 { if(TRUE == Check_One_Soe(temp_soe_type.to_uint16,&start_time,&end_time,&soe_event_read))//检测到一条有效的SOE { num_get++; if((num_get > (cur_packet-1)*25)&&(num_get < (cur_packet*num_to_get)))//比如,要读取第二包,就从第26条开始放数据给发送区,到50条结束 { *temp_send_end_p++ = soe_event_read.soe_type-1000; *temp_send_end_p++ = BCD2HEX(soe_event_read.soe_time.s.year); *temp_send_end_p++ = BCD2HEX(soe_event_read.soe_time.s.month); *temp_send_end_p++ = BCD2HEX(soe_event_read.soe_time.s.day); *temp_send_end_p++ = BCD2HEX(soe_event_read.soe_time.s.hour); *temp_send_end_p++ = BCD2HEX(soe_event_read.soe_time.s.minute); *temp_send_end_p++ = BCD2HEX(soe_event_read.soe_time.s.second); } } up_deal_stat_sy = UP_DEAL_S1; } } break; case UP_DEAL_S3: { *temp_alarm_cnt = ((g_frame_temp_len_sy-3)/7); //计算报警信息条数 g_frame_temp_len_sy = (temp_send_end_p - temp_send_start_p);//需要发送数据的长度 up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_SUCCESS; } break; default: { up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_FAIL; } break; } } //清空数据(51,应答151) 清空冻结数据、历史数据、报警数据 void frame_func_reply_SYNB_ACK_ClearAllData(void) { temp_send_start_p = g_frame_temp_send_buf_sy; temp_send_end_p = g_frame_temp_send_buf_sy; *temp_send_end_p++ = *(new_message_data_rev_sy + 19); *temp_send_end_p++ = *(new_message_data_rev_sy + 20); *temp_send_end_p++ = *(new_message_data_rev_sy + 21); if(*(new_message_data_rev_sy + 19) == 1) //清空冻结数据 { *temp_send_end_p++ = 1; //0:不清空 1:成功 2:失败 FrameSetMsgApp(MsgShenYang_FrozenClear); } if(*(new_message_data_rev_sy + 20) == 1) //清空报警数据 { *temp_send_end_p++ = 1; //0:不清空 1:成功 2:失败 FrameSetMsgApp(MsgShenYang_WarningClear); } if(*(new_message_data_rev_sy + 21) == 1) //清空周期数据 { *temp_send_end_p++ = 1; //0:不清空 1:成功 2:失败 FrameSetMsgApp(MsgShenYang_CircleClear); } g_frame_temp_len_sy = 3; task_complete_sy = PTL_PACK_SUCCESS; } //重启、恢复出厂设置(52,应答152) void frame_func_reply_SYNB_ACK_RestoreFactorySetting(void) { temp_send_start_p = g_frame_temp_send_buf_sy; temp_send_end_p = g_frame_temp_send_buf_sy; *temp_send_end_p++ = *(new_message_data_rev_sy + 19); *temp_send_end_p++ = *(new_message_data_rev_sy + 20); if(*(new_message_data_rev_sy + 20) == 1) //恢复出厂设置 { FrameSetMsgApp(MsgShenYang_FactorySettingAndReset); } else { if(*(new_message_data_rev_sy + 19) == 1) //重启 { FrameSetMsgApp(MsgShenYang_SysReset); } } g_frame_temp_len_sy = 2; task_complete_sy = PTL_PACK_SUCCESS; } //调试指令(71,应答171) 由厂家自行定义的报文,数据域由厂家自行设置 void frame_func_reply_SYNB_DebugInstruction(void) { g_frame_temp_len_sy = 0; task_complete_sy = PTL_PACK_SUCCESS; } /** 5、水表参数设置 此报文数据域采用TLV格式,可同时设置若干报文,数据ID(Tag)的定义详见附表2,不同的Tag对应的数据长度也不同。 请求报文: **/ //水表应答平台请求规约 //参数设置(6,应答106) 设置上传时间、开关阀门、报警参数等 void frame_func_reply_SYNB_ACK_ParameterSetting(void) { static u8 tlv_para_cnt=0;//要设置的参数数量 switch(up_deal_stat_sy) { case UP_DEAL_S0: { u8 temp_tag=0; u8 temp_len=0; u8 temp_value[32]; u8 *temp_rev_p; temp_rev_p = (new_message_data_rev_sy + 19); temp_send_start_p = g_frame_temp_send_buf_sy; temp_send_end_p = g_frame_temp_send_buf_sy; tlv_para_cnt = *temp_rev_p++; //要设置的参数数量 if(tlv_para_cnt <= TLV_STR_BUF_LEN) { *temp_send_end_p++ = tlv_para_cnt; for(int i=0; i= 6) { return SUCCESS_IES; } return ERROR_IES; } //解沈阳NB规约 u8 crack_frame_SY(u16 frame_lenth,u8 *frame_buffer) { u16 tmp_i = 0; u16 tmp_j = 0; u8 tmp_check = 0; for (tmp_i = 0; tmp_i < frame_lenth; tmp_i++) { if (FM_HEAD_MARK == *(frame_buffer + tmp_i)) { if (MET_TYPE_SY == *(frame_buffer + tmp_i + 1)) { frame_struct_SY.head_site = tmp_i; //记录帧头 frame_struct_SY.sta = *(frame_buffer + tmp_i + 16);//状态字,bit0为1时表示加密,即01H表示加密,bit1为1时表示主动上传,其他bit位预留 frame_struct_SY.len.data_buf[0] = *(frame_buffer + tmp_i + 17);//数据长度,沈阳规约数据长度为2字节,低字节在前,高字节在后 frame_struct_SY.len.data_buf[1] = *(frame_buffer + tmp_i + 18); frame_struct_SY.end_site = frame_struct_SY.head_site + frame_struct_SY.len.datas + 20; frame_struct_SY.check_len = frame_struct_SY.end_site - frame_struct_SY.head_site - 1; frame_struct_SY.serial_num0 = *(frame_buffer + tmp_i + 14); //序列号,应答使用 //检测数据帧是否有效 if ((frame_struct_SY.end_site < frame_lenth) && (FM_END_MARK == *(frame_buffer + frame_struct_SY.end_site))) { frame_struct_SY.ctrl = *(frame_buffer + frame_struct_SY.head_site + 15); new_message_data_rev_sy = frame_buffer + frame_struct_SY.head_site; for (tmp_j = 0; tmp_j < 6; tmp_j++) //沈阳规约地址只有6字节的BCD { temp_check_addr[tmp_j] = Sys_data_object.P1.met_addr[tmp_j]; } //计算校验和 for (tmp_j = frame_struct_SY.head_site; tmp_j < (frame_struct_SY.end_site - 1); tmp_j++) { tmp_check += *(frame_buffer + tmp_j); } if (tmp_check == *(frame_buffer + frame_struct_SY.end_site - 1)) { frame_struct_SY.sta &= 0xFD; //表示非主动上传(bit1为1时表示主动上传,0表示应答) frame_lenth = 0; if (ERROR_IES == check_met_addr_SYNB(frame_buffer + frame_struct_SY.head_site, temp_check_addr)) //检查指令包含的地址和本表地址是否相同,相同返回1,不同返回0 { return (ERROR_IES); } return SUCCESS_IES; } } } } } return ERROR_IES; } //沈阳规约处理 u8 up_deal_code_sy(void) { task_complete_sy = PTL_PACK_BUSY; switch(frame_struct_SY.ctrl) { case FM_UPLOAD_FROZEN_DATA_REPLY_CTRL://冻结数据的上报应答 { frame_func_reply_SYNB_UploadFrozenData(); frame_struct_SY.ack_ctrl = FM_UPLOAD_FROZEN_DATA_CTRL; } break; case FM_UPLOAD_CYCLE_DATA_REPLY_CTRL://周期数据的上报应答 { frame_func_reply_SYNB_UploadCycleData(); frame_struct_SY.ack_ctrl = FM_UPLOAD_CYCLE_DATA_CTRL; } break; case FM_SUDDEN_ALARM_UPLOAD_REPLY_CTRL://报警信息的上报应答 { frame_func_reply_SYNB_SuddenAlarmUpload(); frame_struct_SY.ack_ctrl = FM_SUDDEN_ALARM_UPLOAD_CTRL; } break; case FM_FROZEN_DATA_QUERY_CTRL://冻结数据查询 { frame_func_reply_SYNB_ACK_FrozenDataQuery(); frame_struct_SY.ack_ctrl = FM_FROZEN_DATA_QUERY_REPLY_CTRL; } break; case FM_CYCLE_DATA_QUERY_CTRL://周期数据查询 { frame_func_reply_SYNB_ACK_CycleDataQuery(); frame_struct_SY.ack_ctrl = FM_CYCLE_DATA_QUERY_REPLY_CTRL; } break; case FM_ALARM_HISTORY_DATA_QUERY_CTRL://报警信息查询 { frame_func_reply_SYNB_ACK_AlarmHistoryDataQuery(); frame_struct_SY.ack_ctrl = FM_ALARM_HISTORY_DATA_QUERY_REPLY_CTRL; } break; case FM_CLEAR_ALL_DATA_CTRL://清空数据 { frame_func_reply_SYNB_ACK_ClearAllData(); frame_struct_SY.ack_ctrl = FM_CLEAR_ALL_DATA_REPLY_CTRL; } break; case FM_RESTORE_FACTORY_SETTING_CTRL: { frame_func_reply_SYNB_ACK_RestoreFactorySetting(); frame_struct_SY.ack_ctrl = FM_RESTORE_FACTORY_SETTING_REPLY_CTRL; } break; case FM_DEBUG_INSTRUCTION_CTRL: { frame_func_reply_SYNB_DebugInstruction(); frame_struct_SY.ack_ctrl = FM_DEBUG_INSTRUCTION_REPLY_CTRL; } break; case FM_PARAMENTER_SETTING_CTRL: { frame_func_reply_SYNB_ACK_ParameterSetting(); frame_struct_SY.ack_ctrl = FM_PARAMENTER_SETTING_REPLY_CTRL; } break; case FM_PARAMENTER_QUERY_CTRL: { frame_func_reply_SYNB_ACK_ParameterQuery(); frame_struct_SY.ack_ctrl = FM_PARAMENTER_QUERY_REPLY_CTRL; } break; default: { up_deal_stat_sy = UP_DEAL_S0; task_complete_sy = PTL_PACK_FAIL; } break; } return task_complete_sy; } void Frame_ResetDealState_Shenyang(void) { up_deal_stat_sy = UP_DEAL_S0; } void get_imei_and_signal_parameters(u8 *tmp_data_buf) { u8 i = 0; u8 s_temp_data1 = 0; u8 temp_buf1[16]; u8 temp_buf2[16]; s16 s_temp_data=0; UNION_2U8TOU16 s_temp_singal; NbiotGetIMEI((char*)temp_buf1); temp_buf2[0] = temp_buf1[0] - 0x30; for(i=1;i<8;i++) { temp_buf2[i] = (temp_buf1[2*i]-0x30)&0x0F; temp_buf2[i] |= ((temp_buf1[2*i-1]-0x30)<<4)&0xF0; } for(i=0;i<8;i++) { *tmp_data_buf ++ = temp_buf2[7-i]; } *tmp_data_buf ++ =0; *tmp_data_buf ++ =0; *tmp_data_buf ++ =0; NbiotGetRSRP(&s_temp_data); s_temp_singal.datas = (s_temp_data*0.1); s_temp_singal.datas = (~ s_temp_singal.datas) | 0x8000; *tmp_data_buf ++ = s_temp_singal.datas_map .data0 ; *tmp_data_buf ++ = s_temp_singal.datas_map .data1; NbiotGetSNR(&s_temp_data); //沈阳平台解析未放大10倍,2字节有符号整数 s_temp_data = s_temp_data*0.1; if(s_temp_data<0) { s_temp_singal.datas = (-s_temp_data); s_temp_singal.datas = (~s_temp_singal.datas) |0x8000; } else { s_temp_singal.datas = s_temp_data; } *tmp_data_buf ++ = s_temp_singal.data_buf[0]; *tmp_data_buf ++ = s_temp_singal.data_buf[1]; NbiotGetECL(&s_temp_data); s_temp_singal.datas = s_temp_data*0.1; *tmp_data_buf ++ = (u8)(s_temp_singal.datas); //沈阳规约ECL要一个字节,整数0、1、2 NbiotGetCSQ(&s_temp_data1); //沈阳规约CSQ上传1字节正数 *tmp_data_buf ++ = s_temp_data1; } //沈阳NB规约组帧 void Frame_ack_ShenYangBase(STRUCT_FRAME_SY temp_struct, u8* p_temp_buf, u16 p_temp_len, u8* p_send_buf, u16* p_send_len) { u8 i = 0; u16 j = 0; UNION_2U8TOU16 frame_pack_len; p_send_buf[0] = 0xFE; //沈阳规约没要求加前导 p_send_buf[1] = 0xFE; p_send_buf[2] = FM_HEAD_MARK; //包头68H p_send_buf[3] = MET_TYPE_SY; //规约版本02H //ASCII格式的IMEI,11字节(imei实际有15个数) //信号参数6字节 //信号强度(RSRP),2字节有符号整数 // 信噪比(SNR),2字节有符号整数 // 覆盖等级:1字节整数,0,1,2 //信号质量(CSQ):1字节正数 //表地址6字节 //序列号1字节 自加 //功能码1字节 //加密版本1字节 0或1 //数据域长度2字节 //数据域N字节 //校验码1字节 //包尾16H get_imei_and_signal_parameters(&p_send_buf[4]); //共18字节 for (i = 0; i < 6; i++) //沈阳规约地址是6字节BCD { p_send_buf[21 + i] = Sys_data_object.P1.met_addr[i]; } p_send_buf[27] = temp_struct.serial_num0; //应答序列号 p_send_buf[28] = temp_struct.ack_ctrl; p_send_buf[29] = temp_struct.sta; frame_pack_len.datas = p_temp_len; p_send_buf[30] = frame_pack_len.datas_map .data0 ;//沈阳规约数据长度2字节,低字节在前,高字节在后 p_send_buf[31] = frame_pack_len.datas_map .data1 ; memcpy(&p_send_buf[32], p_temp_buf, p_temp_len); p_send_buf[32+frame_pack_len.datas]=0; for (j = 2; j < 32+frame_pack_len.datas; j++) { p_send_buf[32+frame_pack_len.datas] += p_send_buf[j];//校验和 } p_send_buf[33+frame_pack_len.datas] = FM_END_MARK; //帧结束符 *p_send_len = 34+frame_pack_len.datas; } //沈阳NB规约应答帧格式组帧 void Sy_Frame_nb_read_ack(u8* p_send_buf, u16* p_send_len) { Frame_ack_ShenYangBase(frame_struct_SY, g_frame_temp_send_buf_sy, g_frame_temp_len_sy, p_send_buf, p_send_len); } ////////////////////////////////////////////////////////////////以下为主动上报相关////////////////////////////// //沈阳NB规约数据上报组帧 void Sy_Frame_nb_upload(u8* p_send_buf, u16* p_send_len) { Frame_ack_ShenYangBase(temp_struct_upload_SY, SY_CircleUploadBuf, SY_UploadDataLen, p_send_buf, p_send_len); } //报警数据上传组帧 void Nb_SY_ReadWarningRecord(u8 *p_send_buf, u16 *p_send_len) { static u8 num_get,num_to_read,totalnum; static mtype16_ temp_soe_type; static ONE_SOE soe_event_read; static DateTime_noweek start_time; static DateTime_noweek end_time; switch(step_UploadWarningSY) { case SY_STATE_S0: { DateTime tempDataTime; temp_warning_start_p = p_send_buf; temp_warning_end_p = p_send_buf; RtccGetDateTime(&tempDataTime);//获取当前时间 num_to_read = Sys_data_object.P4.Point_SOE_write; temp_soe_type.to_uint16 = SOE_ALL_TYPE; //起始时间 start_time.s.year = tempDataTime.s.year; start_time.s.month = tempDataTime.s.month; start_time.s.day = tempDataTime.s.day; start_time.s.hour = 0x00; start_time.s.minute = 0x00; start_time.s.second = 0x00; //结束时间 end_time.s.year = tempDataTime.s.year; end_time.s.month = tempDataTime.s.month; end_time.s.day = tempDataTime.s.day; end_time.s.hour = tempDataTime.s.hour; end_time.s.minute = tempDataTime.s.minute; end_time.s.second = tempDataTime.s.second; //读取数量 num_get = 0; totalnum = 0; SY_UploadDataLen = 9; temp_warning_end_p += 9; step_UploadWarningSY = SY_STATE_S1; } break; case SY_STATE_S1://读取一条SOE { if(totalnum >= TOTAL_NUM_SOE)//总共读TOTAL_NUM_SOE次 强制退出不能再读了 { step_UploadWarningSY = SY_STATE_S3; break; } if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM { totalnum++; if(num_to_read > TOTAL_NUM_SOE) //防止指针跑飞了 { num_to_read = TOTAL_NUM_SOE; } if(num_to_read == 0) { num_to_read = TOTAL_NUM_SOE; } num_to_read--; EepRead(EEP_ADDR_SOE_BASE + (u16)num_to_read*LENGTH_ONE_SOE,(u8*)&soe_event_read,LENGTH_ONE_SOE, &s_sy_eep_complete); } step_UploadWarningSY = SY_STATE_S2; } break; case SY_STATE_S2: { if(TASK_IDLE == EepIfIdle())//读完了 { if(TRUE == Check_One_Soe(temp_soe_type.to_uint16,&start_time,&end_time,&soe_event_read))//检测到一条有效的SOE { *temp_warning_end_p++ = soe_event_read.soe_type-1000; *temp_warning_end_p++ = BCD2HEX(soe_event_read.soe_time.s.year); *temp_warning_end_p++ = BCD2HEX(soe_event_read.soe_time.s.month); *temp_warning_end_p++ = BCD2HEX(soe_event_read.soe_time.s.day); *temp_warning_end_p++ = BCD2HEX(soe_event_read.soe_time.s.hour); *temp_warning_end_p++ = BCD2HEX(soe_event_read.soe_time.s.minute); *temp_warning_end_p++ = BCD2HEX(soe_event_read.soe_time.s.second); num_get++; if(num_get >= 20)//最多读20条 { step_UploadWarningSY = SY_STATE_S3; break; } } step_UploadWarningSY = SY_STATE_S1; } } break; case SY_STATE_S3: { DateTime tempRtcc_time; RtccGetDateTime(&tempRtcc_time);;//获取当前时间 //发送日期 3字节 *temp_warning_start_p++ = BCD2HEX(tempRtcc_time.s.year); *temp_warning_start_p++ = BCD2HEX(tempRtcc_time.s.month); *temp_warning_start_p++ = BCD2HEX(tempRtcc_time.s.day); //发送时间 3字节 *temp_warning_start_p++ = BCD2HEX(tempRtcc_time.s.hour); *temp_warning_start_p++ = BCD2HEX(tempRtcc_time.s.minute); *temp_warning_start_p++ = BCD2HEX(tempRtcc_time.s.second); //表计状态 *temp_warning_start_p++ = getWaterState(); //阀门状态 *temp_warning_start_p++ = 0;//无阀 *temp_warning_start_p++ = ((SY_UploadDataLen-9)/7);//报警数量 *p_send_len = temp_warning_end_p-temp_warning_start_p; task_complete_warning_sy = PTL_PACK_SUCCESS; step_UploadWarningSY = SY_STATE_S0; } break; default: { step_UploadWarningSY = SY_STATE_S0; } break; } } void GetUploadDataResetState_ShenYangUDP(void) { upload_frame_stat_sy =SY_STATE_S0; } u8 GetUploadDataCheckIdle_ShenYangUDP(void) { if(SY_STATE_S0 == upload_frame_stat_sy) { return TASK_IDLE; } else { return TASK_BUSY; } } u8 GetUploadDataCheckTask_ShenYangUDP(void) { return task_complete_upload_sy; } void GetUploadDataMachine_ShenYangUDP(u8 data_step, u8* p_send_buf, u16* p_send_len) { switch(upload_frame_stat_sy) { case SY_STATE_S0: { if(data_step == UPLOAD_FRAME_REQUEST_NEW)//请求新数据包 { temp_upload_step = 0; upload_frame_retry_times = 0; upload_frame_stat_sy = SY_STATE_S1; } else if(data_step == UPLOAD_FRAME_UPLOAD_OK)//发送成功 { if(temp_upload_step == SY_STATE_S2)//当前包数据发送成功,任务结束 { task_complete_upload_sy = PTL_PACK_FAIL;//任务完成 upload_frame_stat_sy = SY_STATE_S0; } if(temp_upload_step == SY_STATE_S3)//历史数据发送成功,存储已发送位置,获取下一包数据 { upload_frame_stat_sy = SY_STATE_S10; } if(temp_upload_step == SY_STATE_S4)//报警数据发送成功,任务结束 { task_complete_upload_sy = PTL_PACK_FAIL;//任务完成 upload_frame_stat_sy = SY_STATE_S0; } upload_frame_retry_times = 0; SystemClearUploadAgain();//重传清0 } else if(data_step == UPLOAD_FRAME_UPLOAD_RETRY)//请求重新发送 { upload_frame_stat_sy = SY_STATE_S21; } else if(data_step == UPLOAD_FRAME_ONLINE_FAIL) //联网失败 { if(UPLOAD_TYPE_FIX_TIME == GetEventUploadType()|| (UPLOAD_TYPE_RETRY_AGAIN == GetEventUploadType()))//定时上传 { SystemAddUploadAgain();//重传增加 } task_complete_upload_sy = PTL_PACK_FAIL; upload_frame_stat_sy = SY_STATE_S0; } else { task_complete_upload_sy = PTL_PACK_FAIL; upload_frame_stat_sy = SY_STATE_S0; } } break; case SY_STATE_S1://获取上报总包数 { SY_CircleUploadPackets = getSY_CircleUploadPackets();//上报总包数 if(SY_CircleUploadPackets == 0)//还没有存储数据,则上报当前数据 { upload_frame_stat_sy = SY_STATE_S2; } else { SY_CircleThisPacketNum = 0; SY_CircleThisUploadPacket_Index = getSY_ThisCirclePacket_Index(SY_CircleThisPacketNum);//要上报的位置 upload_frame_stat_sy = SY_STATE_S3; } } break; case SY_STATE_S2://只上报当前数据 { temp_upload_step = SY_STATE_S2; temp_struct_upload_SY.ack_ctrl = FM_UPLOAD_CYCLE_DATA_CTRL; temp_struct_upload_SY.sta = 0; upload_serial_num_sy++;//序列号增加 temp_struct_upload_SY.serial_num0 = upload_serial_num_sy; SY_UploadDataLen = NB_SY_Frame_Upload_CurrentData(&SY_CircleUploadBuf[0]);//获取数据部分 Sy_Frame_nb_upload(p_send_buf, p_send_len);//上报数据组帧 task_complete_upload_sy = PTL_PACK_SUCCESS;//任务完成 upload_frame_stat_sy = SY_STATE_S0; } break; case SY_STATE_S3://上报历史数据:根据上报位置获取数据 { SY_CiecleThisUploadPacket_Cnt = NB_SY_Frame_Upload_Data(SY_CircleThisUploadPacket_Index, &SY_CircleUploadBuf[10]); if(SY_CiecleThisUploadPacket_Cnt > 0) { temp_upload_step = SY_STATE_S3; DateTime tempRtcc_time; SY_CircleUploadBuf[0] = SY_CircleUploadPackets; //总包数 1字节 SY_CircleUploadBuf[1] = SY_CircleThisPacketNum+1; //当前包序号 1字节 SY_GetCircleDateTime(&tempRtcc_time, SY_CircleThisUploadPacket_Index, 0); //起始日期 3字节 SY_CircleUploadBuf[2] = BCD2HEX(tempRtcc_time.s.year);//BCD转成hex SY_CircleUploadBuf[3] = BCD2HEX(tempRtcc_time.s.month); SY_CircleUploadBuf[4] = BCD2HEX(tempRtcc_time.s.day); //起始时间 3字节 SY_CircleUploadBuf[5] = BCD2HEX(tempRtcc_time.s.hour); SY_CircleUploadBuf[6] = BCD2HEX(tempRtcc_time.s.minute); SY_CircleUploadBuf[7] = BCD2HEX(tempRtcc_time.s.second); SY_CircleUploadBuf[8] = 6; //6:表示30分钟(5x6)时间间隔1字节 SY_CircleUploadBuf[9] = SY_CiecleThisUploadPacket_Cnt; //数据条数1字节 SY_UploadDataLen = 10 + 16*SY_CiecleThisUploadPacket_Cnt;//根据数据条数计算数据长度 temp_struct_upload_SY.ack_ctrl = FM_UPLOAD_CYCLE_DATA_CTRL; temp_struct_upload_SY.sta = 0; upload_serial_num_sy++;//序列号增加 temp_struct_upload_SY.serial_num0 = upload_serial_num_sy; Sy_Frame_nb_upload(p_send_buf, p_send_len);//上报数据组帧 task_complete_upload_sy = PTL_PACK_SUCCESS;//任务完成 upload_frame_stat_sy = SY_STATE_S0; } } break; case SY_STATE_S4://报警上传 { if(FrameCheckMsgApp(MsgShenYang_NbUploadWarningWithCircle))//判断是否上报报警信息 { FrameClearMsgApp(MsgShenYang_NbUploadWarningWithCircle); step_UploadWarningSY = SY_STATE_S0; task_complete_warning_sy = PTL_PACK_BUSY; upload_frame_stat_sy = SY_STATE_S5; } else { task_complete_upload_sy = PTL_PACK_FAIL;//任务失败 upload_frame_stat_sy = SY_STATE_S0; } } break; case SY_STATE_S5://报警上传 { Nb_SY_ReadWarningRecord(SY_CircleUploadBuf, &SY_UploadDataLen); if(task_complete_warning_sy == PTL_PACK_SUCCESS) { temp_struct_upload_SY.ack_ctrl = FM_SUDDEN_ALARM_UPLOAD_CTRL; temp_struct_upload_SY.sta = 0; upload_serial_num_sy++;//序列号增加 temp_struct_upload_SY.serial_num0 = upload_serial_num_sy; Sy_Frame_nb_upload(p_send_buf, p_send_len);//上报数据组帧 temp_upload_step = SY_STATE_S4; task_complete_upload_sy = PTL_PACK_SUCCESS;//任务完成 upload_frame_stat_sy = SY_STATE_S0; } } break; case SY_STATE_S10://当前包上报成功后,更新存储指针 { if(ShenYang_CircleDataStore_ClearUploadIndex(SY_CircleThisUploadPacket_Index)) { SY_CircleThisPacketNum ++; if(SY_CircleThisPacketNum < SY_CircleUploadPackets) { SY_CircleThisUploadPacket_Index = getSY_ThisCirclePacket_Index(SY_CircleThisPacketNum);//要上报的位置 upload_frame_stat_sy = SY_STATE_S3;//继续上报数据 } else { upload_frame_stat_sy = SY_STATE_S4;//上报数据完成,开始上报报警信息 } } } break; case UP_DEAL_S21://重试 { if(upload_frame_retry_times < 3) { upload_frame_retry_times++; if(temp_upload_step == SY_STATE_S2)//当前包数据发送失败,继续发送当前包 { upload_frame_stat_sy = SY_STATE_S2; } else if(temp_upload_step == SY_STATE_S3)//历史数据发送失败,继续发送该包历史数据 { upload_frame_stat_sy = SY_STATE_S3; } else if(temp_upload_step == SY_STATE_S4)//报警数据发送失败,继续发送报警数据 { upload_frame_stat_sy = SY_STATE_S4; } else { task_complete_upload_sy = PTL_PACK_FAIL; upload_frame_stat_sy = SY_STATE_S0; } } else//重新发送失败3次的处理 { if((UPLOAD_TYPE_FIX_TIME == GetEventUploadType())|| (UPLOAD_TYPE_RETRY_AGAIN == GetEventUploadType()))//定时上传 { if((temp_upload_step == SY_STATE_S2)||(temp_upload_step == SY_STATE_S3))//如果上报的是数据,允许重传 { SystemAddUploadAgain();//重传增加 } } task_complete_upload_sy = PTL_PACK_FAIL; upload_frame_stat_sy = SY_STATE_S0; } } break; default: { upload_frame_stat_sy = SY_STATE_S0; break; } } } /******************************************************************************* * @fun_name:NB_SS_Control_GetPara * @brief : * @param[in] :读取上报控制相关参数 * @param[out]: None * @retval : None * @other : ******************************************************************************/ u8 NB_SS_Control_GetPara(NB_SS_ControlParaTypeDef paraType) { return 0; } /******************************************************************************* * @fun_name:NB_SS_Control_SetPara * @param[in] :设置上报控制相关参数 ******************************************************************************/ void NB_SS_Control_SetPara(NB_SS_ControlParaTypeDef paraType, u8 data) { switch(paraType) { case NB_HistroyReadIndex://历史数据的读指针 { Sys_data_object.P1.histroy_w = data; break; } case NB_UploadFailTimes://失败次数 { SystemClearUploadAgain(); Sys_data_object.P1.Supplemental_send_flag.datas = data; Sys_data_object.P3.ProductUpoadFailFlag = 0; break; } case NB_SS_FormatError://上报数据格式错误 { break; } default: break; } } //规约数据存储部分初始化 void DataStoreInit(void) { Quanzhou_Store_InitApp(); ShenYang_Store_InitApp(); } //规约数据存储状态机 void DataStoreMachine(void) { Quanzhou_Store_Machine();//日、月冻结数据存储 ShenYang_Store_Machine();//沈阳数据存储 ShenYang_SOE_Machine();//SOE记录存储 ShenYang_TlvDataStoreMachine(); //沈阳参数 } //规约数据存储休眠判断 u8 DataStoreIfIdle(void) { if((QuanzhouStore_IfSleep() == TRUE) && (ShenYangStore_IfSleep() == TRUE)) { return TRUE; } return FALSE; } #endif