/***************************************************************************** * 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 * *

© COPYRIGHT(c) 2021 LandPower

* * 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 #include #include #include #include #include /* 用户代码头文件. */ #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, ¶m); 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 ****************/