TT12-MCU/applications/getinfo.c

578 lines
16 KiB
C
Raw Permalink Normal View History

#include <board.h>
#include <rtthread.h>
//#include <../packages/webclient-v2.2.0/inc/webclient.h>
#include <webclient.h>
#define LOG_TAG "getinfo"
#define LOG_LVL LOG_LVL_INFO
#include <ulog.h>
#include <string.h>
#include <cJSON.h>
#include <usrcfg.h>
//#define HTTP_GET_URL "http://www.rt-thread.com/service/rt-thread.txt"
#ifndef TT_IP
#define TT_IP "http://" TTIP ":4005"
#endif
#define TT_SIM TT_IP "/action/webGetSIMState"//SIM
#define TT_XH TT_IP "/action/webGetTDSignal"//信号值
#define TT_RW TT_IP "/action/webGetTdState"//入网
#define TT_JH TT_IP "/action/webGetPSState"//激活
#define TT_DW TT_IP "/action/webGetBDGPS"//定位
#define TT_WEB_GET TT_IP "/action/webGetSocketAddr"//服务器地址
#define TT_WEB_SET TT_IP "/action/webSetSocketAddr"//服务器地址
//http://192.168.0.232:4005/action/webGetSIMState webGetBDGPS
#define MAX_LEN 15
//#include <stdio.h>
//#include <stdlib.h> //用于strtod函数
//#include <string.h>
char *infoH[] = { TT_SIM, TT_XH, TT_RW, TT_JH, TT_DW};
typedef struct
{
char sim[MAX_LEN]; // SIM
char xh[MAX_LEN]; // SIM
char rw[MAX_LEN]; // SIM
char jh[MAX_LEN]; // SIM
char jd[MAX_LEN]; // SIM
char wd[MAX_LEN]; // SIM
char ele[MAX_LEN]; // SIM
/**
0.0000011
0.0000110
0.0001100
0.0011000
0.0110000
0.0000011.1
0.0000111
0.0001111
0.0011113
0.0111132
*/
}TT;
TT tmp={.sim="-",.xh="-",.rw="-",.jh="-",.jd="-",.wd="-",.ele="-"};
TT *TTinfo=&tmp;
static rt_tick_t bootstamp=0;
#define RST_LEN 100//存储info的数组的长度
static uint8_t rstInfo[RST_LEN];//存储info的数组
2023-09-12 03:40:39 +00:00
static uint8_t signalInfo[RST_LEN];
void resetInfo()
{
rt_memset(rstInfo,0x3f,RST_LEN);//初始化
2023-09-12 03:40:39 +00:00
rt_memset(signalInfo,0x3f,RST_LEN);//初始化
}
/**
* @description: TT结构体转换为数组
* @param {TT} *TTinfo TT结构体
* @param {rt_uint8_t} *buffer
* @return {*} buffer大小
*/
rt_uint8_t info2HEX(TT *TTinfo, rt_uint8_t *buffer)
{
// 功能将tt数据转换为9字节HEX数据并返回存在data
// 第1节为高3位分别为sim、rw和jh其余位为xhxh值若大于31则为3131=b0001 1111
// 第2-5字节为经度。114.410050= 0xF2 0xD1 0xE4 0x42//根据系统大小端的不同可能是反序
// 第6-9字节为纬度。30.426840= 0x2B 0x6A 0xF3 0x41
// 第10字节为高度只保留整数。-31.5= 0xE1
rt_uint8_t tmp = (atoi(TTinfo->sim) << 7) + (atoi(TTinfo->rw) << 6) + (atoi(TTinfo->jh) << 5)
+ (atoi(TTinfo->xh) > 31 ? 31 : atoi(TTinfo->xh)); // 位操作
char *jd_c = &TTinfo->jd[2]; // 从第二位开始取,去除非数字字符
char *wd_c = &TTinfo->wd[2];
float jd_f = strtod(jd_c, NULL); // 字符转浮点
float wd_f = strtod(wd_c, NULL);
rt_int8_t ele_f = atoi(TTinfo->ele);
// printf("jd--%f\nwd--%f\nele-- %d \n", jd_f, wd_f, ele_f);
rt_uint8_t offset = 0;
memcpy(buffer + offset, &tmp, 1);
offset += 1;
memcpy(buffer + offset, &jd_f, sizeof(float));
offset += sizeof(float);
memcpy(buffer + offset, &wd_f, sizeof(float));
offset += sizeof(float);
memcpy(buffer + offset, &ele_f, sizeof(rt_int8_t));
offset += sizeof(rt_int8_t);
return offset;
}
/**
* @brief
*
* @param rst
* @param cnt
* @param din
* @param len
* @return size_t 0--1
*/
int appendInfo(uint8_t *rst, size_t cnt, uint8_t *din, size_t len )
{
if (cnt < len)
{
return -1;
}
uint8_t tmp[cnt];
memcpy(tmp, rst + len, cnt - len);
memcpy(rst, tmp, cnt - len);
memcpy(rst + cnt - len, din, len);
return 0;
}
/**
*
* @param dout
* @param cnt
* @return 0
*/
int getLoc(uint8_t * dout, size_t cnt)
{
// LOG_D("待实现获取位置函数此处以0xCD代替");
uint8_t tmp[4];
rt_memset(tmp,0,4);
if ((rstInfo[0] == 0x3f) || (memcmp(rstInfo+1,tmp,4) == 0)) {//无有效位置数据1+4+4+1
return 0;
}
memcpy(dout,rstInfo+RST_LEN-cnt*10,cnt*10);//从后开始取
return cnt*10;//1+4+4+1
}
extern SYS_CFG scfg;
void initcfg()
{
2023-09-12 03:40:39 +00:00
resetInfo();//初始化
bootstamp = rt_tick_get_millisecond();
}
2023-08-18 07:36:41 +00:00
INIT_APP_EXPORT(initcfg);
/**
*
*/
//static void updateSta()
//{
// uint16_t v = (rt_tick_get_millisecond()-bootstamp)/1000;//转换为秒
// LOG_I("耗时%dS.",v);
// if ((minActiveTime ==0) | (minActiveTime > v)) {
// minActiveTime = v;
// set_val("minActiveTime", v);
// }
// if (v>maxActiveTime) {
// maxActiveTime=v;
// set_val("maxActiveTime", v);
// }
//}
/**
* TT状态
*/
static void rulecheck(void)
{
//默认为 TT连续5个周期为激活状态且信号强度不低于5。
//满足加1不满足清零
static size_t okCnt=0;
if (!okCnt) {
// LOG_D("当前规则为:连续%d个采集周期TT信号质量不低于%d",scfg.minTTPeriCnt,scfg.minTTsinal);
}
int xh=atoi(TTinfo->xh);
if (xh > 90) {
xh=0;
}
if (atoi(TTinfo->jh) && !(xh < scfg.minTTsinal) ) {//
okCnt += 1;
LOG_D("第%d次符合规则。",okCnt);
}
else {
okCnt = 0;
// LOG_W("不符合。");
TTIsNotReady();
return;
}
if (okCnt >= scfg.minTTPeriCnt) {
//TT具备发送条件
// LOG_I("----");
extern void TTIsReady(void);
TTIsReady();
// LOG_I("符合规则TT具备发送状态。");
okCnt = scfg.minTTPeriCnt -1;
}
// if (okCnt > minTTPeriCnt) {
// //TT具备发送条件
//// rt_event_send(&sw_check, TT_IS_OK);
// upTTflag();
// okCnt = 2;
// LOG_I("符合规则TT具备发送状态。");
//// updateSta();
// }
}
/* 数据解析 */
static void tt_parse(rt_uint8_t *data)
{
// LOG_I("%s",data);
extern TT *TTinfo;
cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
root = cJSON_Parse((const char *) data);
if (!root)
{
LOG_W("JSON string is not ok, or No memory for cJSON root!");
return;
}
object = cJSON_GetObjectItem(root, "data");
item = cJSON_GetObjectItem(object, "tdsignal");
if (item)
{
// TTinfo->xh = atoi(item->valuestring);
// tmp.xh = item->valuestring;
strcpy(TTinfo->xh,item->valuestring);
// rt_kprintf("\nxh:%s ", item->valuestring);
// rt_kprintf("\nxh:%s ", TTinfo->xh);
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "tdnetregstate");
if (item)
{
// TTinfo->rw = atoi(item->valuestring);
// rt_kprintf("\nrw:%s ", TTinfo.rw);
strcpy(TTinfo->rw,item->valuestring);
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "tdpsstate");
if (item)
{
// TTinfo->jh = atoi(item->valuestring);
// rt_kprintf("\njh:%s ", TTinfo.jh);
strcpy(TTinfo->jh,item->valuestring);
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "latitude");
if (item)
{
// TTinfo->wd = item->valuestring;
strcpy(TTinfo->wd,item->valuestring);
item = cJSON_GetObjectItem(object, "longitude");
// TTinfo->jd = item->valuestring;
strcpy(TTinfo->jd,item->valuestring);
item = cJSON_GetObjectItem(object, "elevation");
// TTinfo->ele = item->valuestring;
strcpy(TTinfo->ele,item->valuestring);
// rt_kprintf("%5s%5s%5s%5s%15s%15s%10s\n", TTinfo->sim, TTinfo->xh, TTinfo->rw,
// TTinfo->jh, TTinfo->jd, TTinfo->wd,TTinfo->ele);
LOG_D("Get RAW data done.");
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "tdsimstate");
if (item)
{
// TTinfo->sim = atoi(item->valuestring);
// tmp.sim = item->valuestring;
strcpy(TTinfo->sim,item->valuestring);
// rt_kprintf("\nSIM:%s \n", TTinfo->sim);
cJSON_Delete(root);
return RT_EOK;
}
if (root != RT_NULL)
cJSON_Delete(root);
}
/* HTTP client download data by GET request */
static int webclient_get_data(const char *url)
{
static unsigned char *buffer = RT_NULL;
size_t length = 0;
static size_t errCnt = 0;
if (!isTCPok() || webclient_request(url, RT_NULL, RT_NULL, 0, (void **) &buffer, &length) <= 0)
{
LOG_E("TT server or webclient is not ready.");
2023-06-19 07:56:45 +00:00
if (buffer)
{
web_free(buffer);
}
if (errCnt++ > 15) {
errCnt = 0;
deInitTT();
rt_thread_mdelay(5000);
fileIsReady();
}
return -RT_ERROR;
}
LOG_D("webclient GET request response data :");
LOG_D("%s", buffer);
if (buffer && length && buffer[length-1] == 0x7d) //0x7d='}',首次返回的数据不完整,此处直接丢掉避免报错
{
tt_parse(buffer);
web_free(buffer);
}
return RT_EOK;
}
void getTTinfo_thread_entry(void* parameter)
{
// bootstamp = rt_tick_get();
CFG* cfg = RT_NULL;
cfg = (CFG*) parameter;
// TT TTinfo;
rt_kprintf("\n%10s%s\n", " ", "↓---------getTT START.--------↓");
rt_kprintf("%5s%5s%5s%5s%15s%15s%10s\n", "SIM", "xh", "rw", "jh", "N", "E", "ele");
for (uint8_t i = 0; i < cfg->cnt; ++i) //按指定次数轮询
{
rt_kprintf("%5s%5s%5s%5s%15s%15s%10s\n", TTinfo->sim, TTinfo->xh, TTinfo->rw, TTinfo->jh, TTinfo->jd,
TTinfo->wd, TTinfo->ele);
if (i != cfg->cnt - 1) //最后一次采集不延时
{
rt_thread_mdelay(cfg->s * 1000);
}
}
rt_kprintf("%10s%s\n", " ", "↑---------getTT DONE.---------↑");
}
void getTT(int argc, char **argv)
{
// size_t cnt = 0, s=3;//次数、间隔
static CFG cfg;
rt_memset(&cfg, 0, sizeof(CFG));
if (argc == 1)
{
cfg.cnt = 1;
cfg.s = 3;
}
else if (argc == 2)
{
cfg.cnt = atoi(argv[1]);
cfg.s = 3;
}
else if (argc == 3)
{
cfg.cnt = atoi(argv[1]);
cfg.s = atoi(argv[2]);
}
/* 创建 serial 线程 */
2023-08-25 08:36:00 +00:00
rt_thread_t thread = rt_thread_create("getTT", getTTinfo_thread_entry, (void *) &cfg, 1024 * 5, 25, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
// rt_kprintf("done");
}
else
{
LOG_E("thread 'getTT' create failure.");
return RT_ERROR;
}
}
/* 导出到自动初始化 */
MSH_CMD_EXPORT(getTT, "getTT 3 1" means try 3 times with 1 second interval.);
//MSH_CMD_EXPORT_ALIAS(webclient_get_data, gTTinfo, GET info of TT server.);
2023-07-26 08:26:53 +00:00
/**
* TT是否为开机状态
* @return 1-0-
*/
int isTTon(void)
{
#ifndef RELAY
return !rt_pin_read(TT_EN);
#else
return rt_pin_read(TT_EN);
#endif
}
2023-07-26 08:26:53 +00:00
/**
* TT是否激活
* @return 1-0-
*/
uint8_t isTTjh(void)
2023-07-26 08:26:53 +00:00
{
return atoi(TTinfo->jh);
}
uint8_t getXh(void)
{
return (uint8_t)atoi(TTinfo->xh);
}
2023-07-26 08:26:53 +00:00
void repGetTT_thread_entry(void* parameter)
{
// while(!isTCPok())//第一次运行时未上电则等待
// {}
while(isTCPok())//中间未上电则退出
{
for (size_t var = 0; var < (sizeof(infoH) / sizeof(infoH[0])); var++) //轮询每个参数
{
if (!isTCPok()) {
break;
}
static char *url = RT_NULL;
url = web_strdup(*(infoH + var));
if (url == RT_NULL)
{
LOG_E("no memory for create getTT url buffer.\n");
2023-06-19 07:56:45 +00:00
break;
// return -RT_ENOMEM;
}
if (webclient_get_data(url) != RT_EOK)
{
// LOG_E("---------");
2023-06-19 07:56:45 +00:00
web_free(url);
strcpy(TTinfo->sim,"-");
strcpy(TTinfo->xh,"-");
strcpy(TTinfo->jh,"-");
strcpy(TTinfo->jd,"-");
strcpy(TTinfo->wd,"-");
strcpy(TTinfo->ele,"-");
break;
}
if (url) {
web_free(url);
}
2023-06-19 07:56:45 +00:00
// rt_thread_mdelay(100);
//trans&copy new info to arrBuf
uint8_t buffer[10];
int len = info2HEX(TTinfo, buffer);
appendInfo(rstInfo, RST_LEN, buffer, len);
2023-09-12 03:40:39 +00:00
appendInfo(signalInfo, RST_LEN, buffer, 1);
}
rulecheck();
rt_thread_mdelay(5 * 1000);//间隔3s更新一次数据
}
2023-09-12 03:40:39 +00:00
resetInfo();//复位
strcpy(TTinfo->sim,"-");
strcpy(TTinfo->xh,"-");
strcpy(TTinfo->jh,"-");
strcpy(TTinfo->jd,"-");
strcpy(TTinfo->wd,"-");
strcpy(TTinfo->ele,"-");
}
2023-06-18 01:34:09 +00:00
/**
* TT状态信息3s刷新一次TT断电后退出
*/
void repGetTT(void)
{
while(!isTCPok())//第一次运行时未上电则等待
{}
2023-09-12 03:40:39 +00:00
resetInfo();//初始化
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("repGetTT", repGetTT_thread_entry, RT_NULL, 1024 * 30, 27+2, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
// rt_kprintf("done");
}
else
{
LOG_E("thread 'repGetTT' create failure.");
return RT_ERROR;
}
}
//MSH_CMD_EXPORT(repGetTT,gett);
2023-06-19 07:56:45 +00:00
2023-09-12 03:40:39 +00:00
/**
*
* @param dout
* @param len
*/
size_t getSignals(uint8_t *dout, uint8_t len){
memcpy(dout,signalInfo,len);
return len;
}
void dwebser(int argc, char **argv)
{
static unsigned char *buffer = RT_NULL;
size_t length = 0;
char arg[100]="";
if (argc == 1) {//查询
strcpy(arg,TT_WEB_GET);
}
else if (argc == 3) {//设置
if (strcmp(argv[2],"cssc") == 0) {//最后一个参数为密码,避免意外修改
// ?tdsocketip=47.108.213.132&tdsocketport=7222
strcpy(arg,TT_WEB_SET);
strcat(arg,"?tdsocketip=");
strcat(arg,argv[1]);
strcat(arg,"&tdsocketport=7222");
}
else {
LOG_W("wrong password.");
return;
}
}
else if (argc == 2) {//须密码
LOG_W("need password.");
return;
}
static char *url = RT_NULL;
url = web_strdup(arg);
// LOG_I("%s",url);
if (url == RT_NULL)
{
LOG_E("no memory for create getTT url buffer.\n");
return;
}
if (!isTCPok() || webclient_request(url, RT_NULL, RT_NULL, 0, (void **) &buffer, &length) <= 0)
{
LOG_E("TT server or webclient is not ready.");
if (buffer)
{
web_free(buffer);
}
return;
}
// if (buffer && length && buffer[length-1] == 0x7d) //0x7d='}',首次返回的数据不完整,此处直接丢掉避免报错
{
LOG_I("%s", buffer);
web_free(buffer);
}
}
MSH_CMD_EXPORT(dwebser,'pwebser [IP] [password]'IP无校验)