You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1215 lines
40 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*****************************************************************************
* file lib/process/pd_dbg.c
* author YuLiang
* version 1.0.0
* date 01-June-2023
* brief This file provides all the debug server related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <netinet/tcp.h>
/* 用户代码头文件. */
#include "cJSON.h"
#include "process.h"
#include "mtimer.h"
#include "pd_dbg.h"
#include "pd_csg.h"
#include "pd_dau.h"
/* Private define ------------------------------------------------------------*/
#define DEBUG_HEAD 0x55AA
#define DEBUG_TAIL 0x5AA5
#define DEBUG_CMD_LEN 10 * 1024 * 1024
#define DEBUG_CMU_FILE "PDMonitor"
#define DEBUG_CMU_FILE_BAK "PDMonitor.bak"
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
debug_ctrl_t debug_ctrl;
static char cjson_buf[DEBUG_BUG_SIZE];
static char buf_cmd[DEBUG_CMD_LEN];
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
void _debug_pkt_head_int(debug_pkt_head_t *head, uint16_t cmd, uint32_t len)
{
head->head = DEBUG_HEAD;
head->cmd = cmd;
head->len = len;
}
void _debug_save_fatcory_param(cJSON *root)
{
cJSON *param = NULL;
struct in_addr addr = {0};
dau_t *dau_node = NULL;
uint16_t len = 0;
uint16_t field = 0;
uint8_t i = 0;
uint8_t j = 0;
uint8_t cnt = 0;
param = cJSON_AddObjectToObject(root, "EquipmentFactoryParam");
if (NULL == param)
{
DBG(DBG_M_DEBUG, "Add json object error!\r\n");
return;
}
cJSON_AddStringToObject(param, "DeviceNum", host.name);
snprintf(cjson_buf, DEBUG_CJSON_BUG_SIZE, "%s", device_info.dev_type);
cJSON_AddStringToObject(param, "EquipmentType", cjson_buf);
cJSON_AddNumberToObject(param, "DateOfProduction", device_info.factory_date);
cJSON_AddNumberToObject(param, "DeploymentDate", device_info.deployment_date);
cJSON_AddStringToObject(param, "LocalIP1", device_info.host_ip);
cJSON_AddStringToObject(param, "LocalIP1_V6", "");
cJSON_AddStringToObject(param, "LocalMacAddress1", "");
cJSON_AddStringToObject(param, "LocalIP2", "");
cJSON_AddStringToObject(param, "LocalIP2_V6", "");
cJSON_AddStringToObject(param, "LocalMacAddress2", "");
addr.s_addr = csg.server_ip;
cJSON_AddStringToObject(param, "ServerIP1", inet_ntoa(addr));
cJSON_AddStringToObject(param, "ServerIP1_V6", "");
cJSON_AddStringToObject(param, "ServerIP2", "");
cJSON_AddStringToObject(param, "ServerIP2_V6","");
cJSON_AddNumberToObject(param,"ServerIP1_Port", csg.server_port);
cJSON_AddNumberToObject(param,"ServerIP2_Port", 0);
for(i = 0; i < PD_DAU_SUM; i++)
{
dau_node = dau[i];
if (!dau_node)
{
continue;
}
for(j = 0; j < dau_node->port_num; j++)
{
field = (dau_node->port_reg[j].CR & DAU_CR_PT_Msk) >> DAU_CR_PT_Pos;
len += snprintf(cjson_buf + len, DEBUG_CJSON_BUG_SIZE - len, "%02x", field);
cnt++;
}
}
for(i = cnt; i < PD_PORT_SUM; i++)
{
len += snprintf(cjson_buf + len, DEBUG_CJSON_BUG_SIZE - len, "00");
}
cJSON_AddStringToObject(param, "ChannelType", cjson_buf);
return;
}
void _debug_save_user_param(cJSON *root)
{
cJSON *param = NULL;
param = cJSON_AddObjectToObject(root, "EquipmentUserParam");
if (NULL == param)
{
DBG(DBG_M_DEBUG, "Add json object error!\r\n");
return;
}
cJSON_AddNumberToObject(param, "SystemFrequency", pd_config.config.power_frequency);
cJSON_AddNumberToObject(param, "SyncMode", pd_config.config.sync_mode);
cJSON_AddNumberToObject(param, "TimingSyncMode", pd_config.config.TimingSyncMode);
cJSON_AddNumberToObject(param, "DataAcquisitionCycle", pd_config.config.real_period);
cJSON_AddNumberToObject(param, "TrendDataReportCycle", pd_config.config.trend_period);
cJSON_AddNumberToObject(param, "HeartbeatCycle", pd_config.config.heartbeat_period);
cJSON_AddNumberToObject(param, "NumberWindowsOfPhase", pd_config.config.NumberWindowsOfPhase);
cJSON_AddNumberToObject(param, "SyncTime", pd_config.config.SyncTime);
cJSON_AddNumberToObject(param, "AlarmPeriod", pd_config.config.AlarmPeriod);
cJSON_AddNumberToObject(param, "TimePrpsStrategy", pd_config.config.TimePrpsStrategy);
cJSON_AddNumberToObject(param, "StorageTrent", pd_config.config.storage_trend);
cJSON_AddNumberToObject(param, "StorageAlarm", pd_config.config.StorageAlarm);
cJSON_AddNumberToObject(param, "StorageRun", pd_config.config.StorageRun);
cJSON_AddNumberToObject(param, "StorageFtPRPS", pd_config.config.storage_real);
cJSON_AddNumberToObject(param, "LimitEventStorageTime", pd_config.config.limit_event_time);
cJSON_AddNumberToObject(param, "LimitEventStorageCount", pd_config.config.limit_event_cnt);
cJSON_AddNumberToObject(param, "LimitEventStorageSpace", pd_config.config.limit_event_interval);
cJSON_AddNumberToObject(param, "prpsSaveEnable", pd_config.config.is_prps_save);
return;
}
void _debug_save_port_param(cJSON *root)
{
cJSON *port_array = NULL;
cJSON *param = NULL;
pd_port_config_old_t *config = NULL;
uint8_t unit = 0;
uint8_t port = 0;
uint8_t i = 0;
port_array = cJSON_AddArrayToObject(root, "SensorConfigParam");
if (NULL == port_array)
{
DBG(DBG_M_DEBUG, "Add json array error!\r\n");
return;
}
for(i = 1; i <= PD_PORT_SUM; i++)
{
if (dau_vport_to_port(i, &unit, &port) != E_NONE)
{
break;
}
config = &pd_config.port_config[unit][port].config;
param = cJSON_CreateObject();
if (!param)
{
DBG(DBG_M_DEBUG, "Create json error!\r\n");
return;
}
cJSON_AddNumberToObject(param,"ChannelNumber", config->vport);
cJSON_AddNumberToObject(param,"FilterType", config->filter);
cJSON_AddNumberToObject(param,"SensorType", config->sensor_type);
cJSON_AddNumberToObject(param,"PhaseSequence", config->phase_sequence);
cJSON_AddNumberToObject(param,"NearSensor1_Number", config->NearSensor1_Number);
cJSON_AddNumberToObject(param,"NearSensor1_Distance", config->NearSensor1_Distance);
cJSON_AddNumberToObject(param,"Signal1_AttenuationRatio", config->Signal1_AttenuationRatio);
cJSON_AddNumberToObject(param,"NearSensor2_Number", config->NearSensor2_Number);
cJSON_AddNumberToObject(param,"NearSensor2_Distance", config->NearSensor2_Distance);
cJSON_AddNumberToObject(param,"Signal2_AttenuationRatio", config->Signal2_AttenuationRatio);
cJSON_AddNumberToObject(param,"NearSensor3_Number", config->NearSensor3_Number);
cJSON_AddNumberToObject(param,"NearSensor3_Distance", config->NearSensor3_Distance);
cJSON_AddNumberToObject(param,"Signal3_AttenuationRatio", config->Signal3_AttenuationRatio);
cJSON_AddNumberToObject(param,"NearSensor4_Number", config->NearSensor4_Number);
cJSON_AddNumberToObject(param,"NearSensor4_Distance", config->NearSensor4_Distance);
cJSON_AddNumberToObject(param,"Signal4_AttenuationRatio", config->Signal4_AttenuationRatio);
cJSON_AddNumberToObject(param,"EventTriggerThreshold", config->event_threshold);
cJSON_AddNumberToObject(param,"EventTriggerCounter", config->event_counter);
cJSON_AddNumberToObject(param,"EnvironmentalNoiseThreshold", config->env_noise);
cJSON_AddNumberToObject(param,"NoiseReductionLevel", config->noise_reduction);
cJSON_AddNumberToObject(param,"UpperLimitOfDischargeAmplitude", config->UpperLimitOfDischargeAmplitude);
cJSON_AddNumberToObject(param,"WaveTriggerThreshold", config->WaveTriggerThreshold);
cJSON_AddNumberToObject(param,"PrescalerSampleValue", config->PrescalerSampleValue);
cJSON_AddNumberToObject(param,"SamplePointsTotalTriggered", config->SamplePointsTotalTriggered);
cJSON_AddNumberToObject(param,"RecordStartAdr", config->RecordStartAdr);
cJSON_AddNumberToObject(param,"RecordStopAdr", config->RecordStopAdr);
cJSON_AddNumberToObject(param,"SampleRate", config->sample_rate);
cJSON_AddNumberToObject(param,"BeforeTriggerTime", config->BeforeTriggerTime);
cJSON_AddNumberToObject(param,"AfterTriggerTime", config->AfterTriggerTime);
cJSON_AddNumberToObject(param,"StorageEvent", config->storage_event);
cJSON_AddNumberToObject(param,"StorageAEWave", config->storage_wave);
cJSON_AddItemToArray(port_array, param);
}
return;
}
cJSON* _debug_save_cfg_to_json(void)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
if (!root)
{
DBG(DBG_M_DEBUG, "Create json error!\r\n");
return NULL;
}
_debug_save_fatcory_param(root);
_debug_save_user_param(root);
_debug_save_port_param(root);
return root;
}
/* 调试工具修改本地ip 设备ID 服务器地址时需要重启。*/
void _debug_parse_fatcory_param(cJSON *root, unsigned int *changbitmap, BOOT_MSG *boottype)
{
struct sockaddr_in addr = {0};
cJSON *param = cJSON_GetObjectItem(root, "EquipmentFactoryParam");
char *str = NULL;
uint8_t unit = 0;
uint8_t port = 0;
uint8_t i = 0;
uint8_t type = 0;
if (!param)
{
return;
}
str = cJSON_GetStringValue(cJSON_GetObjectItem(param, "EquipmentType"));
if (str)
{
if (strncmp(str, device_info.dev_type, sizeof(device_info.dev_type)) != 0)
{
snprintf(device_info.dev_type, FILE_NAME_LEN, "%s", str);
*changbitmap |= BITMAP_SAVE_FILE;
}
}
str = cJSON_GetStringValue(cJSON_GetObjectItem(param, "DeviceNum"));
if (str)
{
if (strncmp(str, host.name, sizeof(host.name)) != 0)
{
snprintf(host.name, FILE_NAME_LEN, "%s", str);
*changbitmap |= BITMAP_SAVE_FILE;
*boottype = BOOT_LOCAL_HOST_NAME_CHANGE;
}
}
device_info.factory_date = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "DateOfProduction"));
device_info.deployment_date = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "DeploymentDate"));
str = cJSON_GetStringValue(cJSON_GetObjectItem(param, "LocalIP1"));
if (str)
{
if (strncmp(str, device_info.host_ip, sizeof(device_info.host_ip)) != 0)
{
snprintf(device_info.host_ip, INET_ADDRSTRLEN, "%s", str);
*changbitmap |= BITMAP_SAVE_FILE;
*changbitmap |= BITMAP_IP_CHANGE;
*boottype = BOOT_LOCAL_IP_CHANGE;
}
}
str = cJSON_GetStringValue(cJSON_GetObjectItem(param, "ServerIP1"));
if (str)
{
inet_aton(str, &addr.sin_addr);
if (addr.sin_addr.s_addr != csg.server_ip)
{
csg.server_ip = addr.sin_addr.s_addr;
*changbitmap |= BITMAP_SAVE_FILE;
*boottype = BOOT_LOCAL_SERVER_IP_CHANGE;
}
}
int port_tmp = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "ServerIP1_Port"));
if (port_tmp > 0 && port_tmp != csg.server_port)
{
csg.server_port = port_tmp;
*changbitmap |= BITMAP_SAVE_FILE;
*boottype = BOOT_LOCAL_SERVER_PORT_CHANGE;
}
str = cJSON_GetStringValue(cJSON_GetObjectItem(param, "ChannelType"));
if (str)
{
for(i = 0; i < PD_PORT_SUM; i++)
{
if ('\0' == *str)
{
break;
}
type = (*str - '0') << 4;
str++;
type += *str - '0';
str++;
if (dau_vport_to_port(i + 1, &unit, &port) != E_NONE)
{
break;
}
dau_port_type_set(unit, port, type);
dau_reg_port_write(unit, port);
*changbitmap |= BITMAP_SAVE_FILE; // save file
}
}
return;
}
void _debug_parse_user_param(cJSON *root, unsigned int *changbitmap)
{
unsigned int temp;
cJSON *param = cJSON_GetObjectItem(root,"EquipmentUserParam");
if (!param)
{
return;
}
pd_config.config.power_frequency = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "SystemFrequency"));
temp = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "SyncMode"));
if (pd_config.config.sync_mode != temp)
{
pd_config.config.sync_mode = (uint8_t)temp;
*changbitmap |= BITMAP_SAVE_FILE;
pd_sync_mode_set();
}
pd_config.config.TimingSyncMode = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "TimingSyncMode"));
temp = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "DataAcquisitionCycle"));
if (pd_config.config.real_period != temp)
{
pd_config.config.real_period = (uint8_t)temp;
*changbitmap |= BITMAP_SAVE_FILE;
}
temp = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "TrendDataReportCycle"));
if (pd_config.config.trend_period != temp)
{
pd_config.config.trend_period = (uint8_t)temp;
*changbitmap |= BITMAP_SAVE_FILE;
}
temp = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "HeartbeatCycle"));
if (pd_config.config.heartbeat_period != temp)
{
pd_config.config.heartbeat_period = (uint8_t)temp;
*changbitmap |= BITMAP_SAVE_FILE;
}
pd_config.config.NumberWindowsOfPhase = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NumberWindowsOfPhase"));
pd_config.config.SyncTime = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "SyncTime"));
pd_config.config.AlarmPeriod = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "AlarmPeriod"));
pd_config.config.TimePrpsStrategy = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "TimePrpsStrategy"));
pd_config.config.storage_trend = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "StorageTrent"));
pd_config.config.StorageAlarm = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "StorageAlarm"));
pd_config.config.StorageRun = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "StorageRun"));
pd_config.config.storage_real = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "StorageFtPRPS"));
pd_config.config.limit_event_time = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "LimitEventStorageTime"));
pd_config.config.limit_event_cnt = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "LimitEventStorageCount"));
pd_config.config.limit_event_interval = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "LimitEventStorageSpace"));
pd_config.config.is_prps_save = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "prpsSaveEnable"));
return;
}
void _debug_parse_port_param(cJSON *root)
{
pd_port_config_old_t *config = NULL;
cJSON *port_array = NULL;
cJSON *param = NULL;
int size = 0;
uint8_t vport = 0;
uint8_t unit = 0;
uint8_t port = 0;
uint8_t i = 0;
port_array = cJSON_GetObjectItem(root, "SensorConfigParam");
if (!port_array)
{
return;
}
size = cJSON_GetArraySize(port_array);
for (i = 0; i < size; i++)
{
param = cJSON_GetArrayItem(port_array, i);
if (!param )
{
continue;
}
vport = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "ChannelNumber"));
if (dau_vport_to_port(vport, &unit, &port) != E_NONE)
{
continue;
}
config = &pd_config.port_config[unit][port].config;
config->filter = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "FilterType"));
config->sensor_type = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "SensorType"));
config->phase_sequence = (uint8_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "PhaseSequence"));
config->NearSensor1_Number = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor1_Number"));
config->NearSensor1_Distance = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor1_Distance"));
config->Signal1_AttenuationRatio = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "Signal1_AttenuationRatio"));
config->NearSensor2_Number = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor2_Number"));
config->NearSensor2_Distance = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor2_Distance"));
config->Signal2_AttenuationRatio = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "Signal2_AttenuationRatio"));
config->NearSensor3_Number = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor3_Number"));
config->NearSensor3_Distance = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor3_Distance"));
config->Signal3_AttenuationRatio = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "Signal3_AttenuationRatio"));
config->NearSensor4_Number = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor4_Number"));
config->NearSensor4_Distance = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NearSensor4_Distance"));
config->Signal4_AttenuationRatio = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "Signal4_AttenuationRatio"));
config->event_threshold = (int16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "EventTriggerThreshold"));
config->event_counter = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "EventTriggerCounter"));
config->env_noise = (int16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "EnvironmentalNoiseThreshold"));
config->noise_reduction = (int16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "NoiseReductionLevel"));
config->UpperLimitOfDischargeAmplitude = (int16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "UpperLimitOfDischargeAmplitude"));
config->WaveTriggerThreshold = (int16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "WaveTriggerThreshold"));
config->PrescalerSampleValue = (uint16_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "PrescalerSampleValue"));
config->SamplePointsTotalTriggered = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "SamplePointsTotalTriggered"));
config->RecordStartAdr = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "RecordStartAdr"));
config->RecordStopAdr = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "RecordStopAdr"));
config->sample_rate = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "SampleRate"));
config->BeforeTriggerTime = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "BeforeTriggerTime"));
config->AfterTriggerTime = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "AfterTriggerTime"));
config->storage_event = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "StorageEvent"));
config->storage_wave = (uint32_t)cJSON_GetNumberValue(cJSON_GetObjectItem(param, "StorageAEWave"));
pd_config.port_config[unit][port].filter_cfg = pd_config.port_config[unit][port].config.filter;
dau_port_config_set(unit, port);
dau_reg_port_write(unit, port);
}
return;
}
int32_t _debug_parse_json_to_cfg(cJSON *root)
{
unsigned int changbitmap = 0; //bit0:need save
//bit1:local ip changed
BOOT_MSG boottype = BOOT_NONE;
_debug_parse_fatcory_param(root, &changbitmap, &boottype);
_debug_parse_user_param(root, &changbitmap);
_debug_parse_port_param(root);
if (BITMAP_SAVE_FILE == (changbitmap & BITMAP_SAVE_FILE))
{
vtysh_config_save();
if (BITMAP_IP_CHANGE == (changbitmap & BITMAP_IP_CHANGE))
{
uint8_t mac[MAC_ADDR_LEN] = {0};
mac_generate_from_ip(device_info.host_ip, mac);
memcpy(device_info.mac, mac, MAC_ADDR_LEN);
vtysh_device_save();
vtysh_eth0_save();
}
}
if (boottype)
{
reboot_system(DBG_M_DEBUG, boottype);
}
return E_NONE;
}
/* 回复报文处理. */
int32_t _debug_pkt_common_send(char *buf, uint16_t cmd, uint32_t data_len)
{
debug_pkt_head_t *head = (debug_pkt_head_t*)buf;
uint16_t *tail = (uint16_t*)(buf + sizeof(debug_pkt_head_t) + data_len);
_debug_pkt_head_int(head, cmd, data_len);
*tail = DEBUG_TAIL;
if (write(debug_ctrl.fd_client, buf, sizeof(debug_pkt_head_t) + data_len + 2) <= 0)
{
DBG(DBG_M_DEBUG, "Write cmd %x ERROR\r\n", head->cmd);
return E_SYS_CALL;
}
return E_NONE;
}
/* 获取配置报文处理. */
int32_t _debug_pkt_cfg_get(char *buf, int len)
{
cJSON *root = NULL;
char *cfg = NULL;
char *cfg_json = NULL;
uint16_t len_pkt = 0;
/* 获取 json 格式的配置文件. */
root = _debug_save_cfg_to_json();
if (!root)
{
return E_NOT_FOUND;
}
/* 将 json 转为字符串. */
cfg_json = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
len_pkt = strlen(cfg_json);
/* 复制数据. */
cfg = buf + sizeof(debug_pkt_head_t);
memcpy(cfg, cfg_json, len_pkt);
free(cfg_json);
/* 发送数据. */
return _debug_pkt_common_send(buf, DEBUG_CONFIG_GET, len_pkt);
}
/* 设置报文处理. */
int32_t _debug_pkt_cfg_set(char *buf, int len)
{
char *cfg = buf + sizeof(debug_pkt_head_t);
cJSON *root = cJSON_Parse(cfg);
if (!root)
{
DBG(DBG_M_DEBUG, "Parse json error!\r\n");
return E_SYS_CALL;
}
/* 将 json 配置转换成设备配置. */
if (_debug_parse_json_to_cfg(root) != E_NONE)
{
cJSON_Delete(root);
return E_BAD_PARAM;
}
cJSON_Delete(root);
/* 发送数据. */
return _debug_pkt_common_send(buf, DEBUG_CONFIG_SET, 0);
}
/* 重启报文处理. */
int32_t _debug_pkt_reboot(char *buf, int len)
{
/* 发送数据. */
_debug_pkt_common_send(buf, DEBUG_REBOOT, 0);
/* 重启. */
reboot_system(DBG_M_DEBUG, BOOT_LOCAL_RESET);
return E_NONE;
}
/* 时间设置报文处理. */
int32_t _debug_pkt_time_set(char *buf, int len)
{
uint32_t *timestamp = (uint32_t*)(buf + sizeof(debug_pkt_head_t));
/* 配置时间. */
time_set(*timestamp);
/* 发送数据. */
_debug_pkt_common_send(buf, DEBUG_TIME_SET, 0);
return E_NONE;
}
/* 数据手动设置报文处理. */
int32_t _debug_pkt_manual_col(char *buf, int len)
{
uint32_t *flag = (uint32_t*)(buf + sizeof(debug_pkt_head_t));
/* 修改标志位. */
debug_ctrl.is_manual_col = (*flag) ? TRUE : FALSE;
/* 发送数据. */
return _debug_pkt_common_send(buf, DEBUG_NOISE_CAREFOR, 0);
}
/* 获取校准系数报文处理. */
int32_t _debug_pkt_adj_get(char *buf, int len)
{
dau_port_reg_t *reg = NULL;
debug_pkt_adj_t *data = (debug_pkt_adj_t *)(buf + sizeof(debug_pkt_head_t));
uint8_t unit = 0;
uint8_t port = 0;
uint8_t i = 0;
uint8_t j = 0;
memset(data, 0, sizeof(debug_pkt_adj_t));
for(i = 0; i < PD_PORT_SUM; i++)
{
if (dau_vport_to_port(i + 1, &unit, &port) != E_NONE)
{
break;
}
reg = &dau[unit]->port_reg[port];
for(j = 0; j < 4; j++)
{
data->vport[i].point[j] = reg->ASPR[j];
}
for(j = 0; j < 5; j++)
{
data->vport[i].param_a[j] = reg->AFAR[j];
}
for(j = 0; j < 5; j++)
{
data->vport[i].param_b[j] = reg->AFBR[j];
}
}
/* 发送数据. */
return _debug_pkt_common_send(buf, DEBUG_ADJSUT_COEFFICIENT_GET, sizeof(debug_pkt_adj_t));
}
/* 获取校准系数报文处理. */
int32_t _debug_pkt_adj_set(char *buf, int len)
{
dau_port_reg_t *reg = NULL;
debug_pkt_adj_t *data = (debug_pkt_adj_t*)(buf + sizeof(debug_pkt_head_t));
int8_t *ret = (int8_t*)(buf + sizeof(debug_pkt_head_t));
uint8_t unit = 0;
uint8_t port = 0;
uint8_t i = 0;
uint8_t j = 0;
for(i = 0; i < PD_PORT_SUM; i++)
{
if (dau_vport_to_port(i + 1, &unit, &port) != E_NONE)
{
break;
}
reg = &dau[unit]->port_reg[port];
for(j = 0; j < 4; j++)
{
reg->ASPR[j] = data->vport[i].point[j];
}
reg->ASPR[j] = 65535;
for(j = 0; j < 5; j++)
{
reg->AFAR[j] = data->vport[i].param_a[j];
}
for(j = 0; j < 5; j++)
{
reg->AFBR[j] = data->vport[i].param_b[j];
}
dau_reg_port_write(unit, port);
}
/* 发送数据. */
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
if (!dau[unit])
{
continue;
}
dau_param_save(unit);
}
*ret = 1;
return _debug_pkt_common_send(buf, DEBUG_ADJSUT_COEFFICIENT_SET, 1);
}
/* 获取运行状态报文处理. */
int32_t _debug_pkt_status_get(char *buf, int len)
{
debug_pkt_status_t *status = (debug_pkt_status_t*)(buf + sizeof(debug_pkt_head_t));
status->idx = 0;
status->UTC_TimeScale = time(NULL);
status->F50Hz_Frequency = dau_power_frequency_get();
status->F50Hz_SynStatus = pd_state.sync;
status->dau_status = dau_connect_get();
status->sensor_status = 0;
status->is_server_link = csg.is_connect;
status->version = version_hex;
status->communication_time = csg.communication_time;
status->run_time = status->UTC_TimeScale - start_time;
/* 发送数据. */
return _debug_pkt_common_send(buf, DEBUG_RUN_STATUS_GET, sizeof(debug_pkt_status_t));
}
/* CMU 升级报文处理. */
int32_t _debug_pkt_mcu_upgrade(char *buf, int len)
{
debug_pkt_head_t *head = (debug_pkt_head_t*)buf;
char *date = buf + sizeof(debug_pkt_head_t);
int fd = 0;
/* 保存文件. */
fd = open(DEBUG_CMU_FILE_BAK, O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd <= 0)
{
DBG(DBG_M_DEBUG, "Open " DEBUG_CMU_FILE_BAK " ERROR\r\n");
return E_SYS_CALL;
}
if (write(fd, date, head->len) != head->len)
{
DBG(DBG_M_DEBUG, "Write " DEBUG_CMU_FILE_BAK " ERROR\r\n");
return E_SYS_CALL;
}
close(fd);
if (rename(DEBUG_CMU_FILE_BAK, DEBUG_CMU_FILE) < 0)
{
DBG(DBG_M_DEBUG, "Rename " DEBUG_CMU_FILE_BAK " ERROR\r\n");
return E_SYS_CALL;
}
/* 发送回复. */
_debug_pkt_common_send(buf, DEBUG_ARM_UPGRADE, 0);
reboot_system(DBG_M_DEBUG, BOOT_LOCAL_ARM_UPGRADE);
return E_NONE;
}
/* DAU 升级报文处理. */
int32_t _debug_pkt_dau_upgrade(char *buf, int len, uint8_t bitmap)
{
debug_pkt_head_t *head = (debug_pkt_head_t*)buf;
char *date = buf + sizeof(debug_pkt_head_t);
int8_t *ret = (int8_t*)(buf + sizeof(debug_pkt_head_t));
int fd = 0;
fd = open(DEBUG_DAU_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd <= 0)
{
DBG(DBG_M_DEBUG, "Open " DEBUG_DAU_FILE " ERROR\r\n");
return E_SYS_CALL;
}
if (write(fd, date, head->len) != head->len)
{
DBG(DBG_M_DEBUG, "Write " DEBUG_DAU_FILE " ERROR\r\n");
return E_SYS_CALL;
}
close(fd);
/* 发送回复. */
if (dau_update() != E_NONE)
{
*ret = 0;
}
else
{
*ret = 1;
}
_debug_pkt_common_send(buf, head->cmd, 1);
reboot_system(DBG_M_DEBUG, BOOT_LOCAL_FPGA_UPGRADE);
return E_NONE;
}
int32_t _debug_all_upgrade(char *buf, int len)
{
debug_pkt_head_t *head = (debug_pkt_head_t*)buf;
char *date = buf + sizeof(debug_pkt_head_t);
//int8_t *ret = (int8_t*)(buf + sizeof(debug_pkt_head_t));
int fd = 0;
char upgrade_file[128] = {0};
if (buf == NULL)
{
return E_BAD_PARAM;
}
printh("cmd:0x%x len:%d\n", head->cmd, head->len);
snprintf(upgrade_file, 127, "/home/gis/%s", UPGRADE_SOFTWARE);
fd = open(upgrade_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd <= 0)
{
DBG(DBG_M_DEBUG, "Open " DEBUG_DAU_FILE " ERROR\r\n");
return E_SYS_CALL;
}
if (write(fd, date, head->len) != head->len)
{
DBG(DBG_M_DEBUG, "Write " DEBUG_DAU_FILE " ERROR\r\n");
return E_SYS_CALL;
}
close(fd);
return _debug_pkt_common_send(buf, head->cmd, 1);
}
/* 报文校验. */
int32_t _debug_pkt_check(char *buf, int len)
{
debug_pkt_head_t *head = (debug_pkt_head_t*)buf;
uint16_t *tail = (uint16_t*)(buf + len - 2);
if (*tail != DEBUG_TAIL)
{
return E_ERROR;
}
if(head->head != DEBUG_HEAD)
{
return E_ERROR;
}
return E_NONE;
}
/* 调试工具报文数据处理. */
int32_t _debug_pkt_process(char *buf, int32_t len)
{
debug_pkt_head_t *head = (debug_pkt_head_t*)buf;
/* 报文格式检查. */
LD_E_RETURN(DBG_M_DEBUG, _debug_pkt_check(buf, len));
/* 报文处理. */
switch(head->cmd)
{
case DEBUG_CONFIG_GET:
_debug_pkt_cfg_get(buf, len);
break;
case DEBUG_CONFIG_SET:
_debug_pkt_cfg_set(buf, len);
break;
case DEBUG_ALARM_CONFIG_GET:
break;
case DEBUG_REBOOT:
_debug_pkt_reboot(buf, len);
break;
case DEBUG_TIME_SET:
_debug_pkt_time_set(buf, len);
break;
case DEBUG_NOISE_CAREFOR:
_debug_pkt_manual_col(buf, len);
break;
case DEBUG_RUN_STATUS_GET:
_debug_pkt_status_get(buf, len);
break;
case DEBUG_ADJSUT_COEFFICIENT_GET:
_debug_pkt_adj_get(buf, len);
break;
case DEBUG_ADJSUT_COEFFICIENT_SET:
_debug_pkt_adj_set(buf, len);
break;
case DEBUG_ARM_UPGRADE:
_debug_pkt_mcu_upgrade(buf, len);
break;
case DEBUG_FPGA1_UPGRADE:
_debug_pkt_dau_upgrade(buf, len, 0x01);
break;
case DEBUG_FPGA2_UPGRADE:
_debug_pkt_dau_upgrade(buf, len, 0x02);
break;
case DEBUG_FPGA3_UPGRADE:
_debug_pkt_dau_upgrade(buf, len, 0x04);
break;
case DEBUG_FPGA4_UPGRADE:
_debug_pkt_dau_upgrade(buf, len, 0x08);
break;
case DEBUG_FPGA_UPGRADE:
_debug_pkt_dau_upgrade(buf, len, 0x0f);
break;
case DEBUG_UPGRADE_ALL:
_debug_all_upgrade(buf, len);
//init_upgrade_manage();
break;
default:
DBG(DBG_M_DEBUG, "Debug not support cmd:%x\n", head->cmd);
break;
}
return E_NONE;
}
/* tcp 连接粘包处理函数. */
int32_t _debug_pkt_recv_adhesion(char *buf, int len, int *len_recv)
{
debug_pkt_head_t *head = NULL;
static int len_pkt = 0;
static int bytes_cnt = 0;
static int state = 0;
if (0 == state)
{
/* 首包处理. */
head = (debug_pkt_head_t*)buf;
bytes_cnt = 0;
if (head->len > 10485000)
{
/* 报文太长不处理. */
return -1;
}
else if (0x55aa == head->head)
{
/* 报文头处理, 置标志位. */
state = 1;
/* 计算剩余报文长度, 复制数据, 并计算收包总长度. */
len_pkt = head->len + 10 - len;
memcpy(buf_cmd + bytes_cnt, buf, len);
bytes_cnt += len;
/* 计算下一包应该接收多大的数据. */
if (len_pkt > DEBUG_BUG_SIZE)
{
*len_recv = DEBUG_BUG_SIZE;
}
else
{
*len_recv = len_pkt;
}
}
else
{
/* 在状体 0 下, 收到的报文不是以 0x55aa 开头, 无效报文不处理. */
return -1;
}
}
else if(1 == state)
{
/* 报文内容处理. */
/* 计算剩余报文长度, 复制数据, 并计算收包总长度. */
len_pkt -= len;
memcpy(buf_cmd + bytes_cnt, buf, len);
bytes_cnt += len;
/* 计算下一包应该接收多大的数据. */
if (len_pkt > DEBUG_BUG_SIZE)
{
*len_recv = DEBUG_BUG_SIZE;
}
else
{
*len_recv = len_pkt;
}
}
/* 报文没有收全, 继续等待数据. */
if (len_pkt > 0)
{
return 0;
}
state = 0;
return bytes_cnt;
}
/* 调试工具报文接收处理线程. */
void *_debug_pkt_recv_handle(void *arg)
{
struct sockaddr_in client = {0};
char *buf = debug_ctrl.buf;
socklen_t sockt_len = 0;
int len = 0;
int len_pkt = 0;
int len_recv = DEBUG_BUG_SIZE;
while (!is_system_init)
{
sleep(1);
}
/* 监听端口. */
if ((listen(debug_ctrl.fd, 5)) != 0)
{
log_err(LOG_DEBUG, "ERROR at socket listen return %s!", safe_strerror(errno));
return NULL;
}
while(1)
{
/* 连接调试工具. */
sockt_len = sizeof(client);
debug_ctrl.fd_client = accept(debug_ctrl.fd, (struct sockaddr*)&client, &sockt_len);
if (debug_ctrl.fd_client < 0)
{
log_err(LOG_DEBUG, "ERROR at socket accept return %s!", safe_strerror(errno));
continue;
}
/* 连接成功. */
while(1)
{
// 开启保活,保活参数 表示60秒内无交互后每隔6秒检测一次40次都没得到响应时会断开连接。
int keep_alive = 1;
int keep_idle = 60;
int keep_interval = 6;
int keep_count = 40;
if (setsockopt(debug_ctrl.fd_client, SOL_SOCKET, SO_KEEPALIVE, &keep_alive, sizeof(keep_alive)))
{
log_err(LOG_DEBUG, "Error setsockopt(SO_KEEPALIVE) failed, return %s!", safe_strerror(errno));
return NULL;
}
if (setsockopt(debug_ctrl.fd_client, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle, sizeof(keep_idle)))
{
log_err(LOG_DEBUG, "Error setsockopt(TCP_KEEPIDLE) failed, return %s!", safe_strerror(errno));
return NULL;
}
if (setsockopt(debug_ctrl.fd_client, SOL_TCP, TCP_KEEPINTVL, (void *)&keep_interval, sizeof(keep_interval)))
{
log_err(LOG_DEBUG, "Error setsockopt(TCP_KEEPINTVL) failed, return %s!", safe_strerror(errno));
return NULL;
}
if (setsockopt(debug_ctrl.fd_client, SOL_TCP, TCP_KEEPCNT, (void *)&keep_count, sizeof(keep_count)))
{
log_err(LOG_DEBUG, "Error setsockopt(TCP_KEEPCNT) failed, return %s!", safe_strerror(errno));
return NULL;
}
/* 读取数据. */
len = read(debug_ctrl.fd_client, buf, len_recv);
if (len <= 0)
{
/* 连接中断, 关闭 socket 和手动采样. */
DBG(DBG_M_DEBUG, "Read len %d, close fd!\r\n", len);
debug_ctrl.is_manual_col = FALSE;
close(debug_ctrl.fd_client);
break;
}
/* 粘包处理. */
len_pkt = _debug_pkt_recv_adhesion(buf, len, &len_recv);
if (len_pkt <= 0)
{
continue;
}
_debug_pkt_process(buf_cmd, len_pkt);
len_recv = DEBUG_BUG_SIZE;
}
}
return NULL;
}
/* 用于定时将端口的状态发送给调试软件. */
void* _debug_port_state_get(void *arg)
{
/* 如果手动采样开启, 则发送数据. */
if (debug_ctrl.is_manual_col)
{
dau_port_state_get(NULL);
}
/* 重新加入定时器. */
mtimer_add(_debug_port_state_get, NULL, 1, "DEBUG_PORT_STATE_GET");
return NULL;
}
/* Interface functions -------------------------------------------------------*/
/* 调试工具初始化. */
int32_t debug_handle_init(void)
{
struct sockaddr_in server;
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int32_t rv = 0;
int fd = 0;
int opt = 1;
/* 创建 socket. */
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
log_err(LOG_DEBUG, "ERROR at socket create return %s!", safe_strerror(errno));
return E_SYS_CALL;
}
/* fd 为需要端口复用的套接字. */
opt = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
/* 绑定端口. */
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(DEBUG_MANAGE_TOOL_PORT);
if(bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
{
log_err(LOG_DEBUG, "ERROR at socket bind return %s!", safe_strerror(errno));
close(fd);
return E_SYS_CALL;
}
/* 保存数据. */
debug_ctrl.fd = fd;
/* 初始化报文处理线程. */
/* 配置线程RR调度, 优先级25. */
pthread_attr_init(&attr);
param.sched_priority = 25;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, _debug_pkt_recv_handle, NULL);
if (rv != 0)
{
log_err(LOG_DEBUG, "PD can't create debug pthread %d!", rv);
return E_SYS_CALL;
}
else
{
thread_m_add("PD_DEBUG", pid);
}
pthread_attr_destroy(&attr);
/* 每秒上传 DAU 状态寄存器. */
mtimer_add(_debug_port_state_get, NULL, 1, "DEBUG_PORT_STATE_GET");
return E_NONE;
}
/* 数据手动上传报文处理. */
int32_t debug_pkt_port_state_post(void)
{
char *buf = debug_ctrl.buf_post;
debug_pkt_port_t *data = (debug_pkt_port_t *)(buf + sizeof(debug_pkt_head_t));
uint8_t i = 0;
uint8_t unit = 0;
uint8_t port = 0;
if (!debug_ctrl.is_manual_col)
{
return E_NONE;
}
for(i = 0; i < PD_PORT_SUM; i++)
{
if (E_NONE == dau_vport_to_port(i + 1, &unit, &port))
{
data->vport[i].value_adc = dau[unit]->port_state_reg.MSRR[port];
data->vport[i].value_adj = dau[unit]->port_state_reg.AVR[port];
}
else
{
data->vport[i].value_adc = 0;
data->vport[i].value_adj = -800;
}
}
/* 发送数据. */
return _debug_pkt_common_send(buf, DEBUG_NOISE_POST, sizeof(debug_pkt_port_t));
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/