|  |  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  |  * 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>© 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 "main.h"
 | 
					
						
							|  |  |  |  | #include "mtimer.h"
 | 
					
						
							|  |  |  |  | #include "pd_dbg.h"
 | 
					
						
							|  |  |  |  | #include "pd_csg.h"
 | 
					
						
							|  |  |  |  | #include "pd_dau.h"
 | 
					
						
							|  |  |  |  | #include "pd_upgrade.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 "./bak/PDMonitor.bak"
 | 
					
						
							|  |  |  |  | #define DEBUG_CMU_FILE_UPGRADE "PDMonitor.upgrade"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* Private macro -------------------------------------------------------------*/ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* Private typedef -----------------------------------------------------------*/ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* Private variables ---------------------------------------------------------*/ | 
					
						
							|  |  |  |  | debug_ctrl_t debug_ctrl; | 
					
						
							|  |  |  |  | dbg_device_info_t dbg_base_config; | 
					
						
							|  |  |  |  | dbg_global_config_t dbg_global_config; | 
					
						
							|  |  |  |  | dbg_config_port_t dbg_port_config; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static char buf_cmd[DEBUG_CMD_LEN]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* Private function prototypes -----------------------------------------------*/ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* Internal functions --------------------------------------------------------*/ | 
					
						
							|  |  |  |  | void _debug_pkt_head_int(dbg_pkt_head_t *head, uint16_t cmd, uint32_t len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     head->head = DEBUG_HEAD; | 
					
						
							|  |  |  |  |     head->cmd = cmd; | 
					
						
							|  |  |  |  |     head->len = len; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /*  回复报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_common_send(char *buf, uint16_t cmd, uint32_t data_len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     uint16_t total_len; | 
					
						
							|  |  |  |  |     dbg_pkt_head_t *head = (dbg_pkt_head_t*)buf; | 
					
						
							|  |  |  |  |     head->len = data_len; | 
					
						
							|  |  |  |  |     uint16_t *tail = (uint16_t*)(buf + sizeof(dbg_pkt_head_t) + data_len); | 
					
						
							|  |  |  |  |     _debug_pkt_head_int(head, cmd, data_len); | 
					
						
							|  |  |  |  |     *tail = DEBUG_TAIL; | 
					
						
							|  |  |  |  |     total_len = sizeof(dbg_pkt_head_t) + data_len + 2; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "数据包 (总长度: %u bytes):\r\n", total_len); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  头部: head=0x%04X, cmd=0x%04X, len=%u\r\n", head->head, head->cmd, head->len); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  尾部: 0x%04X\r\n", *tail); | 
					
						
							|  |  |  |  |     if (write(debug_ctrl.fd_client, buf, total_len) <= 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "Write cmd %x ERROR\r\n", head->cmd); | 
					
						
							|  |  |  |  |         return E_SYS_CALL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 获取配置报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_factory_cfg_get(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_device_info_t *info = (dbg_device_info_t *)(buf+sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     memset(info, 0, sizeof(dbg_device_info_t)); | 
					
						
							|  |  |  |  |     info->type_m = device_info.type_m; | 
					
						
							|  |  |  |  |     info->type_s = device_info.type_s; | 
					
						
							|  |  |  |  |     info->dev_id = device_info.dev_id; | 
					
						
							|  |  |  |  |     snprintf((char*)info->hostname, FILE_NAME_LEN, "%s", device_info.hostname); | 
					
						
							|  |  |  |  |     info->factory_date = device_info.factory_date; | 
					
						
							|  |  |  |  |     info->deployment_date = device_info.deployment_date; | 
					
						
							|  |  |  |  |     info->ip = device_info.ip; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     memcpy(info->mac, device_info.mac, MAC_ADDR_LEN); | 
					
						
							|  |  |  |  |     info->mask = device_info.mask; | 
					
						
							|  |  |  |  |     info->gw = device_info.gw; | 
					
						
							|  |  |  |  |     strncpy((char*)info->app_version, host.version, 32); | 
					
						
							|  |  |  |  |     strncpy((char*)info->app_compile_time, host.compile, 32); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     //strncpy((char*)info->hardware_version, host.hardversion, 32);
 | 
					
						
							|  |  |  |  |     // 赋值 FPGA_version
 | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     info->csg_port = csg.server_port; | 
					
						
							|  |  |  |  |     info->csg_ipv4 = csg.server_ip; | 
					
						
							|  |  |  |  |     info->running_time = start_time; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     int32_t ret = _debug_pkt_common_send(buf, DEBUG_CONFIG_FACTORY_GET, sizeof(dbg_device_info_t)); | 
					
						
							|  |  |  |  |     /* 发送数据. */ | 
					
						
							|  |  |  |  |     return ret; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | int32_t _debug_pkt_factory_cfg_set(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     REBOOT_MSG boottype = REBOOT_NONE; | 
					
						
							|  |  |  |  |     dbg_device_info_t *info = (dbg_device_info_t *)(buf+sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if(device_info.type_m != info->type_m|| | 
					
						
							|  |  |  |  |         device_info.type_s != info->type_s|| | 
					
						
							|  |  |  |  |         device_info.dev_id != info->dev_id) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         device_info.type_m = info->type_m; | 
					
						
							|  |  |  |  |         device_info.type_s = info->type_s; | 
					
						
							|  |  |  |  |         device_info.dev_id = info->dev_id; | 
					
						
							|  |  |  |  |         boottype = REBOOT_LOCAL_HOST_NAME_CHANGE; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     snprintf(device_info.hostname, FILE_NAME_LEN, "%s", (const char*)info->hostname); | 
					
						
							|  |  |  |  |     device_info.factory_date = info->factory_date; | 
					
						
							|  |  |  |  |     device_info.deployment_date = info->deployment_date; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     if (device_info.ip != info->ip) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "IP 地址变更: %u.%u.%u.%u -> %u.%u.%u.%u\r\n", | 
					
						
							|  |  |  |  |             device_info.ip & 0xFF, (device_info.ip >> 8) & 0xFF, (device_info.ip >> 16) & 0xFF, (device_info.ip >> 24) & 0xFF, | 
					
						
							|  |  |  |  |             info->ip & 0xFF, (info->ip >> 8) & 0xFF, (info->ip >> 16) & 0xFF, (info->ip >> 24) & 0xFF); | 
					
						
							|  |  |  |  |         device_info.ip = info->ip; | 
					
						
							|  |  |  |  |         mac_generate_from_ip(device_info.ip, info->mac); | 
					
						
							|  |  |  |  |         memcpy(device_info.mac, info->mac, MAC_ADDR_LEN); | 
					
						
							|  |  |  |  |         boottype = REBOOT_REMOTE_IP_CHANGE; | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         vtysh_eth0_save(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     device_info.gw = info->gw; | 
					
						
							|  |  |  |  |     device_info.mask = info->mask; | 
					
						
							|  |  |  |  |     vtysh_device_save(); | 
					
						
							|  |  |  |  |     if (csg.server_ip != info->csg_ipv4) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         csg.server_ip = info->csg_ipv4; | 
					
						
							|  |  |  |  |         boottype = REBOOT_REMOTE_SERVER_IP_CHANGE; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (csg.server_port != info->csg_port) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         csg.server_port = info->csg_port; | 
					
						
							|  |  |  |  |         boottype = REBOOT_REMOTE_SERVER_IP_CHANGE; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     vtysh_config_save(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 打印接收到的设备信息
 | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "================================================\r\n"); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "接收到的设备信息:\r\n"); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  主设备号 (type_m): %u\r\n", info->type_m); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  次设备号 (type_s): %u\r\n", info->type_s); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  设备ID (dev_id): %u\r\n", info->dev_id); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  主机名 (hostname): %s\r\n", info->hostname); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  出厂时间 (factory_date): %u\r\n", info->factory_date); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  部署时间 (deployment_date): %u\r\n", info->deployment_date); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  IP 地址 (ip): %u.%u.%u.%u\r\n", | 
					
						
							|  |  |  |  |         (info->ip) & 0xFF, (info->ip >> 8) & 0xFF, (info->ip >> 16) & 0xFF, (info->ip  >> 24) & 0xFF); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  子网掩码 (mask): %u.%u.%u.%u\r\n", | 
					
						
							|  |  |  |  |         (info->mask) & 0xFF, (info->mask >> 8) & 0xFF, (info->mask >> 16) & 0xFF, (info->mask >> 24) & 0xFF); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  网关 (gw): %u.%u.%u.%u\r\n", | 
					
						
							|  |  |  |  |         (info->gw) & 0xFF, (info->gw >> 8) & 0xFF, (info->gw >> 16) & 0xFF, (info->gw >> 24) & 0xFF); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  MAC 地址 (mac): %02X:%02X:%02X:%02X:%02X:%02X\r\n", | 
					
						
							|  |  |  |  |         info->mac[0], info->mac[1], info->mac[2], info->mac[3], info->mac[4], info->mac[5]); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  CSG 端口 (csg_port): %u\r\n", info->csg_port); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "  CSG 服务器 IP (csg_ipv4): %u.%u.%u.%u\r\n", | 
					
						
							|  |  |  |  |         (info->csg_ipv4 >> 24) & 0xFF, (info->csg_ipv4 >> 16) & 0xFF, (info->csg_ipv4 >> 8) & 0xFF, info->csg_ipv4 & 0xFF); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (boottype) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         _debug_pkt_common_send(buf, DEBUG_CONFIG_FACTORY_SET, 0); | 
					
						
							|  |  |  |  |         sleep(1); | 
					
						
							|  |  |  |  |         reboot_system(LOG_DEBUG, boottype); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 设置报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_global_cfg_set(char *pkt, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dau_t * dau_node = dau[0]; | 
					
						
							|  |  |  |  |     dbg_global_config_t *config = (dbg_global_config_t *)(pkt + sizeof(csg_pkt_head_t)); | 
					
						
							|  |  |  |  |     pd_config.config.sample_frequency = config->sample_frequency; | 
					
						
							|  |  |  |  |     pd_config.config.trigger_sample_nums = config->trigger_sample_numbers; | 
					
						
							|  |  |  |  |     pd_config.config.trig_location = (config->pre_trigger_percent << 4) / 100.00; | 
					
						
							|  |  |  |  |     pd_config.config.trig_threshold = config->trigLevel; | 
					
						
							|  |  |  |  |     pd_config.config.trend_up_period = config->trend_up_period; | 
					
						
							|  |  |  |  |     pd_config.config.heartbeat_period = config->heartbeat_period; | 
					
						
							|  |  |  |  |     pd_config.config.ch_en_mask = config->ch_en_mask; | 
					
						
							|  |  |  |  |     if (config->sync_mode == 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |        BITMAP_RESET(pd_config.config.pt_B_sync_mode, PD_BIT_PT); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     else | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         BITMAP_SET(pd_config.config.pt_B_sync_mode, PD_BIT_PT); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     pd_config.config.pt_internal_period = 1000000000UL / config->pt_internal_period; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if(dau_node->is_connect == TRUE) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         dau_node->reg->reg_global.trig_location = pd_config.config.trig_location; | 
					
						
							|  |  |  |  |         dau_node->reg->reg_global.trig_threshold = pd_config.config.trig_threshold; | 
					
						
							|  |  |  |  |         dau_node->reg->reg_global.trig_gap = pd_config.config.trig_gap; | 
					
						
							|  |  |  |  |         dau_node->reg->reg_global.sample_interrupt_intveal_us = pd_config.config.interrupt_interval; | 
					
						
							|  |  |  |  |         dau_node->reg->reg_global.pt_B_sync_mode = pd_config.config.pt_B_sync_mode; | 
					
						
							|  |  |  |  |         dau_node->reg->reg_global.pt_selfsync_cycle = pd_config.config.pt_internal_period; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     vtysh_config_save(); | 
					
						
							|  |  |  |  |     return _debug_pkt_common_send(pkt, DEBUG_CONFIG_GLOBAL_SET, 0); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 查询用户参数查询报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_global_cfg_get(char *pkt, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_global_config_t *pconfig = (dbg_global_config_t *)(pkt + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |     pconfig->sample_frequency = pd_config.config.sample_frequency; | 
					
						
							|  |  |  |  |     pconfig->trigger_sample_numbers = pd_config.config.trigger_sample_nums; | 
					
						
							|  |  |  |  |     pconfig->pre_trigger_percent = (uint32_t)(pd_config.config.trig_location * 100 / 16.00 + 0.5); | 
					
						
							|  |  |  |  |     pconfig->trigLevel = pd_config.config.trig_threshold; | 
					
						
							|  |  |  |  |     pconfig->trend_up_period = pd_config.config.trend_up_period; | 
					
						
							|  |  |  |  |     pconfig->heartbeat_period = pd_config.config.heartbeat_period; | 
					
						
							|  |  |  |  |     pconfig->ch_en_mask = pd_config.config.ch_en_mask; | 
					
						
							|  |  |  |  |     if (IS_BITMAP_SET(pd_config.config.pt_B_sync_mode, PD_BIT_PT)) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         pconfig->sync_mode = 1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     else | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         pconfig->sync_mode = 0; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     pconfig->pt_internal_period = 1000000000UL / pd_config.config.pt_internal_period; | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(pkt, DEBUG_CONFIG_GLOBAL_GET, sizeof(dbg_global_config_t)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 设置报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_port_cfg_set(char *pkt, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     uint8_t unit = 0; | 
					
						
							|  |  |  |  |     uint8_t port = 0; | 
					
						
							|  |  |  |  |     dbg_config_port_t *pnet = (dbg_config_port_t *)(pkt + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     if (dau_vport_to_port(pnet->vport, &unit, &port) != E_NONE) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "Pkt port %d error!\r\n", pnet->vport); | 
					
						
							|  |  |  |  |         return E_ERROR; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].vport = pnet->vport; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].type = pnet->channel_type; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].filter_frequency = pnet->filter_frequency; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].rise_time = pnet->rise_time; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].peak_time = pnet->peak_time; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].fall_time = pnet->fall_time; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].pulse_width = pnet->pulse_width; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].peak_count = pnet->peak_count; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].signal_envelope = pnet->signal_envelope; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].signal_mean = pnet->signal_mean; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].signal_variance = pnet->signal_variance; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].primary_frequency = pnet->primary_frequency; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].primary_freq_peak = pnet->primary_freq_peak; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].spectral_peak_count = pnet->spectral_peak_count; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].spectrum_mean = pnet->spectrum_mean; | 
					
						
							|  |  |  |  |     pd_config.config_port[unit][port].spectrum_variance = pnet->spectrum_variance; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     vtysh_config_save(); | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(pkt, DEBUG_CONFIG_PORT_SET, 0); | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 查询用户参数查询报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_port_cfg_get(char *pkt, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_config_port_t *pnet = (dbg_config_port_t *)(pkt + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |     uint8_t unit = 0; | 
					
						
							|  |  |  |  |     uint8_t port = 0; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     if (dau_vport_to_port(pnet->vport, &unit, &port) != E_NONE) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "Pkt port %d error!\r\n", pnet->vport); | 
					
						
							|  |  |  |  |         return E_ERROR; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     pnet->vport = pd_config.config_port[unit][port].vport; | 
					
						
							|  |  |  |  |     pnet->channel_type = pd_config.config_port[unit][port].type; | 
					
						
							|  |  |  |  |     pnet->vport = pd_config.config_port[unit][port].vport; | 
					
						
							|  |  |  |  |     pnet->channel_type = pd_config.config_port[unit][port].type; | 
					
						
							|  |  |  |  |     pnet->filter_frequency = pd_config.config_port[unit][port].filter_frequency; | 
					
						
							|  |  |  |  |     pnet->rise_time = pd_config.config_port[unit][port].rise_time; | 
					
						
							|  |  |  |  |     pnet->peak_time = pd_config.config_port[unit][port].peak_time; | 
					
						
							|  |  |  |  |     pnet->fall_time = pd_config.config_port[unit][port].fall_time; | 
					
						
							|  |  |  |  |     pnet->pulse_width = pd_config.config_port[unit][port].pulse_width; | 
					
						
							|  |  |  |  |     pnet->peak_count = pd_config.config_port[unit][port].peak_count; | 
					
						
							|  |  |  |  |     pnet->signal_envelope = pd_config.config_port[unit][port].signal_envelope; | 
					
						
							|  |  |  |  |     pnet->signal_mean = pd_config.config_port[unit][port].signal_mean; | 
					
						
							|  |  |  |  |     pnet->signal_variance = pd_config.config_port[unit][port].signal_variance; | 
					
						
							|  |  |  |  |     pnet->primary_frequency = pd_config.config_port[unit][port].primary_frequency; | 
					
						
							|  |  |  |  |     pnet->primary_freq_peak = pd_config.config_port[unit][port].primary_freq_peak; | 
					
						
							|  |  |  |  |     pnet->spectral_peak_count = pd_config.config_port[unit][port].spectral_peak_count; | 
					
						
							|  |  |  |  |     pnet->spectrum_mean = pd_config.config_port[unit][port].spectrum_mean; | 
					
						
							|  |  |  |  |     pnet->spectrum_variance = pd_config.config_port[unit][port].spectrum_variance; | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(pkt, DEBUG_CONFIG_PORT_GET, sizeof(dbg_config_port_t)); | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 重启报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_reboot(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     /* 发送数据. */ | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(buf, DEBUG_REBOOT, 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 重启. */ | 
					
						
							|  |  |  |  |     reboot_system(LOG_DEBUG, REBOOT_LOCAL_RESET); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 时间设置报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_time_set(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     uint32_t *timestamp = (uint32_t*)(buf + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 配置时间. */ | 
					
						
							|  |  |  |  |     time_set(*timestamp); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 发送数据. */ | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(buf, DEBUG_TIME_SET, 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 获取运行状态报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_status_get(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     debug_pkt_status_t *status = (debug_pkt_status_t*)(buf + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |     status->utc = time(NULL); | 
					
						
							|  |  |  |  |     status->run_time = start_time; | 
					
						
							|  |  |  |  |     status->is_server_link = csg.is_connect; | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(buf, DEBUG_DEVICE_STATUS, sizeof(debug_pkt_status_t)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 获取运行状态报文处理. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_set_wave_address(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_wave_addr_t *wave = (dbg_wave_addr_t*)(buf + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     bzero(&csg.wave_svr, sizeof(csg.wave_svr)); | 
					
						
							|  |  |  |  |     csg.wave_svr.sin_family = AF_INET; | 
					
						
							|  |  |  |  |     csg.wave_svr.sin_addr.s_addr = inet_addr(wave->ipv4); | 
					
						
							|  |  |  |  |     csg.wave_svr.sin_port = htons(wave->port); | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(buf, DEBUG_SET_WAVE_ADDRESS, 0); | 
					
						
							|  |  |  |  |         | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | int32_t _debug_pkt_upgrade(char *pkt, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     static int fd = -1; | 
					
						
							|  |  |  |  |     static uint32_t fix_len = 0; | 
					
						
							|  |  |  |  |     dbg_upgrade_data_t *head_msg = (dbg_upgrade_data_t*)(pkt + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |     char *pdata = pkt + sizeof(dbg_pkt_head_t) + sizeof(dbg_upgrade_data_t); | 
					
						
							|  |  |  |  |     dbg_upgrade_ack_t *pack = (dbg_upgrade_ack_t*)(pkt + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |     int32_t size = 0; | 
					
						
							|  |  |  |  |     int32_t len_wr = 0; | 
					
						
							|  |  |  |  |     uint32_t offset = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     csg.is_connect = FALSE;   //关闭主动上传
 | 
					
						
							|  |  |  |  |     /* 首保处理, 打开文件描述符, 初始化变量 */ | 
					
						
							|  |  |  |  |     if (head_msg->index == 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (fd > 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             close(fd); | 
					
						
							|  |  |  |  |             fd = -1; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         fd = open(PD_UPG_SOFTWARE, O_WRONLY | O_CREAT | O_TRUNC, 0777); | 
					
						
							|  |  |  |  |         if (fd < 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             DBG(DBG_M_DEBUG, "Open file " PD_UPG_SOFTWARE " error!\r\n"); | 
					
						
							|  |  |  |  |             return E_SYS_CALL; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         fix_len = head_msg->len; | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "Receive upgrade file start.\r\n"); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG,"type=%d,sum=%d,index=%d,len=%d,fix_len=%d\r\n", head_msg->type, head_msg->sum, head_msg->index, head_msg->len, fix_len); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 收包流程 */ | 
					
						
							|  |  |  |  |     size = head_msg->len; | 
					
						
							|  |  |  |  |     offset = head_msg->index * fix_len; | 
					
						
							|  |  |  |  |     if (lseek(fd, offset, SEEK_SET) < 0)  | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         int error = errno; | 
					
						
							|  |  |  |  |         DBG(DBG_M_PD_CSG_ERR, "lseek file " PD_UPG_SOFTWARE " error: %s, fd=%d, offset=%ld\r\n",  | 
					
						
							|  |  |  |  |             strerror(error), fd, offset); | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         // 检查具体错误类型
 | 
					
						
							|  |  |  |  |         switch(error) { | 
					
						
							|  |  |  |  |             case EBADF:  // 无效文件描述符
 | 
					
						
							|  |  |  |  |                 DBG(DBG_M_DEBUG, "Invalid file descriptor\r\n"); | 
					
						
							|  |  |  |  |                 break; | 
					
						
							|  |  |  |  |             case EINVAL: // 无效的 whence 或 offset
 | 
					
						
							|  |  |  |  |                 DBG(DBG_M_DEBUG, "Invalid offset or whence\r\n"); | 
					
						
							|  |  |  |  |                 break; | 
					
						
							|  |  |  |  |             case EOVERFLOW: // offset 过大
 | 
					
						
							|  |  |  |  |                 DBG(DBG_M_DEBUG, "Offset overflow\r\n"); | 
					
						
							|  |  |  |  |                 break; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return E_SYS_CALL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     len_wr = write(fd, pdata, size); | 
					
						
							|  |  |  |  |     if (len_wr != size) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "Write file " PD_UPG_SOFTWARE " error!\r\n"); | 
					
						
							|  |  |  |  |         return E_SYS_CALL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     /* 最后一个报文处理 */ | 
					
						
							|  |  |  |  |     if (head_msg->sum - 1 == head_msg->index) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         close(fd); | 
					
						
							|  |  |  |  |         fd = -1; | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "Receive upgrade file end.\r\n"); | 
					
						
							|  |  |  |  |         pd_upg_start(PD_UPG_FROM_CSG, head_msg->type); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     pack->index = head_msg->index; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 发送应答 */ | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(pkt, DEBUG_UPGRADE_DATA, sizeof(dbg_upgrade_ack_t)); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 报文校验. */ | 
					
						
							|  |  |  |  | int32_t _debug_pkt_check(char *buf, int len) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_pkt_head_t *head = (dbg_pkt_head_t*)buf; | 
					
						
							|  |  |  |  |     uint16_t *tail = (uint16_t*)(buf + len - 2); | 
					
						
							|  |  |  |  |     DBG(DBG_M_DEBUG, "receive data head->head is 0X%X!,tail is 0X%X!\r\n", | 
					
						
							|  |  |  |  |                             head->head, *tail); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     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) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_pkt_head_t *head = (dbg_pkt_head_t*)buf; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 报文格式检查. */ | 
					
						
							|  |  |  |  |     LD_E_RETURN(DBG_M_DEBUG, _debug_pkt_check(buf, len)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 报文处理. */ | 
					
						
							|  |  |  |  |     switch(head->cmd) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |     case DEBUG_CONFIG_FACTORY_GET: | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "get DEBUG_CONFIG_FACTORY_GET data!\r\n"); | 
					
						
							|  |  |  |  |         _debug_pkt_factory_cfg_get(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_CONFIG_FACTORY_SET: | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "set DEBUG_CONFIG_FACTORY_SET data!\r\n"); | 
					
						
							|  |  |  |  |         _debug_pkt_factory_cfg_set(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_CONFIG_GLOBAL_GET: | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "get DEBUG_CONFIG_GLOBAL_GET data!\r\n"); | 
					
						
							|  |  |  |  |         _debug_pkt_global_cfg_get(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_CONFIG_GLOBAL_SET: | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "set DEBUG_CONFIG_GLOBAL_SET data!\r\n"); | 
					
						
							|  |  |  |  |         _debug_pkt_global_cfg_set(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_CONFIG_PORT_GET: | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "get DEBUG_CONFIG_PORT_GET data!\r\n"); | 
					
						
							|  |  |  |  |         _debug_pkt_port_cfg_get(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_CONFIG_PORT_SET: | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "set DEBUG_CONFIG_GLOBAL_SET data!\r\n"); | 
					
						
							|  |  |  |  |         _debug_pkt_port_cfg_set(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     case DEBUG_REBOOT: | 
					
						
							|  |  |  |  |         _debug_pkt_reboot(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_TIME_SET: | 
					
						
							|  |  |  |  |         _debug_pkt_time_set(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     case DEBUG_DEVICE_STATUS: | 
					
						
							|  |  |  |  |         _debug_pkt_status_get(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_UPGRADE_DATA: | 
					
						
							|  |  |  |  |         _debug_pkt_upgrade(buf, len); | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     case DEBUG_SET_WAVE_ADDRESS: | 
					
						
							|  |  |  |  |         _debug_pkt_set_wave_address( buf,  len); | 
					
						
							|  |  |  |  |         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) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     dbg_pkt_head_t *head = NULL; | 
					
						
							|  |  |  |  |     static int len_pkt = 0; | 
					
						
							|  |  |  |  |     static int bytes_cnt = 0; | 
					
						
							|  |  |  |  |     static int state = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (0 == state) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         /* 首包处理. */ | 
					
						
							|  |  |  |  |         head = (dbg_pkt_head_t*)buf; | 
					
						
							|  |  |  |  |         bytes_cnt = 0; | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         if (head->len > 10485000) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             /* 报文太长不处理. */ | 
					
						
							|  |  |  |  |             return -1; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         else if (0x55aa == head->head) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |                 DBG(DBG_M_DEBUG, "pkt datalen head->len is %d\r\n", head->len); | 
					
						
							|  |  |  |  |             /* 报文头处理, 置标志位. */ | 
					
						
							|  |  |  |  |             state = 1; | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |             /* 计算剩余报文长度, 复制数据, 并计算收包总长度. */ | 
					
						
							|  |  |  |  |             len_pkt = head->len + 32 - 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; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         printf("@2len_pkt=%d\n", len_pkt); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 报文没有收全, 继续等待数据. */ | 
					
						
							|  |  |  |  |     if (len_pkt > 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         return 0; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     state = 0; | 
					
						
							|  |  |  |  |     return bytes_cnt; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | int _debug_keep_alive(int fd) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // 开启保活,保活参数 表示60秒内无交互后,每隔6秒检测一次,40次都没得到响应时会断开连接。
 | 
					
						
							|  |  |  |  |     int keep_alive = 1; | 
					
						
							|  |  |  |  |     int keep_idle = 60; | 
					
						
							|  |  |  |  |     int keep_interval = 6; | 
					
						
							|  |  |  |  |     int keep_count = 10; | 
					
						
							|  |  |  |  |     if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive, sizeof(keep_alive))) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         log_err(LOG_DEBUG, "Error setsockopt(SO_KEEPALIVE) failed, return %s!", safe_strerror(errno)); | 
					
						
							|  |  |  |  |         return -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle, sizeof(keep_idle))) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         log_err(LOG_DEBUG, "Error setsockopt(TCP_KEEPIDLE) failed, return %s!", safe_strerror(errno)); | 
					
						
							|  |  |  |  |         return -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     if (setsockopt(fd, 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 -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     if (setsockopt(fd, 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 -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return 0; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 调试工具报文接收处理线程. */ | 
					
						
							|  |  |  |  | void *_debug_pkt_recv_handle(void *arg) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     char *buf = debug_ctrl.buf; | 
					
						
							|  |  |  |  |     int len = 0; | 
					
						
							|  |  |  |  |     int len_pkt = 0; | 
					
						
							|  |  |  |  |     int len_recv = DEBUG_BUG_SIZE; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     while(1) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         /* 连接成功. */ | 
					
						
							|  |  |  |  |         len_recv = DEBUG_BUG_SIZE; | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         if (debug_ctrl.fd_client > 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             /* 读取数据. */ | 
					
						
							|  |  |  |  |             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); | 
					
						
							|  |  |  |  |                 close(debug_ctrl.fd_client); | 
					
						
							|  |  |  |  |                 debug_ctrl.fd_client = -1; | 
					
						
							|  |  |  |  |                 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; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         usleep(10*1000); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     pthread_exit("thread exit"); | 
					
						
							|  |  |  |  |     return NULL; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | int32_t _debug_create_recv_thread() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     struct sched_param param; | 
					
						
							|  |  |  |  |     pthread_attr_t attr; | 
					
						
							|  |  |  |  |     int32_t rv = 0; | 
					
						
							|  |  |  |  |     pthread_t thread; | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |     /* 初始化报文处理线程. */ | 
					
						
							|  |  |  |  |     /* 配置线程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); | 
					
						
							|  |  |  |  |     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 
					
						
							|  |  |  |  |     rv = pthread_create(&thread, &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", thread); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     pthread_attr_destroy(&attr); | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void *_debug_accept_connect_handle() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     struct sockaddr_in cliaddr = {0}; | 
					
						
							|  |  |  |  |     socklen_t clilen; | 
					
						
							|  |  |  |  |     int connfd; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /* 等待初始化完成 */ | 
					
						
							|  |  |  |  |     while(!is_system_init) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         usleep(100000); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     /* 监听端口. */ | 
					
						
							|  |  |  |  |     if ((listen(debug_ctrl.fd, 5)) != 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         log_err(LOG_DEBUG, "ERROR at socket listen return %s!", safe_strerror(errno)); | 
					
						
							|  |  |  |  |         return NULL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     while (1) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         clilen = sizeof(cliaddr); | 
					
						
							|  |  |  |  |         connfd = accept(debug_ctrl.fd, (struct sockaddr*)&cliaddr, &clilen); | 
					
						
							|  |  |  |  |         if (connfd < 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             log_err(LOG_DEBUG, "ERROR at socket accept return %s!", safe_strerror(errno)); | 
					
						
							|  |  |  |  |             continue; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         char buf[20] = {0}; | 
					
						
							|  |  |  |  |         DBG(DBG_M_DEBUG, "new client: %s, port: %d fd_client=%d\n", | 
					
						
							|  |  |  |  |             inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(buf)), | 
					
						
							|  |  |  |  |             ntohs(cliaddr.sin_port), debug_ctrl.fd_client); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (debug_ctrl.fd_client < 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             debug_ctrl.fd_client = connfd; | 
					
						
							|  |  |  |  |             _debug_create_recv_thread(); | 
					
						
							|  |  |  |  |             _debug_keep_alive(debug_ctrl.fd_client); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         else | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             DBG(DBG_M_DEBUG, "There is a link trying to connect...\n"); | 
					
						
							|  |  |  |  |             close(connfd); | 
					
						
							|  |  |  |  |             connfd = -1; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return NULL; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* Interface functions -------------------------------------------------------*/ | 
					
						
							|  |  |  |  | /* 调试工具初始化. */ | 
					
						
							|  |  |  |  | int32_t debug_handle_init(void) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | int32_t debug_handle_init_after(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; | 
					
						
							|  |  |  |  |     debug_ctrl.fd_client = -1; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     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_accept_connect_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_ACCEPT", pid); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     pthread_attr_destroy(&attr); | 
					
						
							|  |  |  |  |     return E_NONE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 升级结果回复处理 */ | 
					
						
							|  |  |  |  | void debug_upgrade_result_send(int32_t rv, char *buf) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     char buffer[32] = {0}; | 
					
						
							|  |  |  |  |     int32_t *rt = (int32_t*)(buffer + sizeof(dbg_pkt_head_t)); | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     *rt = rv; | 
					
						
							|  |  |  |  |     _debug_pkt_common_send(buffer, 0, 4); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | #endif
 | 
					
						
							|  |  |  |  | /************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/ |