/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-07-06 murmur the first version */ #include #include #include #define LOG_TAG "func" #define LOG_LVL LOG_LVL_DBG #include //3.2.1双模通信功能 //1为TT通信,0为BD短报文通信 void setCommMode(int isTT) { if (isTT) { //change mode } else { } //write to cfg file set_cfg("commMode", isTT); LOG_D("set commMode to %s",isTT?"TT":"BD"); } int getCommMode() { //load from cfg file int flag = get_cfg("commMode"); if (flag < 0) { LOG_W("get mode fault."); } return flag; } //3.2.2状态自检 /** * 系统自检,自动发送自检结果 */ void sysSelfTest() { rt_uint8_t rst[]={0x5A, 0xA5, 0x32, 0x3E, 0x0A, 0x41, 0x00,0x06}; int p = sizeof(rst); rt_uint8_t sysSta=1,xh,jh,commSpeed=0,powerLevel,storageCapacity; rst[p++]=sysSta; rst[p++]=xh; rst[p++]=jh; rst[p++]=commSpeed; rst[p++]=getPowerLevel(); rst[p++]=getCapacityLevel(); rst[p++]=0x00;//校验位 rst[p++]=0xED;//结束位 //发送结果 uploadData(rst,p); } //3.2.3日志记录 //日志功能由各函数通过LOG_D()实现 //3.2.4自毁功能 /** * 设置自毁功能开关 * @param setON 1-自毁功能开启,0-关闭 */ void setSelfDestructSWT(int setON) { //write to cfg file set_cfg("SelfDesSW", setON); LOG_D("set SelfDesSW to %s",setON?"ON":"OFF"); } /** * 获取自毁开关状态 * @return 1-自毁功能开启,0-关闭 */ int getSelfDestructSWT() { //load from cfg file int flag = get_cfg("SelfDesSW"); if (flag < 0) { LOG_W("get mode fault."); } return flag; } /** * 启动自毁 */ void selfDestruct() { if (getSelfDestructSWT()) { //硬件自毁 LOG_W("SELF DESTRUCT START."); } } //3.2.5开、关窗功能 extern void updateAlarm(int *t); /** * 更新开窗时间,目前支持两组开窗时段。更新会清除之前的开窗设置 */ void setCommWindow(int *t) { updateAlarm(t); LOG_D("更新开窗时间完成。"); } /** * 手动控制开窗 * @param t 开窗时长,单位分钟,时间到则自动关窗。t=0时需要手动关窗。 */ void openWindow(int t) { //开启TT pwTT_thread_entry("1");//开机 if (!t) { LOG_D("手动开窗完成,需手动关窗。"); return; } //设置定时器,定时器到则关窗 /* 创建定时器,单次定时器 */ rt_timer_t timer1; timer1 = rt_timer_create("window", pwTT_thread_entry, 0, rt_tick_from_millisecond(t*60*1000), RT_TIMER_FLAG_ONE_SHOT); /* 启动定时器 */ if (timer1 != RT_NULL) { rt_timer_start(timer1); LOG_D("手动开窗完成,%d分钟后自动关窗。",t); } } /** * 手动关窗 */ void closeWindow() { pwTT_thread_entry("0");//关 机 LOG_D("手动关窗完成。"); } //3.2.6工作参数配置、状态查询 //包含浮体自身、标体透传、两者结合 //这里主要实现浮体自身 //浮体自身的参数配置各功能函数有实现,此处需规定参数下发协议和解码实现 //3.2.8定时自报位置信息 //每小时传数据时同步传位置信息 //3.2.9深度异常告警 int packDeepMsg(uint8_t *din, int len, uint8_t *dout) { //获取并更新位置信息 uint8_t loc[]={}; rt_memcpy(din+6, loc, 8);//位置数据从【】字节开始,共8个字节 //加密。因加密后数据长度会变化,故不能只加密位置数据。 uint8_t cd[200]; size_t nlen = cryp_data(din, len, cd); //打包数据 static MSG cfg; rt_memset(&cfg, 0, sizeof(MSG)); // 分配空间 char *fin; time2Str(fin); packInit(&cfg, fin, 0);//写入配置 size_t rst = packMsg(&cfg, din, nlen, dout); LOG_D("位置数据打包完成"); return rst; } //3.2.10位置异常告警 //map.c中实现 /** * 判断是否在电子围栏内部 * @param x 当前位置经度 * @param y 当前位置纬度 * @return 在内部则返回true,反之false */ static int isInFence(float x, float y) { float polyX[]={},polyY[]={}; int polyCorners = mapParse("/map.geojson",polyX,polyY); return pointInPolygon(polyCorners,polyX,polyY,x,y); } /** * 设置位置告警功能开关 * @param setON 1-告警功能开启,0-关闭 */ void setLocationAlertSWT(int setON) { } /** * 检查是否在电子围栏内部,并发出告警 */ void checkLocAndAlert() { //get Lon and Lat float x,y; if (!x || !y) { LOG_W("location info is not ready."); return; } int isIN = isInFence(x, y); if (isIN) { LOG_I("设备在预设范围内,位置正常。"); } else { LOG_W("警告!设备不在预设范围内!"); //告警 } } //3.2.12数据存储区清空 // /** * 采用格式化命令对存储区进行清空,谨慎使用! */ void clearAllData() { mkfs("elm", "W25Q128");//format flash mkfs("elm","sd0");//format SD }