重点_sizeof()和strlen().c

本文深入探讨了C语言中sizeof和strlen函数的区别与应用。sizeof用于计算变量类型的存储空间大小,而strlen则用于计算从变量值开始到第一个空字符的距离,即有效字符串的长度。文章通过多个实例演示了不同类型变量的sizeof和strlen结果,帮助读者理解两者的使用场景。

*sizeof()是计算括号中变量的类型所占的储存空间(不考虑内容)
*strlen()是计算变量值为起点的内存地址到第一个空字符’\0’的距离,以字节为单位,字符串尾部为’\0’ *简单理解:
*sizeof()是类型的长度, strlen()是有效字符串的长度,不包括空字符

#include <stdio.h>
#include <string.h>  //目的:调用取字符串长度strlen()
#define NUM 56  //声明int常量
#define STR "Hello"
#define CH 'A'

int main(void)
{
	int n = 56;
	printf("int n = 56的sizeof:%d\n\n", sizeof(n));

	/*char a[5] = {'a', 'b', 'c', 'd', 'e'};
	printf("char a[5] = \"Hello\"的sizeof:%d\n", sizeof(a));
	printf("char a[5] = \"Hello\"的strlen:%d\n\n", strlen(a));*/

	char m = 'A';
	printf("char m = \'A\'的sizeof:%d\n\n", sizeof(m));  //字符以int类型保存,所以sizeof(CH)=4

	int array1[50] = { 4, 4, 4, 4 };
	printf("int array1[50]的sizeof:%d\n\n", sizeof(array1)); //int数组以int类型保存,所以sizeof(array)=4*50=200

	long long array2[50] = { 4, 4, 4, 4 };
	printf("long long array2[50]的sizeof:%d\n\n", sizeof(array2));  //long long数组以int类型保存,所以sizeof(array)=8*50=400

	char array3[50] = { 4, 4, 4, 4 };
	printf("char array3[50] = { 4, 4, 4, 4 }的sizeof:%d\n\n", sizeof(array3));
	printf("char array3[50] = { 4, 4, 4, 4 }的strlen:%d\n\n", strlen(array3));

	char *s = "0123456789";
	printf("char *s = \"0123456789\"的sizeof:%d\n\n", sizeof(s));
	printf("char *s = \"0123456789\"的strlen:%d\n\n", strlen(s));

	char ss[] = "0123456789";
	printf("char ss[] = \"0123456789\" 的sizeof:%d\n\n", sizeof(ss));
	printf("char ss[] = \"0123456789\" 的strlen:%d\n\n", strlen(ss));

	getchar();
	return 0;

}
/****************************************************************************** * 函数名称: trt_set_video_encoder_config_xml_to_json() * 函数描述: 解析trt:SetVideoEncoderConfiguration请求的具体内容 * 输 入: soap -- soap结构体 * 输 出: json_req -- 根据请求构造的json object * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 trt_set_video_encoder_config_xml_to_json(SOAP_CONTEXT *soap, JSON_OBJPTR *json_req) { S32 i = 0; JSON_OBJPTR json_obj = NULL; JSON_OBJPTR json_sec = NULL; JSON_OBJPTR json_opt = NULL; S32 request_len = 0; S32 ch = 0; char *xml_start = NULL; char *xml_str = NULL; char **p = NULL; char charbuf[LEN_INFO] = {0}; char attr_name[2][LEN_TAG] = {{"token"}, {"anyAttribute"}}; S32 name_str_len = sizeof(attr_name[0]); char attr_value_buf[2][LEN_ANY/2] = {{0}}; S32 value_str_len = sizeof(attr_value_buf[0]); void *ptrs_to_free[SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM] = {0}; TRT_SET_VIDEO_ENCODER_CONF set_config_cmd = {0}; char resolution[LEN_VALUE] = {0}; S32 frame_rate_limit = 0; S32 bitrate_limit = 0; S32 rate_control_flag = 1; VIDEO_CAP_MAIN video_cap_main = {{0}}; if (soap == NULL || json_req == NULL) { ONVIF_TRACE("soap == NULL."); return ERROR; } if (OK != soap_usernametoken_auth(soap, UM_OPERATOR)) { ONVIF_TRACE("Auth failed\n"); soap_fault(soap, "SOAP-ENV:Sender", "ter:NotAuthorized", NULL, "Authority failure"); soap->error = 400; return ERROR; } if (soap->request_begin != NULL && soap->request_end != NULL) { request_len = soap->request_end - soap->request_begin; if (request_len < 0) { ONVIF_TRACE("request_len < 0."); goto error_parse; } xml_str = xml_start = soap->request_begin; p = (char **)&xml_str; } else { ONVIF_ERROR("soap request content is NULL."); return ERROR; } while (((*p) - xml_start) < request_len) { if ((ch = soap_get_tag(xml_start, request_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (charbuf[0] == '/') { continue; } if (TRUE == soap_match_tag(charbuf, "Configuration")) { if (IS_WHITE_SPACE(ch)) { ch = soap_parse_element_attr_out_len(xml_start, request_len, p, 2, (char *)attr_name, name_str_len, (char *)attr_value_buf, value_str_len); // if (strlen(attr_value_buf[1]) != 0) // { // json_obj = jso_from_string((const char *)attr_value_buf[1]); // if (json_obj != NULL) // { // goto out; // } // } ONVIF_TRACE("token: %s", attr_value_buf[0]); if(0 != strcmp(attr_value_buf[0], "main") && 0 != strcmp(attr_value_buf[0], "minor") && 0 != strcmp(attr_value_buf[0], "jpeg")) { goto error_parse; } set_config_cmd.config = MALLOC_AND_REGISTER(TT_VIDEO_ENCODER_CONFIG, 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->token = MALLOC_AND_REGISTER(char, strlen(attr_value_buf[0]) + 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->token) { goto error_parse; } strncpy(set_config_cmd.config->token, attr_value_buf[0], strlen(attr_value_buf[0]) + 1); } continue; } if (TRUE == soap_match_tag(charbuf, "Name")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Name: %s", charbuf); set_config_cmd.config->name = MALLOC_AND_REGISTER(char, strlen(charbuf) + 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->name) { goto error_parse; } strncpy(set_config_cmd.config->name, charbuf,strlen(charbuf) + 1); continue; } if (TRUE == soap_match_tag(charbuf, "UseCount")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("UseCount: %s", charbuf); set_config_cmd.config->use_count = atoi(charbuf); continue; } /* * * 乔安nvr有时会下发Encoding为3的报文,导致设置失败; * onvif协议不支持H265,因此参考slp平台的做法,直接去除对这部分的处理。 * */ #if 0 if (TRUE == soap_match_tag(charbuf, "Encoding")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Encoding: %s", charbuf); i = 0; while (tt_video_encoding_str[i]) { if (!strcmp(tt_video_encoding_str[i], charbuf)) { break; } i++; } if (NULL == tt_video_encoding_str[i]) { goto error_parse; } set_config_cmd.config->encoding = i; continue; } #endif if (TRUE == soap_match_tag(charbuf, "Resolution")) { if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->resolution = MALLOC_AND_REGISTER(TT_VIDEO_RESOLUTION, 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->resolution) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Width")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->resolution) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Width: %s", charbuf); set_config_cmd.config->resolution->width = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Height")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->resolution) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Height: %s", charbuf); set_config_cmd.config->resolution->height = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Quality")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Quality: %s", charbuf); set_config_cmd.config->quality = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "RateControl")) { if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->rate_control = MALLOC_AND_REGISTER(TT_VIDEO_RATE_CONTROL, 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->rate_control) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "FrameRateLimit")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("FrameRateLimit: %s", charbuf); set_config_cmd.config->rate_control->frame_rate_limit = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "EncodingInterval")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("EncodingInterval: %s", charbuf); set_config_cmd.config->rate_control->encoding_interval = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "BitrateLimit")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("BitrateLimit: %s", charbuf); set_config_cmd.config->rate_control->bitrate_limit = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "H264")) { if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->h264 = MALLOC_AND_REGISTER(TT_H264_CONFIG, 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->h264) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "GovLength")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->h264) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("GovLength: %s", charbuf); set_config_cmd.config->h264->gov_length = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "H264Profile")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->h264) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("H264Profile: %s", charbuf); i = 0; while(tt_h264_profile_str[i]) { if (!strcmp(tt_h264_profile_str[i], charbuf)) { break; } i++; } if (NULL == tt_h264_profile_str[i]) { goto error_parse; } set_config_cmd.config->h264->h264_profile = i; continue; } if (TRUE == soap_match_tag(charbuf, "Multicast")) { if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->multicast = MALLOC_AND_REGISTER(TT_MULTICAST_CONFIG, 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->multicast) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Address")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->multicast) { goto error_parse; } set_config_cmd.config->multicast->address = MALLOC_AND_REGISTER(TT_IP_ADDRESS, 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->multicast->address) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Type")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->multicast || NULL == set_config_cmd.config->multicast->address) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Type: %s", charbuf); for (i = 0; i < sizeof(tt_network_host_type)/sizeof(tt_network_host_type[0]);i++) { if (!strcmp(tt_network_host_type[i], charbuf)) { break; } } if (i == sizeof(tt_network_host_type)/sizeof(tt_network_host_type[0])) { goto error_parse; } set_config_cmd.config->multicast->address->type = i; continue; } if (TRUE == soap_match_tag(charbuf, "IPv4Address")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->multicast || NULL == set_config_cmd.config->multicast->address) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("IPv4Address: %s", charbuf); set_config_cmd.config->multicast->address->ipv4_address = MALLOC_AND_REGISTER(char, strlen(charbuf) + 1, ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); if (NULL == set_config_cmd.config->multicast->address->ipv4_address) { goto error_parse; } strncpy(set_config_cmd.config->multicast->address->ipv4_address, charbuf,strlen(charbuf) + 1); continue; } if (TRUE == soap_match_tag(charbuf, "Port")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->multicast) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Port: %s", charbuf); set_config_cmd.config->multicast->port = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "TTL")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->multicast) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("TTL: %s", charbuf); set_config_cmd.config->multicast->ttl = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "AutoStart")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->multicast) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("AutoStart: %s", charbuf); i = 0; while(xsd_boolean_str[i]) { if (!strcmp(xsd_boolean_str[i], charbuf)) { break; } i++; } if (NULL == xsd_boolean_str[i]) { goto error_parse; } set_config_cmd.config->multicast->auto_start = i; continue; } if (TRUE == soap_match_tag(charbuf, "SessionTimeout")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("SessionTimeout: %s", charbuf); /* session_timeout并未被用的,忽略错误,避免因其格式出错导致配置失败 */ soap_xsd_s2duration(charbuf, &set_config_cmd.config->session_timeout); continue; } if (TRUE == soap_match_tag(charbuf, "ForcePersistence")) { if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("ForcePersistence: %s", charbuf); i = 0; while(xsd_boolean_str[i]) { if (!strcmp(xsd_boolean_str[i], charbuf)) { break; } i++; } if (NULL == xsd_boolean_str[i]) { goto error_parse; } set_config_cmd.force_persistence = i; continue; } } /* bug #434969, 在大华NVR上有抓到SetVideoEncoderConfiguration中没有Configuratio内容的报文, * 为防止处理这样的异常报文时set_config_cmd.config为NULL空指针,增加以下判断防止系统崩溃*/ if(!set_config_cmd.config) { goto error_parse; } if(set_config_cmd.config->h264) { if (TT_H264_PROFILE_MAIN != set_config_cmd.config->h264->h264_profile) { SOAP_IF_FAIL_RET(soap_fault(soap, "SOAP-ENV:Receiver", "ter:InvalidArgVal", "ter:ConfigModify", "NVT does not support the function")); soap->error = SOAP_FAULT; goto error_parse; } } if(set_config_cmd.config->rate_control) { /* TODO: 比较是否超出最大值 */ /* if((minFr > req->Configuration->RateControl->frame_rate_limit) || (maxFr < req->Configuration->RateControl->frame_rate_limit) || (minBr > req->Configuration->RateControl->bitrate_limit) || (maxBr < req->Configuration->RateControl->bitrate_limit)) { return onvif_fault(soap, "SOAP-ENV:Sender", "ter:InvalidArgVal", "ter:ConfigModify", NULL); }*/ frame_rate_limit = (1 << 16) + set_config_cmd.config->rate_control->frame_rate_limit; bitrate_limit = select_appropriate_bitrate_limit(set_config_cmd.config->token, set_config_cmd.config->rate_control->bitrate_limit); if (ERROR == bitrate_limit) { goto error_parse; } } else { rate_control_flag = FALSE; } snprintf(resolution, LEN_VALUE, "%d*%d", set_config_cmd.config->resolution->width, set_config_cmd.config->resolution->height); ONVIF_TRACE("VideoPrama:%s,%d,%s,%d,%d\n", set_config_cmd.config->token, set_config_cmd.config->quality, resolution, frame_rate_limit, bitrate_limit); json_obj = jso_new_obj(); jso_obj_add(json_obj, "video", json_sec = jso_new_obj()); jso_obj_add(json_sec, set_config_cmd.config->token, json_opt = jso_new_obj()); jso_add_string(json_opt, "resolution", resolution); /* 设置quality时,DUT只支持1、3、5(低中高三挡),但外司NVR可支持更多选项, * 当DUT不支持设置的quality时,SLP平台一致,就近保存为1、3、5三档。 */ if (0 == ds_read(VIDEO_CAP_MAIN_PATH, &video_cap_main, sizeof(VIDEO_CAP_MAIN))) { if ((VIDEO_QUALITY_S <= set_config_cmd.config->quality) && (VIDEO_QUALITY_L >= set_config_cmd.config->quality)) { // jso_add_int(json_opt, "quality", set_config_cmd.config->quality); } } else { i = 0; while (QUALITYS_NUM > i) { if (set_config_cmd.config->quality >= video_cap_main.qualitys[i]) { ++i; } else { break; } } if (QUALITYS_NUM == i) { set_config_cmd.config->quality = video_cap_main.qualitys[QUALITYS_NUM - 1]; } else if (0 == i) { set_config_cmd.config->quality = video_cap_main.qualitys[0]; } else { set_config_cmd.config->quality = video_cap_main.qualitys[i - 1]; } // jso_add_int(json_opt, "quality", set_config_cmd.config->quality); } if(rate_control_flag) { if (frame_rate_limit) { ; } // jso_add_int(json_opt, "frame_rate", frame_rate_limit); // jso_add_int(json_opt, "bitrate", bitrate_limit); } jso_add_string(json_obj, "method", "set"); // out: *json_req = json_obj; free_ptrs(ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); return OK; error_parse: free_ptrs(ptrs_to_free, SET_VIDEO_ENCODER_CONFIGS_MAX_FREE_NUM); return ERROR; } 代码什么意思,重点解释与set_config_cmd相关部分
09-02
``` static void Regenerat_STA(void) { osTimerStop(RefreshTimerHandle); //关闭页面刷新定时器 //如果再生模式是及时再生 if(Machine_Data_Info.Regenerat_Model == Timely) { osTimerStop(STATimerHandle); //关闭10min后启动再生定时器 } //验证其IC号 vTaskSuspend(defaultTaskHandle); //挂起RFID效验任务 uint8_t Check = Regenerant_Check.RFID_IC_Check(); //验证RFID IC号 vTaskResume(defaultTaskHandle); //恢复RFID效验任务 //Check = 0; if(Check == 0) { //发送红灯显示到水龙头 Public.Memory_Clr(Stopcock_Signal.pucSend_Buffer,sizeof(Stopcock_Signal.pucSend_Buffer)); Stopcock_Signal.pucSend_Buffer[0] = 0xAA; Stopcock_Signal.pucSend_Buffer[1] = 0x04; Stopcock_Signal.pucSend_Buffer[2] = 0x04; Stopcock_Signal.pucSend_Buffer[3] = 0x0D; Stopcock_Signal.SendArray(Stopcock_Signal.pucSend_Buffer,4); //主机上显示红灯 RGB_RED(3); //开始再生 Regenerat_Model.Regenerat_Deal(); //主机上显示白灯 RGB_WHITE(3); //发送白灯显示到水龙头 Public.Memory_Clr(Stopcock_Signal.pucSend_Buffer,sizeof(Stopcock_Signal.pucSend_Buffer)); Stopcock_Signal.pucSend_Buffer[0] = 0xAA; Stopcock_Signal.pucSend_Buffer[1] = 0x04; Stopcock_Signal.pucSend_Buffer[2] = 0x02; Stopcock_Signal.pucSend_Buffer[3] = 0x0D; Stopcock_Signal.SendArray(Stopcock_Signal.pucSend_Buffer,4); //网络连接正常的情况下,发送软化效率到小程序 if(LZT_AI_WB2.SmartConifg_Flag == 1) { Public.Memory_Clr((uint8_t *)Send_JSONBuf,strlen((const char*)Send_JSONBuf)); //清除发送buff sprintf((char *)Send_JSONBuf,SOFTEN_EFFICIENCY_UPLOAD_ALIYUN,2,san_yuan_zu_id.nameid, Machine_Data_Info.Soften_Efficiency*10, //软化效率 (Machine_Data_Info.Can_Deal_Volume - Machine_Data_Info.Use_Water_Volume)/100); //本次软水剩余量 LZT_AI_WB2.Publish_INFO((uint8_t *)Send_JSONBuf); //发送到阿里云 } } else { //发送异常消息 //校验失败,再生剂已经用完,请更换新的再生剂(3-4) Public.Memory_Clr(Abnormal_Deal.pucSend_Buffer,sizeof(Abnormal_Deal.pucSend_Buffer)); //清空发送缓冲区 Abnormal_Deal.pucSend_Buffer[0] = 0xAA; Abnormal_Deal.pucSend_Buffer[1] = 0x04; //异常类型 Abnormal_Deal.pucSend_Buffer[2] = 0x02; //异常优先级 Abnormal_Deal.pucSend_Buffer[3] = 0x0D; Abnormal_Deal.SendArray(Abnormal_Deal.pucSend_Buffer,4); //发送异常消息 } osTimerStart(RefreshTimerHandle,10000); //打开页面刷新定时器 System_STA_Machine.System_STA_Machine_Status = STANDBY_STA; //切换回待机状态 }```解释代码
03-20
这两份代码呈现的,/****************************************************************************** * Copyright (c) 2020-2020 TP-Link Technologies CO.,LTD. * * Filename: diagnose_main.h * Version: 1.0 * Description: 自动诊断头文件 * Author: 赖滨绍<laibinshao@tp-link.com.cn> * Date: 2020-12-10 ******************************************************************************/ #ifndef _H_DIAGNOSE_MAIN #define _H_DIAGNSOE_MAIN #include "diagnose_commom.h" typedef enum { DIAGNOSE_WIRELESS=0, /*无线诊断*/ DIAGNOSE_GATEWAY, /*网关诊断*/ DIAGNOSE_ADDR1, /*外网1诊断*/ DIAGNOSE_ADDR2, /*外网2诊断*/ DIAGNOSE_BASE_CLOUD, /*基础云诊断*/ #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT DIAGNOSE_LTE_DNS1, /* LTE检测的DNS地址1 */ DIAGNOSE_LTE_DNS2, /* LTE检测的DNS地址2 */ DIAGNOSE_USER_ADDR1, /* 用户自定义地址1 */ DIAGNOSE_USER_ADDR2, /* 用户自定义地址2 */ #endif DIAGNOSE_STORAGE, /*存储诊断*/ DIAGNOSE_FIRMWARE, /*固件诊断*/ DIAGNOSE_SAFETY, /*安全诊断(视频加密)*/ DIAGNOSE_MAX } DIAGNOSE_PARA; /*标记诊断项对应的位*/ typedef enum { NET_GATEWAY = 0, /*网关*/ NET_INTERNET1, /*外网1*/ NET_INTERNET2, /*外网2*/ NET_BASE_CLOUD, /*基础云*/ /* 由于外销基础云域名不让ping, 暂改成官网域名 “www.tp-link.com” */ #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT NET_4G_DET_DNS1, /* 4G网络检测的DNS地址1 */ NET_4G_DET_DNS2, /* 4G网络检测的DNS地址2 */ NET_USER_DEFINED1, /* 用户自定义地址1 */ NET_USER_DEFINED2, /* 用户自定义地址2 */ #endif NET_MAX }NETWORK_PARA; /*网络诊断参数,表示在g_ping_array数组中的位置*/ typedef enum { CSTG_OFFLINE = 0, /*云掉线*/ CSTG_ONLINE /*云在线*/ } CSTG_STAT; /*云状态*/ #endif /****************************************************************************** * Copyright (c) 2020-2020 TP-Link Technologies CO.,LTD. * * Filename: diagnose_main.c * Version: 1.0 * Description: 自动诊断部分 * Author: 赖滨绍<laibinshao@tp-link.com.cn> * Date: 2020-12-10 ******************************************************************************/ #include <sys/types.h> #include <arpa/inet.h> #include <errno.h> #include "diagnose_main.h" #include "msg_utils.h" #include "telnet.h" #define ITEMS_TIMEOUT_VAL 15 /*网络诊断超时时间*/ #define MAX_CLIENTS_NUM 10 /*接受客户端请求诊断数量*/ #define CLIENT_GET_TIMEOUT 30 /*客户端get请求最大次数*/ #define CLIENT_RECLAIM_INTERVAL 50 /*客户端诊断实例资源回收超时*/ DIAG_ADDR g_default_address; /*网络诊断地址*/ LOCAL S32 g_diagnose_timerid = ERROR; /*网络诊断超时定时器*/ LOCAL S8 g_is_auto_diagnose = 0; /*是否收到自诊断消息*/ PHY_STATUS g_phy_stat; /*物理链路状态*/ TASK_STRUCT g_client_array[MAX_CLIENTS_NUM]; /*记录客户端信息*/ NETWORK_STRUCT g_network_array[ADDR_COUNTS]; /*网络地址诊断信息*/ CONNECT_INFO g_connect_info; STORAGE_INFO g_storage_info; FIRMWARE_STRUCT g_firmware_info; VIDEO_ENCRYPTION g_video_encryption; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT #define NET_DETECTION_DEFAULT_DNS1 "8.8.8.8" #define NET_DETECTION_DEFAULT_DNS2 "www.google.com" LOCAL S8 g_is_lte_diagnose = 0; /* 是否是lte模块发起的自诊断信息 */ LOCAL S8 g_is_other_model_diagnose = 0; /* 其他模块发起的自诊断信息 */ #endif LOCAL S8 g_task_running = 0; /*当前是否进行了除网络诊断外的其他诊断*/ /*********************************************************************************************** *函数: *描述:加载数据模型中的诊断地址 *参数: *返回值: ***********************************************************************************************/ S32 load_network_address() { int index = 0; DIAG_ADDR target_addr; memset(&target_addr, 0, sizeof(DIAG_ADDR)); if (0 == ds_read(DIAGNOSE_ADDR_PATH, (void*)(&target_addr), sizeof(DIAG_ADDR))) { DIAGNOSE_WARNING("diagnose read address error."); return ERROR; } /*第0位保留为网关地址*/ for(index = 1; index < ADDR_COUNTS; index++) { strncpy(g_default_address.diag_addr[index], target_addr.diag_addr[index], ADDR_LEN); } DIAGNOSE_DEBUG("internet1:%s internet2:%s basecloud:%s", g_default_address.diag_addr[1], g_default_address.diag_addr[2], g_default_address.diag_addr[3]); return OK; } /*********************************************************************************************** *函数: *描述:关注数据据块,加载网关地址 *参数: *返回值: ***********************************************************************************************/ void load_gateway_address() { LINK_STATUS link_status = {0}; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; LTE_DHCP_IP lte_dhcp_ip = {0}; ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA)); if(lte_config.internet_wired_enable == 0 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 0)) { ds_read(LTE_DHCP_IP_PATH, (U8*)&lte_dhcp_ip, sizeof(LTE_DHCP_IP)); ip_to_str(lte_dhcp_ip.gateway, g_default_address.diag_addr[0]); }else #endif { ds_read(LINK_STATUS_PATH, &link_status, sizeof(LINK_STATUS)); ip_to_str(link_status.gateway, g_default_address.diag_addr[0]); } DIAGNOSE_DEBUG("gateway:%s, internet1:%s,internet2:%s,cloud:%s",g_default_address.diag_addr[0], g_default_address.diag_addr[1],g_default_address.diag_addr[2],g_default_address.diag_addr[3]); } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT /*********************************************************************************************** *函数: *描述:关注lte模块net_det数据块,加载用户自定义地址 *参数: *返回值: ***********************************************************************************************/ void load_user_defined_address() { LTE_CONFIG_NET_DETECTION net_det = {0}; if(0 == ds_read(LTE_NET_DET_PATH, (U8*)&net_det, sizeof(LTE_CONFIG_NET_DETECTION))) { DIAGNOSE_ERROR("read path: %s\n failed.", LTE_NET_DET_PATH); return; } DIAGNOSE_ERROR("[LTE] add default dns address:%s", NET_DETECTION_DEFAULT_DNS1); strncpy(g_default_address.diag_addr[NET_4G_DET_DNS1], NET_DETECTION_DEFAULT_DNS1, ADDR_LEN); DIAGNOSE_ERROR("[LTE] add default dns address:%s", NET_DETECTION_DEFAULT_DNS2); strncpy(g_default_address.diag_addr[NET_4G_DET_DNS2], NET_DETECTION_DEFAULT_DNS2, ADDR_LEN); if(strlen(net_det.hostname_1) != 0) { DIAGNOSE_ERROR("add user defined address:%s.", net_det.hostname_1); strncpy(g_default_address.diag_addr[NET_USER_DEFINED1], net_det.hostname_1, ADDR_LEN); }else { memset(g_default_address.diag_addr[NET_USER_DEFINED1], 0, ADDR_LEN); } if(strlen(net_det.hostname_2) != 0) { DIAGNOSE_ERROR("add user defined address:%s.", net_det.hostname_2); strncpy(g_default_address.diag_addr[NET_USER_DEFINED2], net_det.hostname_2, ADDR_LEN); }else { memset(g_default_address.diag_addr[NET_USER_DEFINED2], 0, ADDR_LEN); } DIAGNOSE_ERROR("user defined addrees1:%s, user define address2:%s.", g_default_address.diag_addr[NET_USER_DEFINED1], g_default_address.diag_addr[NET_USER_DEFINED2]); } #endif /*********************************************************************************************** *函数:ip_to_str *描述:将网络字节序IP转成字符形式 *参数: *返回值: ***********************************************************************************************/ S32 ip_to_str(U32 ip_addr, char* str_ip) { struct in_addr dst; if (NULL == str_ip) { return ERROR; } memset(str_ip, 0, IP_LEN); dst.s_addr = ip_addr; if (NULL == inet_ntop(AF_INET, (void*)&dst, str_ip, IP_LEN)) { return ERROR; } return OK; } void diagnose_stop(void) { int index =0; g_task_running = 0; if (g_is_auto_diagnose) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(g_is_lte_diagnose) { lte_diagnose_reply_result(); g_is_lte_diagnose = 0; }else #endif { diagnose_reply_result(); /*诊断完成后发送诊断消息*/ } g_is_auto_diagnose = 0; } DIAGNOSE_DEBUG("diagnose stop, save diagnose result to network config\n"); diagnose_result_save_config(); if (ERROR != g_diagnose_timerid) { inet_del_timer(g_diagnose_timerid); g_diagnose_timerid = ERROR; } for (index = 0; index < ADDR_COUNTS; index++) { if (TESTED != g_network_array[index].status) { g_network_array[index].status = TESTED; g_network_array[index].res = DIAGNOSE_FAILED; } if (g_network_array[index].do_telnet) { if (g_network_array[index].tel_state != TESTED) { g_network_array[index].tel_res = DIAGNOSE_FAILED; } telnet_stop(&g_network_array[index]); } } } /*********************************************************************************************** *函数:check_signal_quality *描述:获取无线信号强度 *参数: *返回值: ***********************************************************************************************/ S32 check_signal_quality(CONNECT_INFO* ptr_wireless) { DS_HANDLE_CONTEXT ds_context; JSON_OBJPTR data_obj = NULL; const char* ptr_value = NULL; int error_code = OK; PHY_STATUS phy_status = {0}; if (NULL == ptr_wireless) { return ERROR; } ds_read(PHY_STATUS_PATH, &phy_status, sizeof(PHY_STATUS)); if (1 == phy_status.ether || 0 == phy_status.wlan) { strncpy(ptr_wireless->link_type, "ethernet", LINK_TYPE_LEN); return OK; } /*构造jason请求sd信息*/ memset(&ds_context, 0, sizeof(DS_HANDLE_CONTEXT)); if (NULL == (ds_context.req_obj = jso_new_obj())) { return ERROR; } if (NULL == (data_obj = jso_new_obj())) { error_code = ERROR; goto out; } jso_obj_add(ds_context.req_obj, "network", data_obj); jso_add_string(data_obj, "get_connection_type", ""); jso_add_string(ds_context.req_obj, "method", "do"); ds_context.group_mask = ROOT_MASK; ds_context.method = METHOD_DO; ds_handle(&ds_context); if (NULL == ds_context.res_obj) { error_code = ERROR; goto out; } if (NULL == (ptr_value = jso_obj_get_string_origin(ds_context.res_obj, "link_type"))) { error_code = ERROR; goto out; } strncpy(ptr_wireless->link_type, ptr_value, LINK_TYPE_LEN); if (0 == strcmp(ptr_value, "ethernet")) { /*有线连接*/ error_code = OK; goto out; } /*无线连接*/ if (NULL == (ptr_value = jso_obj_get_string_origin(ds_context.res_obj, "ssid"))) { error_code = ERROR; goto out; } strncpy(ptr_wireless->ssid, ptr_value, WIFI_SSID_MAX_LEN); jso_obj_get_int(ds_context.res_obj, "rssi", &(ptr_wireless->rssi)); error_code = OK; DIAGNOSE_INFO("ssid:%s rssi:%d", ptr_wireless->ssid, ptr_wireless->rssi); out: if (NULL != ds_context.req_obj) { jso_free_obj(ds_context.req_obj); ds_context.req_obj = NULL; } if (NULL != ds_context.res_obj) { jso_free_obj(ds_context.res_obj); ds_context.res_obj = NULL; } return error_code; } /*********************************************************************************************** *函数: *描述:网络诊断数组初始化 *参数: *返回值: ***********************************************************************************************/ void address_array_init() { /*数组第0位放网关地址*/ memset(&g_network_array[NET_GATEWAY], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_GATEWAY].para_name, "gateway", PARA_NAME_LEN); g_network_array[NET_GATEWAY].params_code = DIAGNOSE_GATEWAY; g_network_array[NET_GATEWAY].test = 1; /*数组第1位放外网地址1*/ memset(&g_network_array[NET_INTERNET1], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_INTERNET1].para_name, "internet1", PARA_NAME_LEN); g_network_array[NET_INTERNET1].params_code = DIAGNOSE_ADDR1; g_network_array[NET_INTERNET1].test = 1; /*数组第2位放外网地址2*/ memset(&g_network_array[NET_INTERNET2], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_INTERNET2].para_name, "internet2", PARA_NAME_LEN); g_network_array[NET_INTERNET2].params_code = DIAGNOSE_ADDR2; g_network_array[NET_INTERNET2].test = 1; /*数组第3位放云服务器地址*/ memset(&g_network_array[NET_BASE_CLOUD], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_BASE_CLOUD].para_name, "cloud", PARA_NAME_LEN); g_network_array[NET_BASE_CLOUD].params_code = DIAGNOSE_BASE_CLOUD; g_network_array[NET_BASE_CLOUD].test = 1; g_network_array[NET_BASE_CLOUD].do_telnet = 1; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT memset(&g_network_array[NET_4G_DET_DNS1], 0, sizeof(NETWORK_STRUCT)); memset(&g_network_array[NET_4G_DET_DNS2], 0, sizeof(NETWORK_STRUCT)); memset(&g_network_array[NET_USER_DEFINED1], 0, sizeof(NETWORK_STRUCT)); memset(&g_network_array[NET_USER_DEFINED2], 0, sizeof(NETWORK_STRUCT)); LTE_CONFIG_NET_DETECTION net_det = {0}; if(0 == ds_read(LTE_NET_DET_PATH, (U8*)&net_det, sizeof(LTE_CONFIG_NET_DETECTION))) { DIAGNOSE_ERROR("read path %s failed.", LTE_NET_DET_PATH); return; } if(net_det.ping_enable == 1 && g_is_lte_diagnose == 1 && g_is_other_model_diagnose == 0) { /* 如果是LTE模块发起的ping检测只检测dns1 dns2用户自定义地址 */ g_network_array[NET_INTERNET1].test = 0; g_network_array[NET_INTERNET2].test = 0; /* 如果是LTE模块发起的ping检测暂时不检测网关地址 */ g_network_array[NET_GATEWAY].test = 0; /* 如果是LTE模块发起的ping检测不对bata云进行telnet */ g_network_array[NET_BASE_CLOUD].do_telnet = 0; g_network_array[NET_BASE_CLOUD].test = 0; /* 数组第4位放LTE检测的DNS地址1 */ strncpy(g_network_array[NET_4G_DET_DNS1].para_name, "dns1", PARA_NAME_LEN); g_network_array[NET_4G_DET_DNS1].params_code = DIAGNOSE_LTE_DNS1; g_network_array[NET_4G_DET_DNS1].test = 1; /* 数组第5位放LTE检测的DNS地址2 */ strncpy(g_network_array[NET_4G_DET_DNS2].para_name, "dns2", PARA_NAME_LEN); g_network_array[NET_4G_DET_DNS2].params_code = DIAGNOSE_LTE_DNS2; g_network_array[NET_4G_DET_DNS2].test = 1; /* 数组第6位放用户自定义地址1(如果有配置的话) */ if(strlen(net_det.hostname_1) != 0) { strncpy(g_network_array[NET_USER_DEFINED1].para_name, "hostname_1", PARA_NAME_LEN); g_network_array[NET_USER_DEFINED1].params_code = DIAGNOSE_USER_ADDR1; g_network_array[NET_USER_DEFINED1].test = 1; } /* 数组第7位放用户自定义地址2(如果有配置的话) */ if(strlen(net_det.hostname_2) != 0) { strncpy(g_network_array[NET_USER_DEFINED2].para_name, "hostname_2", PARA_NAME_LEN); g_network_array[NET_USER_DEFINED2].params_code = DIAGNOSE_USER_ADDR2; g_network_array[NET_USER_DEFINED2].test = 1; } } #endif return; } /*********************************************************************************************** *函数: *描述:ping结束时,保存错误码,保存ip、域名及ping结果,设置相应标志 *参数: *返回值: ***********************************************************************************************/ void save_result_callback(struct _DIAGNOSE_CONTEXT* context) { int index = 0; if (NULL == context) { return; } g_network_array[context->index].status = TESTED; /*设置诊断状态为结束*/ if (NULL != context->dnsData) { strncpy(g_network_array[context->index].str_domain, context->dnsData->url, ADDR_LEN); /*保存域名*/ } if (0 == context->ipAddr && NULL != context->dnsData) /*dns解析失败*/ { g_network_array[context->index].res = DIAGNOSE_FAILED; goto exit; } ip_to_str(context->ipAddr, g_network_array[context->index].str_ip);/*保存ip地址*/ if (PING_SUCCESS != context->status) { g_network_array[context->index].res = DIAGNOSE_FAILED; /*设置诊断结果为失败*/ goto exit; } g_network_array[context->index].res = DIAGNOSE_SUCCESS; /*设置诊断结果为成功*/ DIAGNOSE_DEBUG("save %s OK", g_network_array[context->index].para_name); exit: /*是否所有诊断结束*/ for (index = 0; index < ADDR_COUNTS; index++) { if (0 == g_network_array[index].test) { continue; } if (g_network_array[index].do_telnet && TESTED != g_network_array[index].tel_state) { break; } if (TESTED != g_network_array[index].status) { break; } } if (ADDR_COUNTS == index) { diagnose_stop(); } return; } /*********************************************************************************************** *函数: *描述:发起ping请求 *参数: *返回值:ERROR:ping失败 OK:ping 发起成功 ***********************************************************************************************/ S32 ping_start(char* addr, U32 index, U32* context_id) { U32 icmpid = 0; IP_ADDR ip_addr = {0}; DIAGNOSE_DNS_DATA* dns_data = NULL; if (NULL == addr || NULL == context_id) { return ERROR; } /*ip合法检查*/ if (0 == inet_pton(AF_INET, addr, (void*)&ip_addr)) { if (FALSE == valid_domain(addr)) { DIAGNOSE_WARNING("Invalid target domain name format."); return ERROR; } dns_data = (DIAGNOSE_DNS_DATA *)DIAGNOSE_MALLOC(sizeof(DIAGNOSE_DNS_DATA)); if (NULL == dns_data) { DIAGNOSE_WARNING("Failed to alloc memory, size=%d.", sizeof(DIAGNOSE_DNS_DATA)); return ERROR; } memset(dns_data, 0, sizeof(DIAGNOSE_DNS_DATA)); strncpy(dns_data->url, addr, ADDR_LEN); } else { if (FALSE == valid_ip_addr(ip_addr.ipAddr)) { DIAGNOSE_DEBUG("Invalid target ip format."); return ERROR; } } /*发起ping请求*/ DIAGNOSE_ERROR("start ping:%s", (NULL == dns_data) ? addr : dns_data->url); icmpid = diagnose_ping(dns_data, ip_addr.ipAddr, DEFAULT_PING_SIZE, DEFAULT_PING_TIMES, DEFAULT_PING_TIMEOUT, index, save_result_callback); if (CONTEXT_IDLE == icmpid) { DIAGNOSE_FREE(dns_data); return ERROR; } *context_id = icmpid; return OK; } /*********************************************************************************************** *函数:network_diagnose *描述:基础网络诊断 *参数: *返回值: ***********************************************************************************************/ S32 network_diagnose() { int index = 0; U32 context_id = 0; int ping_stat = 0; address_array_init(); for (index = 0; index < ADDR_COUNTS; index++) { if (0 == g_network_array[index].test) { continue; } ping_stat = ping_start(g_default_address.diag_addr[index], index, &context_id); if (OK != ping_stat) { DIAGNOSE_DEBUG("ping start failed"); g_network_array[index].res = DIAGNOSE_FAILED; g_network_array[index].status = TESTED; } else { g_network_array[index].status = TESTING; } if (g_network_array[index].do_telnet) { if (OK == telnet_start(g_default_address.diag_addr[index], &g_network_array[index])) { g_network_array[index].tel_state = TESTING; } else { g_network_array[index].tel_state = TESTED; g_network_array[index].tel_res = DIAGNOSE_FAILED; } } } g_diagnose_timerid = inet_add_timer(diagnose_timer_handle, 0, ITEMS_TIMEOUT_VAL, EXECUTE_SINGLE); if (ERROR == g_diagnose_timerid) { return ERROR; } return OK; } /*********************************************************************************************** *函数:get_sd_info *描述:通过ds_handle获得sd卡信息 *参数: *返回值: ***********************************************************************************************/ LOCAL S32 get_sd_info(STORAGE_INFO* ptr_storage) { const char* ptr = NULL; int error_code = OK; JSON_OBJPTR data_obj = NULL; JSON_OBJPTR data_array = NULL; JSON_OBJPTR array_obj = NULL; JSON_OBJPTR json_harddisk_manage = NULL; JSON_OBJPTR json_harddisk_info = NULL; JSON_OBJPTR json_harddisk_NO = NULL; JSON_OBJPTR json_harddisk_parse = NULL; DS_HANDLE_CONTEXT ds_context; if (NULL == ptr_storage) { return ERROR; } /*构造jason请求sd信息*/ memset(&ds_context, 0, sizeof(DS_HANDLE_CONTEXT)); if (NULL == (ds_context.req_obj = jso_new_obj())) { DIAGNOSE_WARNING("jso_new_obj failed."); return ERROR; } if (NULL == (data_obj = jso_new_obj())) { error_code = ERROR; goto out; } jso_obj_add(ds_context.req_obj, "harddisk_manage", data_obj); jso_add_string(ds_context.req_obj, "method", "get"); if (NULL == (data_array = jso_new_array())) { error_code = ERROR; goto out; } jso_obj_add(data_obj, "name", data_array); if (NULL == (array_obj = jso_new_string("harddisk"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); if (NULL == (array_obj = jso_new_string("video"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); if (NULL == (array_obj = jso_new_string("picture"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); if (NULL == (data_array = jso_new_array())) { error_code = ERROR; goto out; } jso_obj_add(data_obj, "table", data_array); if (NULL == (array_obj = jso_new_string("hd_info"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); /*发送请求*/ ds_context.group_mask = ROOT_MASK; ds_context.method = METHOD_GET; ds_handle(&ds_context); if(NULL == ds_context.res_obj) { error_code = ERROR; goto out; } /*读取返回值*/ if (NULL == (json_harddisk_manage = jso_obj_get(ds_context.res_obj, "harddisk_manage"))) { error_code = ERROR; goto out; } if (NULL == (json_harddisk_info = jso_obj_get(json_harddisk_manage, "hd_info"))) { error_code = ERROR; goto out; } if (NULL == (json_harddisk_NO = jso_array_get_idx(json_harddisk_info, 0))) { error_code = ERROR; goto out; } if (NULL == (json_harddisk_parse = jso_obj_get(json_harddisk_NO, "hd_info_1"))) { error_code = ERROR; goto out; } if (NULL != (ptr= jso_obj_get_string_origin(json_harddisk_parse, "total_space"))) /*sd总大小*/ { strncpy(ptr_storage->size.total, ptr, SD_SIZE_LEN); } if (NULL != (ptr = jso_obj_get_string_origin(json_harddisk_parse, "free_space"))) /*sd剩余空间*/ { strncpy(ptr_storage->size.free, ptr, SD_SIZE_LEN); } if (NULL != (ptr = jso_obj_get_string_origin(json_harddisk_parse,"record_duration")))/*sd已录时长*/ { strncpy(ptr_storage->recorded_time, ptr, SD_SIZE_LEN); } if (NULL != (ptr = jso_obj_get_string_origin(json_harddisk_parse, "status"))) /*sd状态*/ { strncpy(ptr_storage->available, ptr, SD_STATUS_LEN); } error_code = OK; out: if (NULL != ds_context.req_obj) { jso_free_obj(ds_context.req_obj); ds_context.req_obj = NULL; } if (NULL != ds_context.res_obj) { jso_free_obj(ds_context.res_obj); ds_context.res_obj = NULL; } return error_code; } /*********************************************************************************************** *函数:storage_diagnose *描述:存储诊断 *参数: *返回值: ***********************************************************************************************/ LOCAL S32 storage_diagnose(STORAGE_INFO* ptr_storage) { if (NULL == ptr_storage) { return ERROR; } DIAGNOSE_DEBUG("start storage diagnose"); /*云存储*/ ds_read(CSTG_UPLOAD_ENABLE_PATH, &(ptr_storage->upload_enable), sizeof(CSTG_UPLOAD_ENABLE)); ds_read(CSTG_IS_UPLOADING_PATH, &(ptr_storage->uploading), sizeof(CSTG_IS_UPLOADING)); /*本地存储*/ ds_read(PLAN_ADVANCE_PATH, &(ptr_storage->plan_advance), sizeof(PLAN_ADVANCE));/*预录延录时间*/ get_sd_info(ptr_storage); /*请求sd 状态、总大小、剩余空间、已录时长*/ return OK; } /*********************************************************************************************** *函数: *描述:获取固件是否有更新 *参数: *返回值: ***********************************************************************************************/ S32 request_fw_status() { DS_HANDLE_CONTEXT ds_context = {0}; JSON_OBJPTR data_obj = NULL; if (NULL == (ds_context.req_obj = jso_new_obj())) { return ERROR; } if (NULL == (data_obj = jso_new_obj())) { return ERROR; } jso_obj_add(ds_context.req_obj, "cloud_status", data_obj); jso_add_string(ds_context.req_obj, "method", "get"); jso_add_string(data_obj, "name", "check_fw_ver"); ds_context.group_mask = ROOT_MASK; ds_context.method = METHOD_GET; ds_handle(&ds_context); if(NULL == ds_context.res_obj) { return ERROR; } return OK; } /*********************************************************************************************** *函数:firmware_diagnose *描述:固件诊断 *参数: *返回值: ***********************************************************************************************/ LOCAL S32 firmware_diagnose(FIRMWARE_STRUCT* ptr_firmware) { NEW_FIRMWARE new_firm; if (NULL == ptr_firmware) { return ERROR; } DIAGNOSE_DEBUG("start firmware diagnose"); memset(&new_firm, 0, sizeof(NEW_FIRMWARE)); if (0 == ds_read(CLOUD_CONFIG_NEWFW_PATH, &new_firm, sizeof(NEW_FIRMWARE))) { return ERROR; } ptr_firmware->fw_new_notify = new_firm.fw_new_notify; return OK; } /*********************************************************************************************** *函数:safety_diagnose *描述:安全诊断 *参数: *返回值: ***********************************************************************************************/ void safety_diagnose(VIDEO_ENCRYPTION* ptr_videoencryption) { if (NULL == ptr_videoencryption) { return; } DIAGNOSE_DEBUG("start safety diagnose"); ptr_videoencryption->is_encryption = 1; return; } S32 diagnose_msg_send(int res) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(g_is_lte_diagnose) { LTE_NETWORK_DIAGNOSE_RPL_MSG msg = {0}; DIAGNOSE_ERROR("send lte model diagnose msg out id:%d", res); msg.res = res; return msg_send(LTE_NETWORK_DIAGNOSE_RPL_MID, (U8 *)&msg, sizeof(msg)); }else #endif { NETWORK_DIAGNOSE_RPL_MSG msg = {0}; DIAGNOSE_DEBUG("send diagnose msg out id:%d", res); msg.res = res; return msg_send(NETWORK_DIAGNOSE_RPL_MID, (U8 *)&msg, sizeof(msg)); } } S32 diagnose_reply_result(void) { int res = 0; if (LINK_DOWN == g_phy_stat.ether && LINK_DOWN == g_phy_stat.wlan) { res = NETWORK_PHY_DOWN; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_GATEWAY].res) { res = NETWORK_GATEWAY_FAILED; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_INTERNET1].res && DIAGNOSE_FAILED == g_network_array[NET_INTERNET2].res) { if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_FAILED; goto out; } res = NETWORK_OK; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_CLOUD_FAILED; goto out; } res = NETWORK_OK; out: return diagnose_msg_send(res); } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT S32 lte_diagnose_reply_result(void) { int res = 0; LTE_CONFIG_NET_DETECTION lte_net_detection; memset(&lte_net_detection, 0, sizeof(LTE_CONFIG_NET_DETECTION)); ds_read(LTE_NET_DET_PATH, &lte_net_detection, sizeof(LTE_CONFIG_NET_DETECTION)); INFO_INTERNET info_internet; memset(&info_internet, 0, sizeof(INFO_INTERNET)); ds_read(INFO_INTERNET_PATH, &info_internet, sizeof(INFO_INTERNET)); if (INTERNET_4G_CONNECTED != info_internet.link_status) { res = NETWORK_4G_DOWN; goto out; } if(strlen(lte_net_detection.hostname_1) != 0 || strlen(lte_net_detection.hostname_2) != 0) { if(DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS1].res && DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS2].res) { if(g_network_array[NET_USER_DEFINED1].test == 1 && g_network_array[NET_USER_DEFINED2].test == 1) { if(g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED && g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED) { res = NETWORK_DETECTION_FAILED; goto out; } }else { if((g_network_array[NET_USER_DEFINED1].test == 1 && g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED) || (g_network_array[NET_USER_DEFINED2].test == 1 && g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED)) { res = NETWORK_DETECTION_FAILED; goto out; } } } res = NETWORK_DETECTION_OK; goto out; }else { if (DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS1].res && DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS2].res) { res = NETWORK_DETECTION_FAILED; goto out; } } res = NETWORK_DETECTION_OK; out: return diagnose_msg_send(res); } #endif S32 diagnose_result_save_config(void) { int res = 0; LINK_STATUS link_status = {0}; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA)); if(lte_config.internet_wired_enable == 0 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 0)) { INFO_INTERNET info_internet = {0}; ds_read(INFO_INTERNET_PATH, (U8*)&info_internet, sizeof(INFO_INTERNET)); if(INTERNET_4G_CONNECTED != info_internet.link_status) { res = NETWORK_PHY_DOWN; goto out; } if(DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS1].res && DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS2].res) { if(g_network_array[NET_USER_DEFINED1].test == 1 && g_network_array[NET_USER_DEFINED2].test == 1) { if(g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED && g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED) { res = NETWORK_DETECTION_FAILED; goto out; } }else if(g_network_array[NET_USER_DEFINED1].test == 0 && g_network_array[NET_USER_DEFINED2].test == 0) { res = NETWORK_DETECTION_FAILED; goto out; }else { if(g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED || g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED) { res = NETWORK_DETECTION_FAILED; goto out; } } } res = NETWORK_OK; }else #endif { if (LINK_DOWN == g_phy_stat.ether && LINK_DOWN == g_phy_stat.wlan) { res = NETWORK_PHY_DOWN; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_GATEWAY].res) { res = NETWORK_GATEWAY_FAILED; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_INTERNET1].res && DIAGNOSE_FAILED == g_network_array[NET_INTERNET2].res) { if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_FAILED; goto out; } res = NETWORK_OK; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_CLOUD_FAILED; goto out; } res = NETWORK_OK; } out: ds_read(LINK_STATUS_PATH, (U8 *)&link_status, sizeof(link_status)); if (link_status.internet_status != res) { DIAGNOSE_ERROR("internet status has changed: [%d] ===> [%d]", link_status.internet_status, res); link_status.internet_status = res; } ds_write(LINK_STATUS_PATH, (U8 *)&link_status, sizeof(link_status)); return OK; } /*********************************************************************************************** *函数:get_result *描述:web轮询诊断结果 *参数: type:本次诊断的参数,每一位代表一个诊断项 *返回值: ***********************************************************************************************/ LOCAL S32 get_result(JSON_OBJPTR jso_result, char* type, int cli_index) { JSON_OBJPTR data_obj = NULL; JSON_OBJPTR data_array = NULL; int index = 0; int finish = 0; char buffer[PARSE_BUFFER_LEN] = {'\0'}; char item_status[DIAGNOSE_BIT_LEN + 1] = {'\0'}; if (NULL == type || NULL == jso_result) { return SLP_EINVARG; } memset(item_status, '0', DIAGNOSE_BIT_LEN); if (NULL == (data_array = jso_new_array())) { DIAGNOSE_WARNING("Lookup failed, jso_new_array failed."); return SLP_ENOMEMORY; } /*无线信号*/ if (SET_TEST == type[DIAGNOSE_WIRELESS] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_connect_info.rssi); jso_add_string(data_obj, "link_type", g_connect_info.link_type); jso_add_string(data_obj, "rssi", buffer); jso_add_string(data_obj, "ssid", g_connect_info.ssid); jso_obj_add(jso_result, "wireless", data_obj); if (TESTED == g_connect_info.status) { item_status[DIAGNOSE_WIRELESS] = ITEM_FINISH; } else if (TESTING == g_connect_info.status) { item_status[DIAGNOSE_WIRELESS] = ITEM_TESTING; } } /*网络诊断*/ for (index = 0; index < ADDR_COUNTS; index++) { if (SET_TEST == type[g_network_array[index].params_code] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_network_array[index].res); jso_add_string(data_obj, "ip", g_network_array[index].str_ip); jso_add_string(data_obj, "domain", g_network_array[index].str_domain); jso_add_string(data_obj, "res", buffer); if (1 == g_network_array[index].do_telnet) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_network_array[index].tel_res); jso_add_string(data_obj, "telnet", buffer); } jso_obj_add(jso_result, g_network_array[index].para_name, data_obj); if (TESTED == g_network_array[index].status) { item_status[g_network_array[index].params_code] = ITEM_FINISH; } } } /*存储诊断*/ if(SET_TEST == type[DIAGNOSE_STORAGE] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_storage_info.upload_enable.enable); jso_add_string(data_obj, "cstg_enable", buffer); memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_storage_info.uploading.is_uploading); jso_add_string(data_obj, "cstg_uploading", buffer); jso_add_string(data_obj, "hd_status", g_storage_info.available); jso_add_string(data_obj, "total", g_storage_info.size.total); jso_add_string(data_obj, "free", g_storage_info.size.free); memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", 3); jso_add_string(data_obj, "record_type", buffer); jso_add_string(data_obj, "record_duration", g_storage_info.recorded_time); jso_add_string(data_obj, "hd_lifespan", g_storage_info.sd_lifespan); jso_obj_add(jso_result, "storage", data_obj); if (TESTED == g_storage_info.status) { item_status[DIAGNOSE_STORAGE] = ITEM_FINISH; } } /*固件诊断*/ if(SET_TEST == type[DIAGNOSE_FIRMWARE] && NULL != (data_obj = jso_new_obj())) { firmware_diagnose(&g_firmware_info); memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_firmware_info.fw_new_notify); jso_add_string(data_obj, "new_fw", buffer); jso_obj_add(jso_result, "firmware", data_obj); if (TESTED == g_firmware_info.status) { item_status[DIAGNOSE_FIRMWARE] = ITEM_FINISH; } } /*安全诊断*/ if(SET_TEST == type[DIAGNOSE_SAFETY] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_video_encryption.is_encryption); jso_add_string(data_obj, "is_encrypted", buffer); jso_obj_add(jso_result, "encrypted", data_obj); if (TESTED == g_video_encryption.status) { item_status[DIAGNOSE_SAFETY] = ITEM_FINISH; } } for (index = 0; index < DIAGNOSE_BIT_LEN; index++) { if (SET_TEST == type[index] && ITEM_FINISH != item_status[index]) { break; } } if (DIAGNOSE_BIT_LEN == index || AUTO_STOP == g_client_array[cli_index].is_stop) { finish = 1; goto exit; } g_client_array[cli_index].time_out++; if (g_client_array[cli_index].time_out > CLIENT_GET_TIMEOUT) { finish = 1; inet_del_timer(g_client_array[cli_index].timerid); memset(&g_client_array[cli_index], 0, sizeof(TASK_STRUCT)); } exit: jso_add_string(jso_result, "status", item_status); jso_add_string(jso_result, "finish", finish == 1 ? "1" : "0"); return SLP_ENONE; } void diagnose_timer_handle(S32 param) { DIAGNOSE_INFO("Ping test timeout!"); diagnose_stop(); } void init_global_var() { memset(&g_connect_info, 0, sizeof(g_connect_info)); memset(&g_storage_info, 0, sizeof(g_storage_info)); memset(&g_firmware_info, 0, sizeof(g_firmware_info)); memset(&g_video_encryption, 0, sizeof(g_video_encryption)); memset(g_network_array, 0, sizeof(NETWORK_STRUCT) * ADDR_COUNTS); memset(g_client_array, 0, sizeof(TASK_STRUCT) * MAX_CLIENTS_NUM); memset(&g_phy_stat, 0, sizeof(PHY_STATUS)); } /*********************************************************************************************** *函数: *描述:来自客户端的诊断,如web、App *参数: *返回值: ***********************************************************************************************/ LOCAL S32 client_diagnose() { if (0 == g_task_running) { memset(&g_connect_info, 0, sizeof(g_connect_info)); memset(&g_storage_info, 0, sizeof(g_storage_info)); memset(&g_firmware_info, 0, sizeof(g_firmware_info)); memset(&g_video_encryption, 0, sizeof(g_video_encryption)); request_fw_status(); check_signal_quality(&g_connect_info); g_connect_info.status = TESTED; storage_diagnose(&g_storage_info); g_storage_info.status = TESTED; firmware_diagnose(&g_firmware_info); g_firmware_info.status = TESTED; safety_diagnose(&g_video_encryption); g_video_encryption.status = TESTED; g_task_running = 1; } if (ERROR == g_diagnose_timerid) { network_diagnose(); } return OK; } void phy_status_change(void) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA)); #endif ds_read(PHY_STATUS_PATH, &g_phy_stat, sizeof(PHY_STATUS)); if (LINK_DOWN == g_phy_stat.ether && LINK_DOWN == g_phy_stat.wlan) { DIAGNOSE_DEBUG("catch phy link down"); #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(lte_config.internet_wired_enable == 1 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 1)) #endif { diagnose_stop(); } } } /*开启自诊断*/ S32 diagnose_operation_handle(dms_handler_t *handler, U8 *mbuf, U32 mlen, U32 sender_dms_id) { /*开启网络诊断*/ g_is_auto_diagnose = 1; if (ERROR == g_diagnose_timerid) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT NET_DIAGNOSE_MSG *msg = NULL; if(mbuf != NULL && mlen == sizeof(NET_DIAGNOSE_MSG)) { msg = (NET_DIAGNOSE_MSG*)mbuf; if(msg->model == MODEL_LTE) { g_is_lte_diagnose = 1; g_is_other_model_diagnose = 0; }else { g_is_other_model_diagnose = 1; } }else { g_is_other_model_diagnose = 1; } #endif network_diagnose(); } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT else if(ERROR != g_diagnose_timerid) { NET_DIAGNOSE_MSG *msg = NULL; if(mbuf != NULL && mlen == sizeof(NET_DIAGNOSE_MSG)) { msg = (NET_DIAGNOSE_MSG*)mbuf; if(msg->model == MODEL_LTE) { LTE_NETWORK_DIAGNOSE_RPL_MSG msg_sendto_lte = {0}; int res = TIMER_NOT_OVER; DIAGNOSE_ERROR("send lte model diagnose msg out id:%d", res); msg_sendto_lte.res = res; msg_send(LTE_NETWORK_DIAGNOSE_RPL_MID, (U8 *)&msg_sendto_lte, sizeof(msg)); } } } #endif return OK; } void client_array_reclaim_handle(S32 param) { if (param >= 0 && param < MAX_CLIENTS_NUM) { inet_del_timer(g_client_array[param].timerid); memset(&g_client_array[param], 0, sizeof(TASK_STRUCT)); } } S32 get_empty_client_ctx(int* client_index) { int index = 0; if (NULL == client_index) { return ERROR; } for (index = 0; index < MAX_CLIENTS_NUM; index++) { if (0 == strlen(g_client_array[index].instance_id)) { g_client_array[index].timerid = inet_add_timer(client_array_reclaim_handle, index, CLIENT_RECLAIM_INTERVAL, EXECUTE_SINGLE); if (ERROR == g_client_array[index].timerid) { return ERROR; } *client_index = index; return OK; } } return ERROR; } S32 get_client_instance_by_id(const char* instance_id, int* cli_index) { int index = 0; if (NULL == instance_id || NULL == cli_index) { return ERROR; } for (index = 0; index < MAX_CLIENTS_NUM; index++) { if (0 == strlen(g_client_array[index].instance_id)) { continue; } if (0 == strcmp(g_client_array[index].instance_id, instance_id)) { *cli_index = index; return OK; } } return ERROR; } S32 valid_param(const char* type) { int type_len = 0; int index = 0; if (NULL == type) { return SLP_EINVARG; } type_len = strlen(type); if (0 == type_len || type_len > DIAGNOSE_BIT_LEN) { return SLP_EINVARG; } for (index = 0; index < type_len; index++) { if (type[index] != '0' && type[index] != '1') { return IPC_DIAGNOSE_TYPE_NOT_SUPPORT; } if (index > DIAGNOSE_MAX && SET_TEST == type[index]) { return IPC_DIAGNOSE_TYPE_NOT_SUPPORT; } } return SLP_ENONE; } /*********************************************************************************************** *函数:start_oneclick_diagnose_callback *描述:快速诊断 *参数:读取诊断id,执行对应诊断内容 *返回值: ***********************************************************************************************/ S32 start_oneclick_diagnose_callback(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { const char* ptr = NULL; char instance_id[DIAGNOSE_ID_LEN + 1] = {'\0'}; U64 time_stamp = 0; int rand_num = 0; int error_code = SLP_ENONE; int client_index = 0; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; LTE_CONFIG_NET_DETECTION net_det = {0}; #endif if (!context || !context->res_obj || !context->req_obj) { error_code = SLP_ESYSTEM; goto out; } ptr = jso_obj_get_string_origin(param, "type"); if (NULL == ptr) { error_code = IPC_DIAGNOSE_PARAMS_INVALID; goto out; } error_code = valid_param(ptr); if (SLP_ENONE != error_code) { goto out; } if (ERROR == get_empty_client_ctx(&client_index)) { error_code = IPC_DIAGNOSE_TASK_BUSY; goto out; } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(0 == ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA))) { DIAGNOSE_ERROR("read config path %s fail.", LTE_INFO_DATA_PATH); error_code = IPC_DIAGNOSE_INTERNAL_ERROR; goto out; } if(0 == ds_read(LTE_NET_DET_PATH, (U8*)&net_det, sizeof(LTE_CONFIG_NET_DETECTION))) { DIAGNOSE_ERROR("read config path %s fail.", LTE_NET_DET_PATH); error_code = IPC_DIAGNOSE_INTERNAL_ERROR; goto out; } if((lte_config.internet_wired_enable == 0 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 0)) && net_det.ping_enable == 1) { goto out; }else #endif { if (ERROR == client_diagnose()) { goto out; } } /*返回诊断id*/ srand((U32)time(NULL)); time_stamp = nvmp_get_us(); rand_num = rand() % 10000; snprintf(instance_id, DIAGNOSE_ID_LEN, "%llu-%u", time_stamp, rand_num); g_client_array[client_index].time_out = 0; g_client_array[client_index].is_stop = 0; strncpy(g_client_array[client_index].instance_id, instance_id, DIAGNOSE_ID_LEN); jso_add_string(context->res_obj, "diagnose_id", instance_id); return SLP_ENONE; out: snprintf(instance_id, DIAGNOSE_ID_LEN, "%d", 0); jso_add_string(context->res_obj, "diagnose_id", instance_id); return error_code; } S32 diagnose_result_callback(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { const char* ptr = NULL; char str_type[DIAGNOSE_BIT_LEN + 1] = {'\0'}; /*诊断内容*/ char instance_id[DIAGNOSE_ID_LEN + 1] = {'\0'}; /*诊断实例id*/ int error_code = SLP_ENONE; int cli_index = 0; if (!context || !context->res_obj || !context->req_obj) { return SLP_ESYSTEM; } if (NULL == (ptr = jso_obj_get_string_origin(param, "diagnose_id"))) { return IPC_DIAGNOSE_PARAMS_INVALID; } strncpy(instance_id, ptr, DIAGNOSE_ID_LEN); if (ERROR == get_client_instance_by_id(instance_id, &cli_index)) { return IPC_DIAGNOSE_ID_NOT_FOUND; } if (NULL == (ptr = jso_obj_get_string_origin(param, "type"))) { return IPC_DIAGNOSE_PARAMS_INVALID; } error_code = valid_param(ptr); if (SLP_ENONE != error_code) { return error_code; } strncpy(str_type, ptr, DIAGNOSE_BIT_LEN); return get_result(context->res_obj, str_type, cli_index); } S32 stop_oneclick_diagnose_callback(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { char instance_id[DIAGNOSE_ID_LEN + 1] = {'\0'}; const char* ptr = NULL; int cli_index = 0; if (!context || !context->res_obj || !context->req_obj) { return SLP_ESYSTEM; } ptr = jso_obj_get_string_origin(param, "diagnose_id"); if (NULL == ptr) { return IPC_DIAGNOSE_PARAMS_INVALID; } strncpy(instance_id, ptr, DIAGNOSE_ID_LEN); if (ERROR == get_client_instance_by_id(instance_id, &cli_index)) { return IPC_DIAGNOSE_ID_NOT_FOUND; } g_client_array[cli_index].is_stop = AUTO_STOP; if (g_client_array[cli_index].timerid > 0) { inet_del_timer(g_client_array[cli_index].timerid); } memset(&g_client_array[cli_index], 0, sizeof(TASK_STRUCT)); DIAGNOSE_DEBUG("stop get result ......."); return SLP_ENONE; } 重点去关注,这函数是不是填充地址,第一位地址留给了网关,然后他怎么去获取的网关?我主要关注在有线部分, 234位的外网都正常,现在我要修改功能是,读取网关时,我的ip是在4G那边的,他会默认读到4G的网关,首先找到具体读网关的操作在哪里,然后,能否指定读eth0的网关?
10-23
while (((*p) - xml_start) < request_len) { if ((ch = soap_get_tag(xml_start, request_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (charbuf[0] == '/') { continue; } if (TRUE == soap_match_tag(charbuf, "Configuration")) { if (IS_WHITE_SPACE(ch)) { ch = soap_parse_element_attr_out_len(xml_start, request_len, p, 2, (char *)attr_name, name_str_len, (char *)attr_value_buf, value_str_len); if (strlen(attr_value_buf[1]) != 0) { json_obj = jso_from_string((const char *)attr_value_buf[1]); if (json_obj != NULL) { goto out; } } ONVIF_TRACE("token: %s", attr_value_buf[0]); if(0 != strcmp(attr_value_buf[0], "main") && 0 != strcmp(attr_value_buf[0], "minor")) { goto error_parse; } set_config_cmd.config = MALLOC_AND_REGISTER(TT_VIDEO_ENCODER_CONFIG, 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->token = MALLOC_AND_REGISTER(char, strlen(attr_value_buf[0]) + 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->token) { goto error_parse; } strncpy(set_config_cmd.config->token, attr_value_buf[0], strlen(attr_value_buf[0]) + 1); } continue; } if (TRUE == soap_match_tag(charbuf, "Name")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Name: %s", charbuf); set_config_cmd.config->name = MALLOC_AND_REGISTER(char, strlen(charbuf) + 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->name) { goto error_parse; } strncpy(set_config_cmd.config->name, charbuf,strlen(charbuf) + 1); continue; } if (TRUE == soap_match_tag(charbuf, "UseCount")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("UseCount: %s", charbuf); set_config_cmd.config->use_count = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Encoding")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Encoding: %s", charbuf); if (0 == strcmp(charbuf, TR2_VIDEO_ENCODING_MIME_NAME_H264)) { encode_type = "H264"; } else if (0 == strcmp(charbuf, TR2_VIDEO_ENCODING_MIME_NAME_H265)) { encode_type = "H265"; } else { ONVIF_ERROR("Invalid encode type: %s", charbuf); goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Resolution")) { if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->resolution = MALLOC_AND_REGISTER(TT_VIDEO_RESOLUTION, 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->resolution) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Width")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->resolution) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Width: %s", charbuf); set_config_cmd.config->resolution->width = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Height")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->resolution) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Height: %s", charbuf); set_config_cmd.config->resolution->height = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Quality")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Quality: %s", charbuf); set_config_cmd.config->quality = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "RateControl")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (IS_WHITE_SPACE(ch)) { char attr_in_name[20] = {"ConstantBitRate"}; char attr_out_buf[30] = {0}; int name_string_len = sizeof(attr_in_name); int value_string_len = sizeof(attr_out_buf); ch = soap_parse_element_attr_out_len(xml_start, request_len, p, 1, attr_in_name, name_string_len, attr_out_buf, value_string_len); if (EOF == ch) { ONVIF_ERROR("EOF == ch"); goto error_parse; } if (0 == strcmp(attr_out_buf, "true")) { bitrate_type = BITRATE_TYPE_CBR; } else if (0 == strcmp(attr_out_buf, "false")) { bitrate_type = BITRATE_TYPE_VBR; } } set_config_cmd.config->rate_control = MALLOC_AND_REGISTER(TT_VIDEO_RATE_CONTROL, 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->rate_control) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "FrameRateLimit")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("FrameRateLimit: %s", charbuf); set_config_cmd.config->rate_control->frame_rate_limit = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "BitrateLimit")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("BitrateLimit: %s", charbuf); set_config_cmd.config->rate_control->bitrate_limit = atoi(charbuf); continue; } } 以上代码解析以下报文时 <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SetVideoEncoderConfiguration xmlns="http://www.onvif.org/ver20/media/wsdl"> <Configuration token="main" GovLength="25"> <Name xmlns="http://www.onvif.org/ver10/schema">TestName1</Name> <UseCount xmlns="http://www.onvif.org/ver10/schema">0</UseCount> <Encoding xmlns="http://www.onvif.org/ver10/schema">H264</Encoding> <Resolution xmlns="http://www.onvif.org/ver10/schema"> <Width>3840</Width> <Height>2160</Height> </Resolution> <RateControl xmlns="http://www.onvif.org/ver10/schema"> <FrameRateLimit>15</FrameRateLimit> <BitrateLimit>1024</BitrateLimit> </RateControl> <Multicast xmlns="http://www.onvif.org/ver10/schema"> <Address> <Type>IPv4</Type> <IPv4Address>0.0.0.0</IPv4Address> </Address> <Port>0</Port> <TTL>0</TTL> <AutoStart>false</AutoStart> </Multicast> <Quality xmlns="http://www.onvif.org/ver10/schema">1</Quality> </Configuration> </SetVideoEncoderConfiguration> </s:Body>会有以下打印 [2025-10-31 15:30:24] [ERROR] tr2_set_video_encoder_config_xml_to_json():535 - [ONVIF]EOF == ch [2025-10-31 15:30:24] [ERROR] onvif_proc_data_srv():133 - [ONVIF]soap_serve_request failed. [2025-10-31 15:30:24] [ERROR] soap_get_namespace():460 - [ONVIF]Not a namespace: Type [ONVIF Test] Using third_account to auth [2025-10-31 15:30:24] [ERROR] tr2_set_video_encoder_config_xml_to_json():535 - [ONVIF]EOF == ch [2025-10-31 15:30:24] [ERROR] onvif_proc_data_srv():133 - [ONVIF]soap_serve_request failed. [2025-10-31 15:30:25] [ERROR] soap_get_namespace():460 - [ONVIF]Not a namespace: Type [ONVIF Test] Using third_account to auth [2025-10-31 15:30:25] [ERROR] tr2_set_video_encoder_config_xml_to_json():535 - [ONVIF]EOF == ch [2025-10-31 15:30:25] [ERROR] onvif_proc_data_srv():133 - [ONVIF]soap_serve_request failed. [2025-10-31 15:30:25] [ERROR] soap_get_namespace():460 - [ONVIF]Not a namespace: Type [ONVIF Test] Using third_account to auth [2025-10-31 15:30:25] [ERROR] tr2_set_video_encoder_config_xml_to_json():535 - [ONVIF]EOF == ch [2025-10-31 15:30:25] [ERROR] onvif_proc_data_srv():133 - [ONVIF]soap_serve_request failed. 分析一下
11-01
#include "data_changes.h" #include "ras_common.h" extern PIRSensor_p sensor; extern g4_module_ctx_t* g_ctx_air780; global_state_t g_state = { .ina219 = NULL, .dht11_pin = 21, .restart_gpio = 12, .current_lat = 0.0f, .current_lng = 0.0f, .has_valid_gps = 0, .last_th = -1000.0f, .last_rh = -1000.0f, .last_percent = -1000.0f, .last_reported_percent = -1000.0f, .last_lat_for_dist = 0.0f, .last_lng_for_dist = 0.0f, .last_csq_rssi = -1, .first_sample_done = 0, .keep_running = 1, .data_thread_running = 0, .data_thread = 0, .restart_thread = 0 }; // Thing_Model_t g_thing_Model; void stop_all_threads(void); // 同步 module info 的互斥锁 extern pthread_mutex_t g_module_info_mutex; // ==================== GPS 回调 ==================== void my_gps_data_handle(const gps_paresd_data_t* data) { if (!data || data->lat[0] == '\0' || data->lng[0] == '\0') return; //printf("纬度: %s, 经度: %s\n", data->lat, data->lng); float lat_raw = atof(data->lat); float lng_raw = atof(data->lng); if (lat_raw != 0.0f && lng_raw != 0.0f) { // 转换 DDMM.MMMM 格式到 DD.DDDDDD 十进制度数 float lat_deg = floorf(lat_raw / 100.0f); float lat_min = lat_raw - lat_deg * 100.0f; g_state.current_lat = lat_deg + lat_min / 60.0f; float lng_deg = floorf(lng_raw / 100.0f); float lng_min = lng_raw - lng_deg * 100.0f; g_state.current_lng = lng_deg + lng_min / 60.0f; g_state.has_valid_gps = 1; // 生成百度坐标字符串 zuobiao_dta(lng_raw, lat_raw, g_state.buf_lat_lng, sizeof(g_state.buf_lat_lng)); printf("转换后坐标: %s (WGS84: %.6f, %.6f)\n", g_state.buf_lat_lng, g_state.current_lng, g_state.current_lat); writeFilegps(g_state.buf_lat_lng, "zuobiao.txt"); } else { // printf("GPS 数据无效(0.0)\n"); // printf("经纬度:%s\n",g_state.buf_lat_lng); } } // ==================== 重新初始化硬件 ==================== int reinitialize_hardware(void) { printf("重新初始化硬件...\n"); // 重新初始化 INA219 if (g_state.ina219) { ina219_close(g_state.ina219); } g_state.ina219 = start_init_in291(); if (!g_state.ina219) { fprintf(stderr, "[ERROR] INA219 重新初始化失败\n"); return -1; } // 重新初始化 DHT11 if (!dht11_init(g_state.dht11_pin)) { fprintf(stderr, "[ERROR] DHT11 重新初始化失败\n"); return -1; } // 重新初始化 GPIO if (qckg_init(g_state.restart_gpio) != 0) { fprintf(stderr, "[ERROR] GPIO 重新初始化失败\n"); return -1; } // 重新初始化 4G 模块 g4_module_config_t config = { .serial_device = "/dev/ttyAMA0", .baud_rate = 9600, .timeout_seconds = 3, .max_retry = 3 }; if (start_air780_debug(config) == 0) { fprintf(stderr, "[ERROR] 4G 模块重新启动成功\n"); // 重置状态变量 g_state.last_th = -1000.0f; g_state.last_rh = -1000.0f; g_state.last_percent = -1000.0f; g_state.last_reported_percent = -1000.0f; g_state.last_csq_rssi = -1; //清空GPS全局变量 memset(g_state.buf_lat_lng, 0, sizeof(g_state.buf_lat_lng)); g_state.current_lat = 0.0f; g_state.current_lng = 0.0f; g_state.has_valid_gps = 0; printf("重新初始化GPS模块...\n"); set_gps_data_callback(my_gps_data_handle); sleep(1); // 等待旧线程退出 gps_data_init_with_device("/dev/ttyAMA1"); // 重置状态变量 g_state.first_sample_done = 0; printf("硬件重新初始化成功\n"); return 0; } return 0; } // ==================== 信号处理函数 ==================== void signal_handler(int sig) { printf("\n接收到信号 %d,准备退出...\n", sig); g_state.keep_running = 0; } // ==================== 数据采集线程 ==================== void* pthread_data_change(void* arg) { printf("数据采集线程启动\n"); // 等待完成,设置超时时间 int timeout = 300; // 超时 int wait_count = 0; while (g_ctx_air780->current_step != STEP_COMPLETE) { sleep(1); // 等待1秒 wait_count++; if (wait_count >= timeout) { printf("等待超时,当前步骤: %d\n", g_ctx_air780->current_step); break; } } //等待温湿度数据读取成功 int temp_humid_timeout = 360; // 温湿度读取超时时间(秒) int temp_humid_wait_count = 0; int temp_humid_valid = 0; printf("等待温湿度传感器数据...\n"); while (!temp_humid_valid && temp_humid_wait_count < temp_humid_timeout) { // 尝试读取温湿度数据 DHT11_Data_t d = dht11_read_data(g_state.dht11_pin); if (d.humidity_integer != 0 || d.temperature_integer != 0) { float current_rh = (float)d.humidity_integer + (float)d.humidity_decimal / 10.0f; float current_th = (float)d.temperature_integer + (float)d.temperature_decimal / 10.0f; if (current_th > -40.0f && current_th < 80.0f && current_rh >= 0.0f && current_rh <= 100.0f) { printf("成功读取温湿度: 温度%.1f℃, 湿度%.1f%%\n", current_th, current_rh); temp_humid_valid = 1; break; } } temp_humid_wait_count++; if (temp_humid_wait_count % 5 == 0) { printf("等待温湿度数据... (%d/%d 秒)\n", temp_humid_wait_count, temp_humid_timeout); } sleep(1); } if (!temp_humid_valid) { printf("警告: 温湿度读取异常,继续执行...\n"); } if (g_ctx_air780->current_step == STEP_COMPLETE) { // printf("步骤完成,继续执行...\n"); // if(get_ip_address(g_state.reportInfo_Device_Status.ipAddress,sizeof(g_state.reportInfo_Device_Status.ipAddress)) // &&get_rpi_serial(g_state.reportInfo_Device_Status.deviceSN, sizeof(g_state.reportInfo_Device_Status.deviceSN)) // &&get_device_model(g_state.reportInfo_Device_Status.deviceModel,sizeof(g_state.reportInfo_Device_Status.deviceModel)) // &&get_firmware_version(g_state.reportInfo_Device_Status.firmwareVersion, sizeof(g_state.reportInfo_Device_Status.firmwareVersion)) // &&get_hardware_nrevisio(g_state.reportInfo_Device_Status.hardwareVersion, sizeof(g_state.reportInfo_Device_Status.hardwareVersion))) // { // printf("设备信息获取成功\n"); // memcpy(g_state.reportInfo_Device_Status.sdCardStatus,"正常",sizeof(g_state.reportInfo_Device_Status.sdCardStatus)); // if(sensor != NULL) // { // g_state.reportInfo_Device_Status.motionDetectEnable = 1; // }else{ // g_state.reportInfo_Device_Status.motionDetectEnable = 0; // } // vp_reportinfo_Device_Status(&g_state.reportInfo_Device_Status); // } } else { printf("步骤未完成,当前状态: %d\n", g_ctx_air780->current_step); } while ((g_state.data_thread_running)&&(g_ctx_air780->current_step == STEP_COMPLETE)) { sleep(10); // 1. 网络路由 char out_route[32] = {0}; route_select(out_route, sizeof(out_route)); // 2. 电量 float bus_voltage = -1.0f; if (g_state.ina219) { bus_voltage = ina219_get_bus_voltage_V(g_state.ina219); } float current_percent = (bus_voltage - 6.0f) / 2.17f * 100.0f; current_percent = fmaxf(0.0f, fminf(100.0f, current_percent)); printf("当前电量%.1f\n",current_percent); // 3. 温湿度 DHT11_Data_t d = dht11_read_data(g_state.dht11_pin); float current_th = -1.0f, current_rh = -1.0f; if (d.humidity_integer != 0 || d.temperature_integer != 0) { current_rh = (float)d.humidity_integer + (float)d.humidity_decimal / 10.0f; current_th = (float)d.temperature_integer + (float)d.temperature_decimal / 10.0f; printf("温度%.1f, 湿度%.1f\n", current_th, current_rh); } // 4. 网络状态 + CSQ 解析 int current_csq_rssi = update_network_info(out_route); update_device_info(); // 5. 判断是否需要上报 int should_report_1 = 0; int should_report_2 = 0; int should_report_3 = 0; // 路由变化检测 if (strcmp(out_route, g_state.last_route_show) != 0) { should_report_3 = 1; printf("路由变化: %s -> %s,触发上报\n", g_state.last_route_show, out_route); memset(g_state.last_route_show, 0, sizeof(g_state.last_route_show)); size_t route_len = strlen(out_route); size_t copy_len = (route_len < sizeof(g_state.last_route_show)) ? route_len : (sizeof(g_state.last_route_show) - 1); memcpy(g_state.last_route_show, out_route, copy_len); } if (g_state.has_valid_gps && g_state.first_sample_done) { if (g_state.last_lat_for_dist == 0.0f && g_state.last_lng_for_dist == 0.0f) { g_state.last_lat_for_dist = g_state.current_lat; g_state.last_lng_for_dist = g_state.current_lng; printf("[DEBUG] 初始化参考坐标: lat=%.6f, lng=%.6f\n", g_state.last_lat_for_dist, g_state.last_lng_for_dist); } printf("[DEBUG] 距离计算: 上次(%.6f, %.6f) -> 当前(%.6f, %.6f)\n", g_state.last_lat_for_dist, g_state.last_lng_for_dist, g_state.current_lat, g_state.current_lng); float dist = haversine_distance_m( g_state.last_lat_for_dist, g_state.last_lng_for_dist, g_state.current_lat, g_state.current_lng ); printf("[DEBUG] 计算距离: %.2f 米\n", dist); if (dist > 40.0f) { should_report_1 = 1; printf("[DEBUG] 更新参考坐标: lat=%.6f, lng=%.6f\n", g_state.current_lat, g_state.current_lng); g_state.last_lat_for_dist = g_state.current_lat; g_state.last_lng_for_dist = g_state.current_lng; SAFE_MEMCPY(g_state.lng_lat, g_state.buf_lat_lng, sizeof(g_state.lng_lat)); printf("位置变化 %.1f 米,触发上报\n", dist); } } //温湿度变化检测 if (current_th >= 0 && g_state.last_th >= 0 && fabsf(current_th - g_state.last_th) > 2.0f) { should_report_2 = 1; printf("温度变化 %.1f℃,触发上报\n", fabsf(current_th - g_state.last_th)); } if (current_rh >= 0 && g_state.last_rh >= 0 && fabsf(current_rh - g_state.last_rh) > 3.0f) { should_report_2 = 1; printf("湿度变化 %.1f%%,触发上报\n", fabsf(current_rh - g_state.last_rh)); } // 电量累计变化检测 if (g_state.last_reported_percent >= 0) { float accumulated_change = fabsf(current_percent - g_state.last_reported_percent); if (accumulated_change >= 1.0f) { should_report_2 = 1; g_state.last_reported_percent = current_percent; printf("电量累计变化 %.1f%%,触发上报\n", accumulated_change); } } // 保存旧值 int old_csq = g_state.last_csq_rssi; // 更新 g_state.last_csq_rssi if (current_csq_rssi >= 0) { g_state.last_csq_rssi = current_csq_rssi; } // 判断是否需要上报 if (current_csq_rssi >= 0) { if (old_csq == -1) { // 首次有效值,触发上报 should_report_3 = 1; printf("首次获取有效 CSQ: %d,触发上报\n", current_csq_rssi); } else if (abs(current_csq_rssi - old_csq) > 6) { should_report_3 = 1; printf("CSQ 变化 %d -> %d,触发上报\n", old_csq, current_csq_rssi); } } // 首次采集 if (!g_state.first_sample_done) { printf("首次采集上报\n"); should_report_2 = 1; should_report_1 = 1; should_report_3 = 1; g_state.first_sample_done = 1; g_state.last_reported_percent = current_percent; if (g_state.has_valid_gps) { should_report_1 = 1; g_state.last_lat_for_dist = g_state.current_lat; g_state.last_lng_for_dist = g_state.current_lng; SAFE_MEMCPY(g_state.lng_lat, g_state.buf_lat_lng, sizeof(g_state.lng_lat)); } if (current_csq_rssi >= 0) { g_state.last_csq_rssi = current_csq_rssi; } memset(g_state.last_route_show, 0, sizeof(g_state.last_route_show)); size_t route_len = strlen(out_route); size_t copy_len = (route_len < sizeof(g_state.last_route_show)) ? route_len : (sizeof(g_state.last_route_show) - 1); memcpy(g_state.last_route_show, out_route, copy_len); printf("首次采集,上报\n"); } else { if (current_csq_rssi >= 0) { g_state.last_csq_rssi = current_csq_rssi; } } // 更新其他"上次值" g_state.last_percent = current_percent; if(current_th >= 0) { // 更新结构体 g_state.reportInfo_Location_Power_TemperatureHumidity.th = (current_th < 0) ? -1.0f : roundf(current_th * 100.0f) / 100.0f; g_state.reportInfo_Location_Power_TemperatureHumidity.rh = current_rh; } snprintf(g_state.reportInfo_Location_Power_TemperatureHumidity.percent, sizeof(g_state.reportInfo_Location_Power_TemperatureHumidity.percent), "%.1f", current_percent); // 6. 执行上报 vp_reportInfo_Information(&g_state.reportInfo_Information); usleep(1000000); if (should_report_2&&g_state.reportInfo_Location_Power_TemperatureHumidity.th >= 0&&g_state.reportInfo_Location_Power_TemperatureHumidity.rh >= 0) { vp_reportInfo_Power_TemperatureHumidity(&g_state.reportInfo_Location_Power_TemperatureHumidity); // 上报后更新温湿度电量的上报基准值 if (current_th >= 0) g_state.last_th = current_th; if (current_rh >= 0) g_state.last_rh = current_rh; g_state.last_reported_percent = current_percent; usleep(1000000); } if (should_report_3) { vp_reportInfo_Network_Status(&g_state.reportInfo_Network_Status); usleep(1000000); } if(should_report_1){ vp_reportInfo_Location(g_state.lng_lat); usleep(1000000); } } cleanup_resources(); printf("数据采集线程退出\n"); return NULL; } // ==================== 重启检测线程 ==================== void* pthread_data_restart(void* arg) { int gpio_pin = (int)(intptr_t)arg; time_t start_time = 0; int high_detected = 0; time_t last_restart_time = 0; // 上次重启时间 const int RESTART_COOLDOWN = 10; // 重启冷却时间(秒) printf("重启检测线程启动,监控GPIO%d\n", gpio_pin); while (g_state.keep_running) { int state = qckg_read(gpio_pin); if (state == 1) { if (!high_detected) { start_time = time(NULL); high_detected = 1; printf("检测到高电平,开始计时...\n"); } else { if (difftime(time(NULL), start_time) >= 3.0) { time_t current_time = time(NULL); // 检查冷却时间 if (difftime(current_time, last_restart_time) < RESTART_COOLDOWN) { printf("重启操作过于频繁(冷却时间剩余: %.0f秒)\n", RESTART_COOLDOWN - difftime(current_time, last_restart_time)); high_detected = 0; start_time = 0; continue; } printf("高电平持续3秒,触发硬件重新初始化\n"); last_restart_time = current_time; // 清理资源 stop_all_threads(); printf("等待硬件稳定...\n"); sleep(2); if (reinitialize_hardware() == 0) { memset(&g_state.reportInfo_Information, 0, sizeof(g_state.reportInfo_Information)); memset(&g_state.reportInfo_Network_Status, 0, sizeof(g_state.reportInfo_Network_Status)); memset(&g_state.reportInfo_Location_Power_TemperatureHumidity, 0, sizeof(g_state.reportInfo_Location_Power_TemperatureHumidity)); memset(&g_state.reportInfo_Device_Status, 0, sizeof(g_state.reportInfo_Device_Status)); printf("硬件重新初始化成功\n"); // 重新启动数据采集线程 g_state.data_thread_running = 1; if (pthread_create(&g_state.data_thread, NULL, pthread_data_change, NULL) != 0) { fprintf(stderr, "重新创建数据采集线程失败\n"); g_state.data_thread_running = 0; } else { printf("数据采集线程重新启动成功\n"); } } else { fprintf(stderr, "硬件重新初始化失败\n"); } // 重置检测状态 high_detected = 0; start_time = 0; } } } else { if (high_detected) { printf("高电平中断,重置计时\n"); high_detected = 0; start_time = 0; } } usleep(100000); // 100ms } printf("重启检测线程退出\n"); return NULL; } // ==================== 外部接口 ==================== int data_change() { if (g_state.data_thread != 0) { printf("数据采集线程已在运行\n"); return 0; } // 初始化硬件 // wiring_init(); // g_state.dht11_pin = 21; // g_state.restart_gpio = 17; // 初始化硬件 if (reinitialize_hardware() == 0) { g_state.data_thread_running=1; int ret = pthread_create(&g_state.data_thread, NULL, pthread_data_change, NULL); if (ret != 0) { fprintf(stderr, "创建数据采集线程失败: %d\n", ret); g_state.data_thread_running = 0; return -1; } }else { printf("初始化硬件失败\n"); } printf("数据采集启动成功\n"); return 0; } int restart() { if (g_state.restart_thread != 0) { printf("重启检测线程已在运行\n"); return 0; } // const int gpio_pin = 17; int ret = pthread_create(&g_state.restart_thread, NULL, pthread_data_restart, (void*)(intptr_t)g_state.restart_gpio); if (ret != 0) { fprintf(stderr, "创建重启检测线程失败: %d\n", ret); return -1; } printf("重启检测启动成功\n"); return 0; } // 停止所有线程 void stop_all_threads(void) { printf("停止所有线程...\n"); g_state.data_thread_running = 0; if (g_state.data_thread) { pthread_join(g_state.data_thread, NULL); g_state.data_thread = 0; } cleanup_resources(); printf("所有线程已停止\n"); } 这个是相关代码
最新发布
11-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值