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.

921 lines
27 KiB
C

/* 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);
}
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 = 0x0C02;//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 = 0x0C02;//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;
}