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

927 lines
27 KiB
C

This file contains ambiguous Unicode characters!

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

/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <netinet/tcp.h>
#include "cmd.h"
#include "mtimer.h"
#include "process.h"
#include "hwgpio.h"
#include "fifo.h"
#include "debug.h"
#include "ca_dbg.h"
#include "ca_csg.h"
#include "ca_cau.h"
#include "ca_param.h"
#include "ca_network.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 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;
}
/* 回复报文处理. */
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_CA_DBG, "Write cmd %x ERROR\r\n", head->cmd);
return E_SYS_CALL;
}
return E_NONE;
}
/* 报文校验. */
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)
{
LOG("++++++++++++111");
return E_ERROR;
}
if(head->head != DEBUG_HEAD)
{
LOG("++++++++++++222");
return E_ERROR;
}
return E_NONE;
}
int _dbg_pkt_config_get(debug_msg_info_t *msg)
{
int i;
debug_pkt_device_cfg_t cfg = {0};
char *pdata = NULL;
struct in_addr addr;
if (msg == NULL)
return -1;
//sprintf((char *)pparam_config->gateway.DeviceNum, "%04d%04d",
// device_info.id_major, device_info.id_minor);
strncpy((char *)pparam_config->gateway.DeviceNum, host.name, 15);
//sysctrl.dev_hex_id = sysctrl.dev_hex_id;
inet_pton(AF_INET, device_info.host_ip, &addr);
memcpy(pparam_config->gateway.LocalIP1, &addr.s_addr, 4);
memcpy(pparam_config->gateway.ServerIP1, &csg.server.sin_addr.s_addr, 4);
pparam_config->gateway.ServerIP1_Port = csg.server_port;
LOG("serverip=0x%x", csg.server_ip);
LOG("%d %d %d %d", csg.server_ip & 0xff, (csg.server_ip >> 8) & 0xff,
(csg.server_ip >> 16) & 0xff, (csg.server_ip >> 24) & 0xff);
memcpy(&cfg.gateway, &pparam_config->gateway, sizeof(GateWay_t));
char buf[64] = {0};
sprintf(buf, "V%s", host.version);
LOG("version=%s\n", host.version);
strcpy((char *)cfg.gateway.reserved, buf);
memcpy(&cfg.landDevCfg, &pparam_config->landHexCfg, sizeof(LandDevCfg_t));
for (i = 0; i < 24; i++)
{
cfg.CAUInit[i].Range = pparam_config->cauParam[i].Range;
cfg.CAUInit[i].Ratio = pparam_config->cauParam[i].Ratio;
cfg.CAUInit[i].ZeroPoint = pparam_config->cauParam[i].ZeroPoint;
cfg.CAUInit[i].ChangeThreshold = pparam_config->cauParam[i].ChangeThreshold;
cfg.CAUInit[i].HighLimit = pparam_config->cauParam[i].HighLimit;
cfg.CAUInit[i].LowLimit = pparam_config->cauParam[i].LowLimit;
}
/* copy data */
pdata = msg->pbuf + sizeof(debug_pkt_head_t);
memcpy(pdata, &cfg, sizeof(cfg));
_debug_pkt_common_send((char *)msg->pbuf, msg->cmd, sizeof(cfg));
return 0;
}
int _dbg_pkt_config_set(debug_msg_info_t *msg)
{
int i;
if (msg == NULL)
return -1;
if (msg->len != sizeof(debug_pkt_device_cfg_t))
{
printh("_dbg_pkg_config_set invalid msg reallen:%d expect len:%d\n",
msg->len, sizeof(debug_pkt_device_cfg_t));
return -1;
}
debug_pkt_device_cfg_t *pcfg = (debug_pkt_device_cfg_t *)msg->pbuf;
if (strncmp((char *)pcfg->gateway.apn, (char *)pparam_config->gateway.apn,
sizeof(pparam_config->gateway.apn)) != 0)
{
_network_change_apn((char *)pcfg->gateway.apn);
}
if (pparam_config->gateway.radioType != pcfg->gateway.radioType
&& pcfg->gateway.radioType == 1)
{
_network_set_connect_type(CONNET4G);
}
strncpy(host.name, (char *)pcfg->gateway.DeviceNum, 15);
sysctrl.dev_hex_id = dev_id_2_hex(host.name);
sprintf(device_info.host_ip, "%d.%d.%d.%d", pcfg->gateway.LocalIP1[0],
pcfg->gateway.LocalIP1[1], pcfg->gateway.LocalIP1[2], pcfg->gateway.LocalIP1[3]);
LOG("host_ip:%s", device_info.host_ip);
char serverip[16] = {0};
sprintf(serverip, "%d.%d.%d.%d", pcfg->gateway.ServerIP1[0],
pcfg->gateway.ServerIP1[1], pcfg->gateway.ServerIP1[2], pcfg->gateway.ServerIP1[3]);
csg.server_ip = inet_addr(serverip);
LOG("serverip=0x%x", csg.server_ip);
LOG("%d %d %d %d", csg.server_ip & 0xff, (csg.server_ip >> 8) & 0xff,
(csg.server_ip >> 16) & 0xff, (csg.server_ip >> 24) & 0xff);
csg.server_port = (uint16_t)pcfg->gateway.ServerIP1_Port;
memcpy(&pparam_config->gateway, &pcfg->gateway, sizeof(GateWay_t));
memcpy(&pparam_config->landHexCfg, &pcfg->landDevCfg, sizeof(LandDevCfg_t));
for (i = 0; i < 24; i++)
{
memcpy(&pparam_config->cauParam[i], &pcfg->CAUInit[i], 24);
DBG(DBG_M_CA_DBG, "ch%d Range=%f Ratio=%f ZeroPoint=%f ChangeThreshold=%f HighLimit=%f LowLimit=%f\n",
i, pcfg->CAUInit[i].Range, pcfg->CAUInit[i].Ratio, pcfg->CAUInit[i].ZeroPoint, pcfg->CAUInit[i].ChangeThreshold, pcfg->CAUInit[i].HighLimit, pcfg->CAUInit[i].LowLimit);
}
param_save();
vtysh_config_save();
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_eth0_save();
vtysh_device_save();
reboot_system(LOG_DEBUG, BOOT_LOCAL_IP_CHANGE);
return 0;
}
int _dbg_pkt_reboot_system()
{
reboot_system(LOG_DEBUG, BOOT_LOCAL_RESET);
return 0;
}
int _dbg_get_current_cau_values(float *fdestArr)
{
float valist[24] = {0};
int chswitch;
int i;
cau_real_data_t *pval = &cau.real_data;
memcpy(valist, pval->tag, sizeof(pval->tag));
for (i = 0; i < 11; i++)
{
chswitch = pparam_config->cauParam[i].chSwitch;
if (chswitch > 0)
fdestArr[chswitch - 1] = valist[i];
}
return 0;
}
int _dbg_pkt_realdata_get(debug_msg_info_t *msg)
{
//printf("%d:%s\n", __LINE__, __FUNCTION__);
char *pdata = NULL;
time_t now;
if (msg == NULL)
return 0;
time(&now);
debug_pkt_realdata_t realpack = {0};
realpack.proVer = 0x00000602;
realpack.utc = now - SHIQUCHA;
realpack.vbat = pwr.vbat;
realpack.vsc = pwr.vsc;
realpack.vout = pwr.vout;
//1 填写8相电流 3相电压数据
float cauValues[11] = {0};
_dbg_get_current_cau_values(cauValues);
RtdPack_t *rtd = &realpack.rtd;//实时数据
//rtd->StartFlag1 = sysVar.gateway;
rtd->RunSecCnt = now - sysctrl.start_time;
//rtd->Local_Vbat = realpack.vbat;
//rtd->RoomIn_Temp = temp2U16(envVal[0]);
rtd->RMS_Ia = cauValues[0];
rtd->RMS_Ib = cauValues[1];
rtd->RMS_Ic = cauValues[2];
rtd->RMS_In = cauValues[3];
rtd->RMS_Ground = cauValues[4];
rtd->RMS_rIa = cauValues[5];
rtd->RMS_rIb = cauValues[6];
rtd->RMS_rIc = cauValues[7];
//rtd->RoomOut_Temp = temp2U16(envVal[0]);
//rtd->I16A_Gx = (U16)(tsTag[0]+16000);
//rtd->I16A_Gy = (U16)(tsTag[1]+16000);
//rtd->I16A_Gz = (U16)(tsTag[2]+16000);
//rtd->I16A_Temp1 = temp2U16(tsTag[3]);
//rtd->I16A_Temp2 = temp2U16(tsTag[4]);
//rtd->I16B_Gx = (U16)(tsTag[5]+16000);
//rtd->I16B_Gy = (U16)(tsTag[6]+16000);
//rtd->I16B_Gz = (U16)(tsTag[7]+16000);
//rtd->I16B_Temp1 = temp2U16(tsTag[8]);
//rtd->I16B_Temp2 = temp2U16(tsTag[9]);
//rtd->I16C_Gx = (U16)(tsTag[10]+16000);
//rtd->I16C_Gy = (U16)(tsTag[11]+16000);
//rtd->I16C_Gz = (U16)(tsTag[12]+16000);
//rtd->I16C_Temp1 = temp2U16(tsTag[13]);
//rtd->I16C_Temp2 = temp2U16(tsTag[14]);
//2022-11-08 安靠智能接地箱 三相表面温度
//if(EartBoxProtocol == pConfigCtrl->gateway.CommunicationMode)
//{
// rtd->I16A_Temp2 = temperPT100[0];
// rtd->I16B_Temp2 = temperPT100[1];
// rtd->I16C_Temp2 = temperPT100[2];
//}
//rtd->RoomOut_Humidity = (U16)(envVal[1]*10);
//rtd->WaterLevel = (U16)(envVal[2]);
//rtd->Gas_O2 = (U32)envVal[3];
//rtd->Gas_CH4 = (U32)envVal[4];
//rtd->Gas_H2s = (U32)envVal[5];
//rtd->Gas_CO = (U32)envVal[6];
rtd->RMS_Va = cauValues[8];
rtd->RMS_Vb = cauValues[9];
rtd->RMS_Vc = cauValues[10];
rtd->endFlag = 0x0A0D;
/* copy data */
pdata = msg->pbuf + sizeof(debug_pkt_head_t);
memcpy(pdata, &realpack, sizeof(realpack));
_debug_pkt_common_send((char *)msg->pbuf, msg->cmd, sizeof(realpack));
return 0;
}
int _dbg_pkt_mqtt_config_get(debug_msg_info_t *msg)
{
printh("%d:%s\r\n", __LINE__, __FUNCTION__);
char *pdata = NULL;
if (msg == NULL)
{
return -1;
}
mqtt_param_t *pmqtt = &pparam_config->mqttCfg;
/* copy data */
pdata = msg->pbuf + sizeof(debug_pkt_head_t);
memcpy(pdata, pmqtt, sizeof(mqtt_param_t));
_debug_pkt_common_send((char *)msg->pbuf, msg->cmd, sizeof(mqtt_param_t));
return 0;
}
int _dbg_pkt_mqtt_config_set(debug_msg_info_t *msg)
{
printh("%d:%s\n", __LINE__, __FUNCTION__);
if (msg == NULL)
{
return -1;
}
if (msg->len != sizeof(mqtt_param_t))
{
LOG("invalid msg reallen:%d expect len:%d\n", msg->len, sizeof(mqtt_param_t));
return -1;
}
mqtt_param_t *pmqtt = &pparam_config->mqttCfg;
mqtt_param_t *pnet = (mqtt_param_t *)msg->pbuf;
memcpy(pmqtt, pnet, sizeof(mqtt_param_t));
param_save();
reboot_system(LOG_DEBUG, BOOT_LOCAL_IP_CHANGE);
//system("sync");
//sleep(3);
return 0;
}
int _dbg_pkt_auto_calibration(debug_msg_info_t *msg)
{
if (msg == NULL)
{
return -1;
}
if (msg->len != sizeof(Parameters_t))
{
printh("_dbg_pkt_auto_calibration invalid msg reallen:%d expect len:%d\n",
msg->len, sizeof(Parameters_t));
return -1;
}
printf("_dbg_pkt_auto_calibration msg reallen:%d expect len:%d\n",
msg->len, sizeof(Parameters_t));
memcpy(&cau.cali_param, msg->pbuf, msg->len);
Parameters_t *parm = &cau.cali_param;
printh("inAdjust=%d\n", parm->inAdjust);
printh("isLink=%d\n", parm->isLink);
printh("cauBoard=%d\n", parm->cauBoard);
printh("err=%d\n", parm->err);
printh("chClose:");
int i;
for (i = 0; i < 8; i++)
{
printh("%d ", parm->chClose[i]);
}
printh("\n");
printh("isVoltage=%d\n", parm->isVoltage);
printh("sample:");
for (i = 0; i < 5; i++)
{
printh("%f ", parm->sample[i]);
}
printh("\n");
printh("turns=%f\n", parm->turns); //????
cau.ismanual = 0;
cau.workstat = 0;
return 0;
}
int _dbg_pkt_manual_calibration(debug_msg_info_t *msg)
{
if (msg == NULL)
{
return -1;
}
if (msg->len != sizeof(Parameters_t))
{
printh("_dbg_pkt_manual_calibration invalid msg reallen:%d expect len:%d\n",
msg->len, sizeof(Parameters_t));
return -1;
}
printh("_dbg_pkt_manual_calibration msg reallen:%d expect len:%d\n",
msg->len, sizeof(Parameters_t));
memcpy(&cau.cali_param, msg->pbuf, msg->len);
Parameters_t *parm = &cau.cali_param;
printh("inAdjust=%d\n", parm->inAdjust);
printh("isLink=%d\n", parm->isLink);
printh("cauBoard=%d\n", parm->cauBoard);
printh("err=%d\n", parm->err);
printh("chClose:");
int i;
for (i = 0; i < 8; i++)
{
printf("%d ", parm->chClose[i]);
}
printh("\n");
printh("isVoltage=%d\n", parm->isVoltage);
printh("sample:");
for (i = 0; i < 5; i++)
{
printh("%f ", parm->sample[i]);
}
printh("\n");
printh("turns=%f\n", parm->turns); //????
if (parm->inAdjust == 1)
{
cau.ismanual = 1;
}
else
{
cau.ismanual = 0;
}
cau.workstat = 0;
return 0;
}
void _dbg_upgrade_progress_tips(int totalSize, int transSize)
{
static int per = 1;
int one_percent = totalSize / 100;
if (transSize >= totalSize)
{
per = 100;
LOG("transfer %%%d", per);
}
else if (transSize > one_percent * per)
{
if (++per > 100)
{
per = 100;
}
LOG("transfer %%%d", per);
}
}
int _dbg_pkt_upgrade_arm(debug_msg_info_t *msg)
{
static FILE *upgradefp = NULL;
static int file_len = 0;
char upgrade_file[128] = {0};
if (msg == NULL)
{
return -1;
}
if (msg->len != sizeof(updatePack_t))
{
LOG("invalid msg reallen:%d expect len:%d\n", msg->len, sizeof(updatePack_t));
return -1;
}
if (upgradefp == NULL)
{
sprintf(upgrade_file, "%s/%s", UPDATE_FILE_PATH, UPDATE_TMP_FILE_NAME);
upgradefp = fopen(upgrade_file, "wb");
if (upgradefp == NULL)
{
printh("open file error[%d]:%s", errno, strerror(errno));
return -1;
}
}
updatePack_t *ppkt = (updatePack_t *)msg->pbuf;
char *pdata = (char *)ppkt->dataArea;
int size = ppkt->currLen;
int wrlen = fwrite(pdata, 1, size, upgradefp);
if (wrlen != size)
{
size = size - wrlen;
wrlen = fwrite(pdata+wrlen, 1, size, upgradefp);
printh("write again:size=%d, wrlen=%d\n", size, wrlen);
file_len += wrlen;
}
file_len += wrlen;
_dbg_upgrade_progress_tips(ppkt->totalLen, file_len);
if (file_len == ppkt->totalLen)
{
fclose(upgradefp);
upgradefp = NULL;
unsigned int errcode = 0;
pdata = msg->pbuf + sizeof(debug_pkt_head_t);
memcpy(pdata, &errcode, sizeof(errcode));
_debug_pkt_common_send((char *)msg->pbuf, msg->cmd, sizeof(errcode));
LOG("update success!!!");
char cmd[128] = {0};
snprintf(cmd, 127, "mv %s/%s %s/%s", UPDATE_FILE_PATH, UPDATE_TMP_FILE_NAME,
UPDATE_FILE_PATH, UPDATE_FILE_NAME);
system(cmd);
system("sync");
printh("ls -l | grep update*\n");
system("ls -l | grep update*");
reboot_system(LOG_DEBUG, BOOT_LOCAL_ARM_UPGRADE);
}
return 0;
}
int _dbg_pkt_csg_mqtt_config_get(debug_msg_info_t *msg)
{
printh("%d:%s\n", __LINE__, __FUNCTION__);
//char *pdata = NULL;
if (msg == NULL)
{
return -1;
}
csgMQTTCfg_t csgmqtt = {0};
/* copy data */
//pdata = msg->pbuf + sizeof(debug_pkt_head_t);
//memcpy(pdata, pmqtt, sizeof(mqtt_param_t));
//_debug_pkt_common_send((char *)msg->pbuf, msg->cmd, sizeof(mqtt_param_t));
return 0;
}
int _dbg_pkt_csg_mqtt_config_set(debug_msg_info_t *msg)
{
printh("%d:%s\n", __LINE__, __FUNCTION__);
if (msg == NULL)
{
return -1;
}
if (msg->len != sizeof(csgMQTTCfg_t))
{
LOG("invalid msg reallen:%d expect len:%d\n", msg->len, sizeof(csgMQTTCfg_t));
return -1;
}
//mqtt_param_t *pmqtt = &pparam_config->mqttCfg;
//mqtt_param_t *pnet = (mqtt_param_t *)msg->pbuf;
//memcpy(pmqtt, pnet, sizeof(mqtt_param_t));
//param_save();
//reboot_system(LOG_DEBUG, BOOT_LOCAL_IP_CHANGE);
//system("sync");
//sleep(3);
return 0;
}
static msg_proc_t dbg_proc_table[] =
{
{DEBUG_CONFIG_GET, _dbg_pkt_config_get},
{DEBUG_CONFIG_SET, _dbg_pkt_config_set},
{DEBUG_REBOOT, _dbg_pkt_reboot_system},
{DEBUG_SET_TIME, NULL},
{DEBUG_GET_REALDATA, _dbg_pkt_realdata_get},
{DEBUG_GET_HISDATA, NULL},
{DEBUG_DAU_WAVE, NULL},
{DEBUG_CAU_WAVE, NULL},
{DEBUG_ADJUST_TASK, _dbg_pkt_auto_calibration},
{DEBUG_ADJUST_RESULT, NULL},
{DEBUG_GetHWMQTTCFG, _dbg_pkt_mqtt_config_get},
{DEBUG_SetHWMQTTCFG, _dbg_pkt_mqtt_config_set},
{DEBUG_ManualAdjust, _dbg_pkt_manual_calibration},
{DEBUG_UPGRADE_ARM, _dbg_pkt_upgrade_arm},
{DEBUG_LOAD_CSGMQTTCFG, _dbg_pkt_csg_mqtt_config_get},
{DEBUG_SAVE_CSGMQTTCFG, _dbg_pkt_csg_mqtt_config_set},
{DEBUG_INVALID, NULL}
};
/* 调试工具报文数据处理. */
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_CA_DBG, _debug_pkt_check(buf, len));
msg_proc_t *ptable = &dbg_proc_table[0];
for (; DEBUG_INVALID != head->cmd; ptable++)
{
if (head->cmd == ptable->uiMsgId)
{
//printf("cmd = 0x%x\n", head->cmd);
if (ptable->pfMsgProcFxn)
{
debug_msg_info_t msg = {0};
msg.cmd = head->cmd;
msg.len = head->len;
msg.pbuf = buf + DEBUG_PKT_DATA_POS;
ptable->pfMsgProcFxn(&msg);
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;
}
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;
struct timeval timeout;
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;
}
/* 超时时间 */
timeout.tv_sec = 10;
timeout.tv_usec = 0;
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)))
{
log_err(LOG_DEBUG, "Error setsockopt(SO_SNDTIMEO) failed, return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
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 (!is_system_init)
{
sleep(1);
}
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_CA_DBG, "Read len %d, close fd!\r\n", len);
debug_ctrl.is_manual_col = FALSE;
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, &param);
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;
/* 监听端口. */
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};
LOG("new client: %s, port: %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(buf)),
ntohs(cliaddr.sin_port));
if (debug_ctrl.fd_client < 0)
{
debug_ctrl.fd_client = connfd;
_debug_create_recv_thread();
_debug_keep_alive(debug_ctrl.fd_client);
}
else
{
LOG("There is a link trying to connect...\n");
close(connfd);
connfd = -1;
}
}
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;
}
//fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
/* 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, &param);
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);
/* 每秒上传 DAU 状态寄存器. */
//mtimer_add(_debug_port_state_get, NULL, 1, "DEBUG_PORT_STATE_GET");
return E_NONE;
}
int _debug_pkt_send_data(int cmd, char *psrc, int len)
{
char buf[10*1024] = {0};
char *pdata = NULL;
/* copy data */
pdata = buf + sizeof(debug_pkt_head_t);
memcpy(pdata, psrc, len);
int ret = _debug_pkt_common_send((char *)buf, cmd, len);
printf("ret = %d len = %d\n", ret, len);
return 0;
}