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.

1095 lines
28 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
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/prctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "fifo.h"
#include "pd_net.h"
#include "pd_dau.h"
#include "main.h"
net_t net;
void _net_server_set(int32_t ip, uint16_t port);
int _net_config_save(vty_t* vty);
void _net_sync_time_set();
void _print_sockaddr_in(const struct sockaddr_in *addr)
{
// 将IP地址从网络字节序转换为点分十进制格式
char ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr->sin_addr, ip_str, sizeof(ip_str));
// 将端口号从网络字节序转换为主机字节序并打印
unsigned short port = ntohs(addr->sin_port);
DBG(DBG_M_PD_CSG, "IP Address: %s, Port: %u\r\n", ip_str, port);
}
CMD(net_server_set,
net_server_set_cmd,
"net server A.B.C.D <1-65535>",
"Net\n"
"Server\n"
"IPv4 address\n"
"UDP port\n")
{
_net_server_set(inet_addr((char*)argv[0]), strtol((char*)argv[1], NULL, 10));
return CMD_SUCCESS;
}
/* 设置密码. */
CMD(net_passwd,
net_passwd_cmd,
"net password WORD",
"Net\n"
"Passwd\n"
"Ex: 1234\n")
{
memcpy(net.config.passwd, argv[0], 4);
return CMD_SUCCESS;
}
/* 设置校验码. */
CMD(net_verify,
net_verify_cmd,
"net verify WORD",
"Net\n"
"Verify\n"
"Ex: 1234\n")
{
memcpy(net.config.verify, argv[0], 4);
return CMD_SUCCESS;
}
CMD(net_test_day,
net_test_day_cmd,
"net test day WORD",
"Net\n"
"Test\n"
"Day\n"
"Ex: net test day 03\n")
{
net.last_sync_day = atoi( argv[0]);
printf("last_sync_day=%d\n", net.last_sync_day);
return CMD_SUCCESS;
}
CMD(net_test_month,
net_test_month_cmd,
"net test month WORD",
"Net\n"
"Test\n"
"Month\n"
"Ex: net test month 03\n")
{
net.last_sync_mon = atoi( argv[0]);
printf("last_sync_mon=%d\n", net.last_sync_mon);
return CMD_SUCCESS;
}
CMD(show_net,
show_net_cmd,
"show net",
SHOW_STR
"Displays net config\n")
{
char tmp[5];
printh("Net Connect: %s\r\n", net.is_connect ? "yes" : "no");
memcpy(tmp, net.config.passwd, 4);
tmp[4] = '\0';
printh("passwd: %s\r\n", tmp);
memcpy(tmp, net.config.verify, 4);
tmp[4] = '\0';
printh("verify: %s\r\n", tmp);
printh("heartbeat-interval: %d(min)\r\n", net.config.heartbeat_interval);
printh("collect-interval: %d(min)\r\n", net.config.collect_interval);
printh("sleep-time: %d(min)\r\n", net.config.sleep_time);
printh("online-time: %d(min)\r\n", net.config.online_time);
printh("reset-time: %d-%d-%d\r\n", net.config.reset_time.mday, net.config.reset_time.hour, net.config.reset_time.min);
printh("dev_id: %04X\r\n", device_info.dev_id);
return CMD_SUCCESS;
}
void _net_server_set(int32_t ip, uint16_t port)
{
/* 比较配置 */
if (net.server_ip != ip
|| net.server_port != port)
{
net.server_ip = ip;
net.server_port = port;
/* 发送数据. */
bzero(&net.server, sizeof(net.server));
net.server.sin_family = AF_INET;
net.server.sin_addr.s_addr = net.server_ip;
net.server.sin_port = htons(net.server_port);
}
}
/* 配置保存函数. */
int _net_config_save(vty_t* vty)
{
int16_t i = 0;
struct in_addr addr;
char tmp[128];
addr.s_addr = net.server_ip;
vty_out(vty, "net server %s %d%s", inet_ntoa(addr), net.server_port, VTY_NEWLINE);
i++;
memcpy(tmp, net.config.passwd, 4);
tmp[4] = '\0';
vty_out(vty, "net password %s%s", tmp, VTY_NEWLINE);
i++;
memcpy(tmp, net.config.verify, 4);
tmp[4] = '\0';
vty_out(vty, "net verify %s%s", tmp, VTY_NEWLINE);
i++;
return i;
}
void _net_set_system_time(net_time_t *ptime)
{
struct tm tptr = {0};
struct timeval tv = {0};
tptr.tm_year = ptime->year + 2000 - 1900;
tptr.tm_mon = ptime->month - 1;
tptr.tm_mday = ptime->day;
tptr.tm_hour = ptime->hour;
tptr.tm_min = ptime->minute;
tptr.tm_sec = ptime->second;
tv.tv_sec = mktime(&tptr);
tv.tv_usec = 0;
settimeofday(&tv, NULL);
}
void _net_get_system_time(net_time_t *ptime)
{
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
ptime->year = timeinfo->tm_year + 1900 - 2000;
ptime->month = timeinfo->tm_mon + 1;
ptime->day = timeinfo->tm_mday;
ptime->hour = timeinfo->tm_hour;
ptime->minute = timeinfo->tm_min;
ptime->second = timeinfo->tm_sec;
}
long _net_time_to_long(net_time_t *ptime)
{
struct tm timeinfo;
time_t t;
// 设置年月日时分秒
timeinfo.tm_year = ptime->year + 2000 - 1900; // 年份需要减去1900
timeinfo.tm_mon = ptime->month - 1; // 月份需要减去1因为tm_mon是从0开始计数的即0代表1月
timeinfo.tm_mday = ptime->day; // 日
timeinfo.tm_hour = ptime->hour; // 时
timeinfo.tm_min = ptime->minute; // 分
timeinfo.tm_sec = ptime->second; // 秒
timeinfo.tm_isdst = -1; // 自动判断夏令时
// 将结构体转换为time_t类型
t = mktime(&timeinfo);
return t;
}
void _net_long_to_time(uint32_t rawtime, net_time_t *ptime)
{
struct tm *timeinfo;
timeinfo = localtime((time_t *)&rawtime);
ptime->year = timeinfo->tm_year + 1900 - 2000;
ptime->month = timeinfo->tm_mon + 1;
ptime->day = timeinfo->tm_mday;
ptime->hour = timeinfo->tm_hour;
ptime->minute = timeinfo->tm_min;
ptime->second = timeinfo->tm_sec;
}
/* 包头填充. */
void _net_head_init(char *buf, uint16_t len, uint8_t cmd)
{
int slen = 0;
int i = 0;
char tmp[16] = {0};
net_pkt_head_t *head = (net_pkt_head_t*)buf;
snprintf(tmp, 16, "%04X", device_info.dev_id);
slen = strlen(tmp);
/* 封装报文头. */
head->start_code = NET_START;
head->device_id[0] = 'L';
head->device_id[1] = 'D';
head->device_id[2+i] = tmp[slen-4+i];
i++;
head->device_id[2+i] = tmp[slen-4+i];
i++;
head->device_id[2+i] = tmp[slen-4+i];
i++;
head->device_id[2+i] = tmp[slen-4+i];
head->cmd = cmd;
head->length = htons(len);
}
/* 计算校验码(累加和取反) */
uint8_t net_calc_checksum(char *pkt, int len)
{
uint8_t calc_checksum = 0;
const uint8_t* check_ptr = (uint8_t *)(pkt + 1);
size_t check_len = 6 + 1 + 2 + len;
for (int i = 0; i < check_len; i++)
{
calc_checksum += check_ptr[i];
}
calc_checksum = ~calc_checksum;
return calc_checksum;
}
void _net_send_data(char *pkt, int32_t len, uint8_t cmd)
{
int32_t rv = 0;
int32_t send_len;
uint8_t *ptail = (uint8_t *)(pkt + NET_HEADER_LEN + len);
/* 封装报文头. */
_net_head_init(pkt, len, cmd);
/* 计算校验和. */
*ptail = net_calc_checksum(pkt, len);
ptail++;
*ptail = NET_END;
send_len = len + NET_FIX_LEN;
rv = sendto(net.skfd, pkt, send_len, 0, (struct sockaddr*)&net.server, sizeof(net.server));
if (rv < 0)
{
DBG(DBG_M_PD_NET_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
}
}
// 按照原命令返回
void _net_send_data_ex(char *pkt)
{
net_pkt_head_t *head = (net_pkt_head_t*)pkt;
int send_len;
int rv;
send_len = NET_FIX_LEN + ntohs(head->length);
rv = sendto(net.skfd, pkt, send_len, 0, (struct sockaddr*)&net.server, sizeof(net.server));
if (rv < 0)
{
DBG(DBG_M_PD_NET_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
}
}
/* 校验收到包的包头, 长度, 校验码. */
int32_t _net_pkt_check(char *pkt)
{
net_pkt_head_t *head = (net_pkt_head_t*)pkt;
int datalen = 0;
uint8_t checksum = 0;
uint8_t *pcheck = NULL;
datalen = ntohs(head->length);
printf("recv:\n");
buf_print(pkt, NET_FIX_LEN + datalen);
if (pkt[0] != NET_START && pkt[NET_FIX_LEN + datalen - 1] != NET_END)
{
DBG(DBG_M_PD_NET_ERR, "expect[%d,%d], but receive[%d,%d].\r\n", NET_START, NET_END, pkt[0], pkt[NET_FIX_LEN + datalen - 1]);
return E_ERROR;
}
pcheck = (uint8_t *)(pkt + NET_HEADER_LEN + datalen);
checksum = net_calc_checksum(pkt, datalen);
if (*pcheck != checksum)
{
DBG(DBG_M_PD_NET_ERR, "checksum err %d %d\r\n", *pcheck, checksum);
return E_ERROR;
}
printf("cmd=0x%02x\n", head->cmd);
return E_NONE;
}
void _net_send_contact()
{
char *pkt = net.buf_send;
net_ver_t *pinfo = (net_ver_t *)(pkt + NET_HEADER_LEN);
pinfo->major = 0x03;
pinfo->minor = 0;
_net_send_data(pkt, sizeof(net_ver_t), CMD_CONTACT);
}
void _net_send_time_adjust()
{
char *pkt = net.buf_send;
_net_send_data(pkt, 0, CMD_TIME_ADJ);
}
void _net_send_heartbeat()
{
char *pkt = net.buf_send;
net_time_t now;
net_heartbeat_t *pinfo = (net_heartbeat_t *)(pkt + NET_HEADER_LEN);
_net_get_system_time(&now);
pinfo->signal = 88;
pinfo->vol = 68;
pinfo->time = now;
_net_send_data(pkt, sizeof(net_heartbeat_t), CMD_HEARTBEAT);
}
int _net_send_gis_data()
{
char *pkt = net.buf_send;
pd_trend_t *ptrend = &pd_data.trend;
pd_trend_data_t *pPort = NULL;
net_gis_head_t *pHead = (net_gis_head_t *)(pkt + NET_HEADER_LEN);
net_gis_data_t *pData = NULL;
uint8_t unit = 0;
uint8_t port = 0;
dau_t *dau_node = NULL;
int data_len = 0;
struct timespec ts;
uint8_t err_cnt = 0;
DBG(DBG_M_PD_NET_ERR, "fifo send\r\n");
pHead->verify[0] = net.config.verify[0];
pHead->verify[1] = net.config.verify[1];
pHead->verify[2] = net.config.verify[2];
pHead->verify[3] = net.config.verify[3];
pHead->unit = 0x46;
data_len = sizeof(net_gis_head_t);
for (unit = 0; unit < PD_DAU_SUM; unit++)
{
dau_node = dau[unit];
if (!dau_is_valid(dau_node))
{
continue;
}
pHead->pack_num = dau[unit]->port_num;
port = 0;
while (port < dau[unit]->port_num)
{
char *ppkt = NULL;
pHead->index = port;
net.trend_snd_idx = port;
if (pHead->index == 0)
{
net_time_t timer;
ppkt = pkt + NET_HEADER_LEN + data_len;
_net_long_to_time(ptrend->col.utc, &timer);
memcpy(ppkt, &timer, sizeof(net_time_t));
data_len += sizeof(net_time_t);
}
else
{
ppkt = pkt + NET_HEADER_LEN + data_len;
ppkt[0] = 0;
ppkt[1] = 0;
data_len += 2;
}
pPort = &ptrend->col.data[unit][port];
pData = (net_gis_data_t *)(pkt + NET_HEADER_LEN + data_len);
pData->discharge_type = 0;
pData->capacity = htons(0);
pData->noise = htons(pPort->noise * 1.25 * 10); // 1mv = 1.25pc
pData->avg = htons(pPort->avg * 1.25 * 10);
pData->max = htons(pPort->max * 1.25 * 10);
pData->cnt = htons(pPort->cnt);
pData->relation50 = htons(0);
pData->relation100 = htons(0);
data_len += sizeof(net_gis_data_t);
_net_send_data(pkt, data_len, CMD_GIS_DATA);
DBG(DBG_M_PD_NET_ERR, "pack_num=%d,index=%d\r\n", pHead->pack_num, pHead->index);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += NET_SEND_TIMEOUT; // 设置 3 秒超时
if (sem_timedwait(&net.trend_sem, &ts) != 0)
{
err_cnt++;
if (err_cnt >= NET_SEND_ERR_CNT)
{
//_csg_disconnect_set(__FUNCTION__);
return E_TIMEOUT;
}
DBG(DBG_M_PD_NET_ERR, "trend sem error:%s\n", strerror(errno));
continue;
}
port++;
data_len = sizeof(net_gis_head_t);
}
}
return E_NONE;
}
void _net_handle_contact(char *pkt)
{
net_pkt_head_t *head = (net_pkt_head_t*)pkt;
if (head->length == 0)
{
_net_send_contact();
}
else
{
net.is_connect = TRUE;
log_warn(LOG_NET, "NET connection OK!\n");
}
}
void _net_handle_time_adjust(char *pkt)
{
net_time_t *pinfo = (net_time_t *)(pkt + NET_HEADER_LEN);
time_t now = time(NULL);
long diff;
net.is_time_adjust = TRUE;
diff = now - _net_time_to_long(pinfo);
DBG(DBG_M_PD_NET_ERR, "diff=%ld now=%ld gettime=%ld\n", diff, now, _net_time_to_long(pinfo));
if (abs(now - _net_time_to_long(pinfo)) > NET_ADJUST_TIMEOUT)
{
_net_set_system_time(pinfo);
}
_net_sync_time_set();
_net_send_data_ex(pkt);
}
void _net_handle_set_passwd(char *pkt)
{
net_passwd_t *pinfo = (net_passwd_t *)(pkt + NET_HEADER_LEN);
if (0 == memcmp(pinfo->old, net.config.passwd, 4))
{
memcpy(net.config.passwd, pinfo->new, 4);
_net_send_data_ex(pkt);
vtysh_config_save();
}
else
{
uint16_t *err_code = (uint16_t *)(pkt + NET_HEADER_LEN);
*err_code = 0xFFFF;
_net_send_data(pkt, 2, CMD_SET_PW);
}
}
void _net_handle_set_param(char *pkt)
{
net_config_t *pinfo = (net_config_t *)(pkt + NET_HEADER_LEN);
if (memcmp(pinfo->passwd, net.config.passwd, sizeof(pinfo->passwd)) == 0)
{
net.config.heartbeat_interval = pinfo->heartbeat_interval;
net.config.collect_interval = ntohs(pinfo->collect_interval);
net.config.sleep_time = ntohs(pinfo->sleep_time);
net.config.online_time = ntohs(pinfo->online_time);
memcpy(&net.config.reset_time, &pinfo->reset_time, 3);
memcpy(net.config.verify, pinfo->verify, 4);
_net_send_data_ex(pkt);
vtysh_config_save();
}
else
{
uint16_t *err_code = (uint16_t *)(pkt + NET_HEADER_LEN);
*err_code = 0xFFFF;
_net_send_data(pkt, 2, CMD_SET_PARMA);
}
}
void _net_handle_heartbeat(char *pkt)
{
// do nothing
}
void _net_handle_reset(char *pkt)
{
char *pinfo = pkt + NET_HEADER_LEN;
if (memcmp(pinfo, net.config.passwd, 4) == 0)
{
_net_send_data_ex(pkt);
sleep(3);
reboot_system(LOG_NET, REBOOT_REMOTE_RESET);
}
else
{
uint16_t *err_code = (uint16_t *)(pkt + NET_HEADER_LEN);
*err_code = 0xFFFF;
_net_send_data(pkt, 2, CMD_RESET);
}
}
void _net_handle_gis_data(char *pkt)
{
net_pkt_head_t *head = (net_pkt_head_t*)pkt;
net_gis_reply_t *preply = (net_gis_reply_t *)(pkt + NET_HEADER_LEN);
if (head->length != 0)
{
if (ntohs(head->length) != sizeof(net_gis_reply_t))
{
return ;
}
if (ntohs(preply->fix) != 0xAA55)
{
return ;
}
if (net.trend_snd_idx == preply->index)
{
sem_post(&net.trend_sem);
}
}
else
{
// 平台主动请求,无数据
_net_send_data_ex(pkt);
}
}
#if 0
void _net_handle_gis_data(char *pkt)
{
net_pkt_head_t *head = (net_pkt_head_t*)pkt;
pd_trend_t *ptrend = &pd_data.trend;
pd_trend_data_t *pPort = NULL;
net_gis_head_t *pHead = (net_gis_head_t *)(pkt + NET_HEADER_LEN);
net_gis_data_t *pData = NULL;
uint8_t unit = 0;
uint8_t port = 0;
dau_t *dau_node = NULL;
int send_len = 0;
if (head->length != 0)
{
if (ntohs(head->length) != sizeof(net_gis_reply_t))
{
return ;
}
}
pHead->verify[0] = net.config.verify[0];
pHead->verify[1] = net.config.verify[1];
pHead->verify[2] = net.config.verify[2];
pHead->verify[3] = net.config.verify[3];
pHead->identify = 0;
pHead->pack_num = 1;
pHead->unit = 0x46;
_net_long_to_time(ptrend->col.utc, &pHead->time);
for (unit = 0; unit < PD_DAU_SUM; unit++)
{
dau_node = dau[unit];
if (!dau_is_valid(dau_node))
{
continue;
}
for(port = 0; port < dau[unit]->port_num; port++)
{
send_len = sizeof(net_gis_head_t);
pPort = &ptrend->col.data[unit][port];
pData = (net_gis_data_t *)(pkt + NET_HEADER_LEN + send_len);
pData->discharge_type = 0;
pData->capacity = htons(0);
pData->noise = htons(pPort->noise * 1.25 * 10); // 1mv = 1.25pc
pData->avg = htons(pPort->avg * 1.25 * 10);
pData->max = htons(pPort->max * 1.25 * 10);
pData->cnt = htons(pPort->cnt);
pData->relation50 = htons(0);
pData->relation100 = htons(0);
send_len += sizeof(net_gis_data_t);
_net_send_data(pkt, send_len, CMD_GIS_DATA);
}
}
}
#endif
// 命令映射表
static command_entry command_table[] =
{
{CMD_CONTACT, _net_handle_contact},
{CMD_TIME_ADJ, _net_handle_time_adjust},
{CMD_SET_PW, _net_handle_set_passwd},
{CMD_SET_PARMA, _net_handle_set_param},
{CMD_HEARTBEAT, _net_handle_heartbeat},
{CMD_RESET, _net_handle_reset},
{CMD_GIS_DATA, _net_handle_gis_data},
{CMD_INVALID, NULL}
};
command_handler _net_get_table_handle(command_entry *ptable, command_type cmd)
{
if (NULL == ptable)
{
return NULL;
}
for (;CMD_INVALID != ptable->cmd; ptable++)
{
if (cmd == ptable->cmd)
{
return ptable->handler;
}
}
return ptable->handler;
}
int32_t _net_recv_process(char *pkt, uint32_t len)
{
net_pkt_head_t *head = (net_pkt_head_t *)pkt;
command_handler handle = NULL;
/* 报文头和 CRC 校验. */
LD_E_RETURN(DBG_M_PD_NET_ERR, _net_pkt_check(pkt));
net.heartbeat_timeout = time(NULL);
net.heartbeat_timeout_cnt = 0;
handle = _net_get_table_handle(command_table, head->cmd);
if (handle)
{
handle(pkt);
}
return E_NONE;
}
/* 平台连接处理函数. */
void *_net_recv_handle(void *arg)
{
struct sockaddr_in server;
socklen_t server_len;
int32_t addr = 0;
uint16_t data_len = 0;
net.heartbeat_timeout = time(NULL);
/* 等待初始化完成 */
while(!is_system_init)
{
usleep(100000);
}
prctl(PR_SET_NAME, "NET_RCVE", 0, 0, 0);
while(1)
{
/* 读取数据. */
printf("recv:\n");
_print_sockaddr_in(&server);
data_len = recvfrom(net.skfd, net.buf_recv, NET_PKT_LEN, 0, (struct sockaddr*)&server, &server_len);
if (data_len <= 0)
{
DBG(DBG_M_PD_NET_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno));
continue;
}
_print_sockaddr_in(&server);
addr = server.sin_addr.s_addr;
if (addr != net.server_ip)
{
continue;
}
_net_recv_process(net.buf_recv, data_len);
}
return NULL;
}
void _net_sync_time_set()
{
time_t now;
struct tm *local_time;
// 获取当前时间戳
time(&now);
// 转换为本地时间结构体
local_time = localtime(&now);
net.last_sync_day = local_time->tm_yday;
net.last_sync_mon = local_time->tm_mon;
DBG(DBG_M_PD_NET_ERR, "last_sync_day=%d tm_yday=%d \n", net.last_sync_day, local_time->tm_yday);
}
int _net_sync_time_check()
{
time_t now;
struct tm *local_time;
int res;
// 获取当前时间戳
time(&now);
// 转换为本地时间结构体
local_time = localtime(&now);
if (net.config.reset_time.mday == 0)
{
res = (local_time->tm_min == net.config.reset_time.min
&& local_time->tm_hour == net.config.reset_time.hour
&& local_time->tm_yday != net.last_sync_day);
}
else
{
res = (local_time->tm_min == net.config.reset_time.min
&& local_time->tm_hour == net.config.reset_time.hour
&& local_time->tm_mday == net.config.reset_time.mday
&& local_time->tm_mon != net.last_sync_mon);
}
#if 0
printf("res=%d\n", res);
printf("day hour min\n");
printf("%d %d %d\n", local_time->tm_mday, local_time->tm_hour, local_time->tm_min);
printf("%d %d %d\n", net.config.reset_time.mday, net.config.reset_time.hour, net.config.reset_time.min);
printf("tm_yday=%d last_sync_day=%d tm_mon=%d last_sync_mon=%d\n",
local_time->tm_yday, net.last_sync_day, local_time->tm_mon, net.last_sync_mon);
#endif
return res;
}
void _net_restart_4g()
{
}
/* 心跳和连接处理函数. */
void *_net_heartbeat_handle(void *arg)
{
time_t now = 0;
time_t t_connect = 0;
time_t t_adjust = 0;
time_t t_heartbeat = 0;
int connect_cnt = 0;
prctl(PR_SET_NAME, "NET_HEARTBEAT", 0, 0, 0);
/* 等待初始化完成 */
while(!is_system_init)
{
usleep(100000);
}
while(1)
{
usleep(1000000);
now = time(NULL);
/* 发送连接报文. */
if (!pd_state.is_4G_connect)
continue;
if (!net.is_connect)
{
if (now - t_connect >= NET_CONTACT_TIME)
{
_net_send_contact();
t_connect = now;
connect_cnt++;
if (connect_cnt >= NET_CONNECT_TIME_CNT)
{
reboot_system(LOG_NET, REBOOT_NET_ERROR);
}
}
continue;
}
connect_cnt = 0;
if (!net.is_time_adjust)
{
if (now - t_adjust >= NET_ADJUST_TIME)
{
_net_send_time_adjust();
t_adjust = now;
}
}
if (_net_sync_time_check())
{
net.is_time_adjust = FALSE;
}
/* 发送心跳包. */
if (now - t_heartbeat >= pd_config.config.heartbeat_period * 60)
{
_net_send_heartbeat();
t_heartbeat = now;
net.heartbeat_timeout_cnt++;
if (net.heartbeat_timeout_cnt > 3)
{
net.heartbeat_timeout_cnt = 0;
net.is_connect = FALSE;
}
}
}
return NULL;
}
void *_net_trend_handle(void *arg)
{
pd_csg_msg_t *recv_msg = NULL;
prctl(PR_SET_NAME, "NET_TREND", 0, 0, 0);
/* 等待初始化完成 */
while(!is_system_init)
{
usleep(100000);
}
while (1)
{
if (fifo_read(net.fifo_trend_id, (void**)&recv_msg) != 0)
{
DBG(DBG_M_PD_NET_ERR, "ERROR at fifo %d read!\r\n", net.fifo_trend_id);
continue;
}
if (net.is_connect)
{
_net_send_gis_data();
}
/* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */
XFREE(MTYPE_CSG, recv_msg->data);
fifo_push(net.fifo_trend_id);
}
return NULL;
}
void *_net_event_handle(void *arg)
{
pd_csg_msg_t *recv_msg = NULL;
prctl(PR_SET_NAME, "NET_EVENT", 0, 0, 0);
/* 等待初始化完成 */
while(!is_system_init)
{
usleep(100000);
}
while (1)
{
if (fifo_read(net.fifo_event_id, (void**)&recv_msg) != 0)
{
DBG(DBG_M_PD_NET_ERR, "ERROR at fifo %d read!\r\n", net.fifo_event_id);
continue;
}
/* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */
XFREE(MTYPE_CSG, recv_msg->data);
fifo_push(net.fifo_event_id);
}
return NULL;
}
void *_net_realtime_prps_handle(void *arg)
{
pd_csg_msg_t *recv_msg = NULL;
prctl(PR_SET_NAME, "NET_RT_PRPS", 0, 0, 0);
/* 等待初始化完成 */
while(!is_system_init)
{
usleep(100000);
}
while (1)
{
if (fifo_read(net.fifo_prps_id, (void**)&recv_msg) != 0)
{
DBG(DBG_M_PD_NET_ERR, "ERROR at fifo %d read!\r\n", net.fifo_prps_id);
continue;
}
/* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */
XFREE(MTYPE_CSG, recv_msg->data);
fifo_push(net.fifo_prps_id);
usleep(10000);
}
return NULL;
}
/* 后台通讯公共部分初始化. */
int32_t _net_handle_init_common(void)
{
struct sockaddr_in server;
int fd = 0;
thread_param_t param = {0};
/* 创建协议 socket. */
if (0 == net.skfd)
{
/* 创建socket */
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
log_err(LOG_NET, "ERROR at socket create return %s!", safe_strerror(errno));
return E_SYS_CALL;
}
/* 绑定端口 */
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(7777);
if(bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
{
log_err(LOG_NET, "ERROR at socket bind return %s!", safe_strerror(errno));
close(fd);
return E_SYS_CALL;
}
/* 保存数据. */
net.skfd = fd;
}
net.fifo_prps_id = fifo_create(NET_FIFO_PRPS, PRPS_FIFO_NUM);
if (net.fifo_prps_id < 0)
{
log_err(LOG_NET, "Open fifo " NET_FIFO_PRPS " error!");
return E_ERROR;
}
net.fifo_event_id = fifo_create(NET_FIFO_EVENT, EVENT_FIFO_NUM);
if (net.fifo_event_id < 0)
{
log_err(LOG_NET, "Open fifo " NET_FIFO_EVENT " error!");
return E_ERROR;
}
net.fifo_trend_id = fifo_create(NET_FIFO_TREND, TREND_FIFO_NUM);
if (net.fifo_trend_id < 0)
{
log_err(LOG_NET, "Open fifo " NET_FIFO_TREND " error!");
return E_ERROR;
}
sem_init(&net.trend_sem, 0, 0);
param.arg = NULL;
param.log_module = LOG_NET;
param.priority = 70;
param.thread_name = "NET_RCVE";
create_thread(_net_recv_handle, &param);
param.priority = 70;
param.thread_name = "NET_HEARTBEAT";
create_thread(_net_heartbeat_handle, &param);
param.priority = 40;
param.thread_name = "NET_RT_PRPS";
create_thread(_net_realtime_prps_handle, &param);
param.priority = 35;
param.thread_name = "NET_EVENT";
create_thread(_net_event_handle, &param);
param.priority = 30;
param.thread_name = "NET_TREND";
create_thread(_net_trend_handle, &param);
return E_NONE;
}
/* Interface functions -------------------------------------------------------*/
/* 后台通讯模块预初始化. */
int32_t net_handle_init(void)
{
int32_t rv = 0;
memset(&net, 0, sizeof(net));
net.fifo_prps_id = E_MEM;
net.fifo_event_id = E_MEM;
net.fifo_trend_id = E_MEM;
/* 发送数据. */
net.server_ip = inet_addr("192.168.1.161");
net.server_port = 1885;
bzero(&net.server, sizeof(net.server));
net.server.sin_family = AF_INET;
net.server.sin_addr.s_addr = net.server_ip;
net.server.sin_port = htons(net.server_port);
memcpy(net.config.passwd, "1234", 4);
memcpy(net.config.verify, "1234", 4);
net.config.heartbeat_interval = 1;
net.config.collect_interval = 20;
net.config.sleep_time = 0;
net.config.online_time = 0;
net.config.reset_time.mday = 0;
net.config.reset_time.hour = 23;
net.config.reset_time.min = 59;
cmd_install_element(CONFIG_NODE, &net_server_set_cmd);
cmd_install_element(CONFIG_NODE, &net_passwd_cmd);
cmd_install_element(CONFIG_NODE, &net_verify_cmd);
cmd_install_element(COMMON_NODE, &net_test_day_cmd);
cmd_install_element(COMMON_NODE, &net_test_month_cmd);
cmd_install_element(COMMON_NODE, &show_net_cmd);
/* 注册配置保存函数 */
rv = cmd_config_node_config_register(CONFIG_PRI_NET, _net_config_save);
if (rv != E_NONE)
{
log_err(LOG_NET, "Command save register ERROR %d!", rv);
return rv;
}
return E_NONE;
}
/* 南网后台通讯模块初始化. */
int32_t net_handle_init_after(void)
{
/* 初始化模块. */
if (pd_config.config.protocol_type == PD_PROTOCOL_CSG)
{
LD_E_RETURN(DBG_M_PD_NET_ERR, _net_handle_init_common());
}
return E_NONE;
}
#endif