/****************************************************************************** * file lib/process/pd_csg.c * author YuLiang * version 1.0.0 * date 27-Feb-2023 * brief This file provides all the csg server operation functions. * ****************************************************************************** * Attention * *

© COPYRIGHT(c) 2021 LandPower

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of LandPower nor the names of its contributors may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef CFG_DEV_TYPE_LAND_PD /* 标准C库头文件. */ #include #include #include #include #include #include #include #include #include /* 用户代码头文件. */ #include "cmd.h" #include "fifo.h" #include "pd_main.h" #include "pd_dau.h" #include "pd_csg.h" /* Private define ------------------------------------------------------------*/ #define CSG_LOCK pthread_mutex_lock(&csg.mutex) #define CSG_UNLOCK pthread_mutex_unlock(&csg.mutex) /* Private macro -------------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ csg_t csg; /* Private function prototypes -----------------------------------------------*/ extern void _csg_server_set(int32_t ip, uint16_t port); /* Internal functions --------------------------------------------------------*/ CMD(csg_server_set, csg_server_set_cmd, "csg server A.B.C.D <1-65535>", "Csg\n" "Server\n" "IPv4 address\n" "UDP port\n") { return CMD_SUCCESS; _csg_server_set(inet_addr((char*)argv[0]), strtol((char*)argv[1], NULL, 10)); return CMD_SUCCESS; } void _csg_server_set(int32_t ip, uint16_t port) { /* 比较配置 */ if (csg.server_ip != ip || csg.server_port != port) { csg.server_ip = ip; csg.server_port = port; /* 发送数据. */ bzero(&csg.server, sizeof(csg.server)); csg.server.sin_family = AF_INET; csg.server.sin_addr.s_addr = csg.server_ip; csg.server.sin_port = htons(csg.server_port); } } /* 配置保存函数. */ int _csg_config_save(vty_t* vty) { int16_t i = 0; struct in_addr addr; addr.s_addr = csg.server_ip; vty_out(vty, "csg server %s %d%s", inet_ntoa(addr), csg.server_port, VTY_NEWLINE); i++; return i; } /* 校验收到包的包头, 长度, 校验码. */ int32_t _csg_pkt_check(char *pkt, int32_t len) { csg_pkt_head_t *head = (csg_pkt_head_t*)pkt; csg_pkt_tail_t *tail = (csg_pkt_tail_t*)(pkt + len - CSG_TAIL_LEN); uint16_t checksum = 0; uint16_t i = 0; if (head->head != 0x55aa) { DBG(DBG_M_PD_CSG_ERR, "Pkt head %x error!\r\n", head->head); return E_ERROR; } if( tail->tail != 0x5a5a) { DBG(DBG_M_PD_CSG_ERR, "Pkt tail %x error!\r\n", tail->tail); return E_ERROR; } if (head->len != (len - CSG_TOTLE_LEN)) { DBG(DBG_M_PD_CSG_ERR, "Pkt len %d(%d) error!\r\n", len - CSG_TOTLE_LEN, head->len); return E_ERROR; } for (i = CSG_HEAD_LEN; i < len - CSG_TAIL_LEN; i++) { checksum += (uint8_t)pkt[i]; } if (checksum != tail->checksum) { DBG(DBG_M_PD_CSG_ERR, "Pkt checksum %x(%x) error!\r\n", checksum, tail->checksum); return E_ERROR; } return E_NONE; } /* 包头填充. */ void _csg_head_init(char *buf, uint16_t cmd, uint16_t len) { csg_pkt_head_t *head = (csg_pkt_head_t*)buf; memset(buf, 0, len + CSG_HEAD_LEN); head->head = 0x55AA; head->cmd = cmd; snprintf((char*)head->dev_num, PD_DEV_NUM_LEN, "%s", host.name); head->len = len; } void _csg_cheaksum(char *buf, uint16_t len) { char *data = buf + CSG_HEAD_LEN; csg_pkt_tail_t *tail = (csg_pkt_tail_t*)(data + len); uint16_t i = 0; uint16_t checksum = 0; for(i = 0; i < len; i++) { checksum += (uint8_t)data[i]; } tail->checksum = checksum; tail->tail = 0x5a5a; } /* 主动连接请求. */ int32_t _csg_connect_send(void) { char *pkt = csg.buf_reply; uint16_t *data = (uint16_t*)(pkt + CSG_HEAD_LEN); int32_t rv = 0; uint16_t len = 8; _csg_head_init(pkt, CSG_CONNECT_REQ, len); *data = sofrware_version_get(); _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } return E_NONE; } /* 心跳包. */ int32_t _csg_heartbeat_send(void) { char *pkt = csg.buf_reply; csg_pkt_heartbeat_t *data = (csg_pkt_heartbeat_t*)(pkt + CSG_HEAD_LEN); int32_t rv = 0; uint16_t len = sizeof(csg_pkt_heartbeat_t); uint16_t i = 0; _csg_head_init(pkt, CSG_HEARTBEAT_REQ, len); data->heartbeat = csg.heartbeat; data->utc = time(NULL) - CSG_SHIQUCHA; data->freq = 50; for(i = 0; i < PD_DAU_SUM; i++) { if (dau[i]) { data->dau_state[i] = dau[i]->is_connect; } else { data->dau_state[i] = 0; } } data->out_sync = 0; data->pt_sync = 0; data->in_sync = 0; if (dau[0]) { if (pd_state.sync) { if (PD_SYNC_PT == pd_config.config.sync_mode) { data->pt_sync = 1; } else if (PD_SYNC_POWER == pd_config.config.sync_mode) { data->in_sync = 1; } else if (PD_SYNC_OUTSIDE == pd_config.config.sync_mode) { data->out_sync = 1; } } } for(i = 0; i < PD_PORT_SUM; i++) { data->port_link_alarm[i] = 0; } _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } csg.heartbeat++; if (csg.heartbeat > 3) { csg.is_connect = FALSE; } return E_NONE; } //反馈设置状态的公共函数 2Byte int32_t _csg_set_state_send(char *pkt, uint16_t cmd, uint8_t vport, uint16_t state) { uint16_t *data = (uint16_t*)(pkt + CSG_HEAD_LEN); int32_t rv = 0; uint16_t len = 4; _csg_head_init(pkt, cmd, len); *data = state; data++; *data = vport; _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } return E_NONE; } /* 主动提交实时图谱. */ int32_t _csg_real_image_send(pd_prps_t *data) { char *buf = csg.buf_send; csg_real_image_t *head = (csg_real_image_t*)(buf + CSG_HEAD_LEN); pd_prps_data_t *data_port = NULL; int32_t rv = 0; uint16_t len = sizeof(csg_real_image_t) + 1280; uint8_t i = 0; uint8_t unit = 0; uint8_t port = 0; _csg_head_init(buf, CSG_REAL_IMAGE_ACK, len); for(unit = 0; unit < PD_DAU_SUM; unit++) { if (!dau[unit]) { continue; } for(port = 0; port < dau[unit]->port_num; port++) { if (!pd_config.port_config[unit][port].is_concern || !data->data[unit][port].is_valid) { continue; } data_port = &data->data[unit][port]; head->index = csg.pkt_index++; head->vport = dau_port_to_vport(unit, port); head->pkt_sum = 10; head->max = data_port->max; head->avg = data_port->avg; head->cnt = data_port->cnt; head->is_sub = 0; head->interval = 0; head->utc = time(NULL) - CSG_SHIQUCHA - CSG_SHIQUCHA; for (i = 0; i < 10; i++) { head->pkt_index = i; memcpy(buf + CSG_HEAD_LEN + sizeof(csg_real_image_t), data_port->data + 640 * i, 1280); _csg_cheaksum(buf, len); rv = sendto(csg.fd, buf, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); } } } } return E_NONE; } /* 趋势数据发送. */ int32_t _csg_trend_send(pd_trend_t *data) { char *buf = csg.buf_send; csg_trend_head_t *head = (csg_trend_head_t*)(buf + CSG_HEAD_LEN); csg_trend_t *trend = NULL; pd_trend_data_t *data_port = NULL; int32_t rv = 0; int32_t vport = 0; uint16_t len = sizeof(csg_trend_head_t); uint8_t unit = 0; uint8_t port = 0; _csg_head_init(buf, CSG_TREND_ACK, len); head->idx = data->index; head->is_sub = 0; head->interval = pd_config.config.trend_period; head->utc = data->utc - CSG_SHIQUCHA - CSG_SHIQUCHA; for(unit = 0; unit < PD_DAU_SUM; unit++) { if (!dau[unit]) { continue; } for(port = 0; port < dau[unit]->port_num; port++) { vport = dau_port_to_vport(unit, port); if (vport <= 0) { continue; } trend = &head->data[vport - 1]; data_port = &data->data[unit][port]; trend->is_valid = 1; trend->max = data_port->max; trend->avg = data_port->avg; trend->noise = data_port->noise; trend->cnt = data_port->cnt; trend->phase = data_port->phase; trend->event_cnt = data_port->event_cnt; } } _csg_cheaksum(buf, len); rv = sendto(csg.fd, buf, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_ERROR; } return E_NONE; } //按通道主动提交事件数据 int32_t _csg_event_send(pd_event_t *data) { char *buf = csg.buf_send; csg_event_head_t *head = (csg_event_head_t*)(buf + CSG_HEAD_LEN); int32_t rv = 0; uint16_t len = sizeof(csg_event_head_t) + 1280; uint8_t i = 0; _csg_head_init(buf, CSG_EVENT_REQ, len); head->idx = csg.pkt_index++; head->vport = data->vport; head->pkt_sum = 10; head->type = data->type; head->max = data->max; head->level = data->level; head->pd_Type = data->type; for(i = 0;i < 8; i++) { head->type_per[i] = data->type_per[i]; } head->PositionDistance = data->PositionDistance; head->utc = data->utc - CSG_SHIQUCHA - CSG_SHIQUCHA; head->event_idx = data->index; head->cnt = data->cnt; for (i = 0; i < 10; i++) { head->pkt_idx = i; memcpy(buf + CSG_HEAD_LEN + sizeof(csg_event_head_t), data->data + 640 * i, 1280); _csg_cheaksum(buf, len); rv = sendto(csg.fd, buf, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); } } return E_NONE; } void _csg_connect_recv(void) { csg.is_connect = TRUE; csg.heartbeat = 0; } /* 解析心跳报文. */ void _csg_heartbeat_recv(char *pkt) { csg.heartbeat = 0; uint32_t server_time = *(uint32_t*)(pkt + CSG_HEAD_LEN); server_time += CSG_SHIQUCHA; if (abs(server_time - time(NULL)) > 10) { time_set(server_time + 28800); //北京时间 } } /* 主动连接请求. */ int32_t _csg_acitve_connect_recv(char *pkt) { uint16_t *data = (uint16_t*)(pkt + CSG_HEAD_LEN); int32_t rv = 0; uint16_t len = 8; _csg_head_init(pkt, CSG_CONNECT_REQ, len); *data = sofrware_version_get(); _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } csg.is_connect = TRUE; csg.heartbeat = 0; return E_NONE; } /* 设备重启报文. */ void _csg_reboot_recv(char *pkt) { reboot_system(DBG_M_PD_CSG, BOOT_REMOTE_RESET); } /* 厂家参数设置报文处理. 说明:修改本地ip 设备ID 服务器地址时需要重启。 */ int32_t _csg_factory_set_recv(char *pkt) { struct sockaddr_in server; pd_factory_old_t *factory = &pd_config.factory; uint8_t unit = 0; uint8_t port = 0; int32_t vport = 0; int need_save = 0; int change_ip = 0; BOOT_MSG boottype = BOOT_NONE; memcpy(factory, pkt + CSG_HEAD_LEN, sizeof(pd_factory_old_t) - 24); if (strncmp((char *)(factory->dev_num), host.name, sizeof(host.name))) { snprintf((char*)host.name, PD_DEV_NUM_LEN, "%s", factory->dev_num); need_save++; boottype = BOOT_REMOTE_HOST_NAME_CHANGE; } if (0 == strncmp((char*)factory->dev_type, "GOM5010", 7)) { device_info.id_major = 5010; } device_info.factory_date = factory->factory_date; device_info.deployment_date = factory->deployment_date; server.sin_addr.s_addr = factory->ipv4; if (strncmp(device_info.host_ip, inet_ntoa(server.sin_addr), sizeof(device_info.host_ip))) { snprintf((char*)device_info.host_ip, INET_ADDRSTRLEN, "%s", inet_ntoa(server.sin_addr)); need_save++; change_ip++; boottype = BOOT_REMOTE_IP_CHANGE; } memcpy(device_info.mac, factory->mac, MAC_ADDR_LEN); if (csg.server_ip != factory->server_ipv4) { csg.server_ip = factory->server_ipv4; need_save++; boottype = BOOT_REMOTE_SERVER_IP_CHANGE; } if (csg.server_port != factory->server_port) { csg.server_port = factory->server_port; need_save++; boottype = BOOT_REMOTE_SERVER_PORT_CHANGE; } for(unit = 0; unit < PD_DAU_SUM; unit++) { if (!dau[unit]) { continue; } for(port = 0; port < dau[unit]->port_num; port++) { vport = dau_port_to_vport(unit, port); if (vport <= 0) { continue; } dau_port_type_set(unit, port, factory->port_type[vport - 1]); dau_reg_port_write(unit, port); need_save++; // save file } } _csg_set_state_send(pkt, CSG_FACTORY_SET_ACK, 0, 1); if (need_save) { vtysh_config_save(); if (change_ip) { uint8_t mac[MAC_ADDR_LEN] = {0}; mac_generate_from_ip(device_info.host_ip, mac); memcpy(device_info.mac, mac, MAC_ADDR_LEN); vtysh_device_save(); vtysh_eth0_save(); } } if (boottype) { reboot_system(DBG_M_PD_CSG, boottype); } return 0; } /* 厂家参数查询报文处理. */ int32_t _csg_factory_get_recv(char *pkt) { pd_factory_old_t *factory = &pd_config.factory; uint16_t len = sizeof(pd_factory_old_t); uint8_t unit = 0; uint8_t port = 0; int32_t vport = 0; int32_t rv = 0; _csg_head_init(pkt, CSG_FACTORY_GET_ACK, len); snprintf((char*)factory->dev_num, PD_DEV_NUM_LEN, "%s", host.name); snprintf((char*)factory->dev_type, PD_DEV_TYPE_LEN, "GOM%d", device_info.id_major); factory->factory_date = device_info.factory_date; factory->deployment_date = device_info.deployment_date; factory->ipv4 = inet_addr((char*)device_info.host_ip); memcpy(factory->mac, device_info.mac, MAC_ADDR_LEN); factory->server_ipv4 = csg.server_ip; factory->server_port = csg.server_port; for(unit = 0; unit < PD_DAU_SUM; unit++) { if (!dau[unit]) { continue; } for(port = 0; port < dau[unit]->port_num; port++) { vport = dau_port_to_vport(unit, port); if (vport <= 0) { continue; } factory->port_type[vport - 1] = (dau[unit]->port_reg[port].CR & DAU_CR_PT_Msk) >> DAU_CR_PT_Pos; } } memcpy(pkt + CSG_HEAD_LEN, factory, len); _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } return E_NONE; } /* 配置用户参数报文报文处理. */ int32_t _csg_config_set_recv(char *pkt) { int need_save = 0; int cpld_save = 0; pd_config_old_t *pnet = (pd_config_old_t *)(pkt + CSG_HEAD_LEN); if ((pd_config.config.sync_mode != pnet->sync_mode) || (pd_config.config.real_period != pnet->real_period) || (pd_config.config.trend_period != pnet->trend_period) || (pd_config.config.heartbeat_period != pnet->heartbeat_period)) { need_save++; } if (pd_config.config.sync_mode != pnet->sync_mode) { cpld_save++; } memcpy(&pd_config.config, pkt + CSG_HEAD_LEN, sizeof(pd_config_old_t)); if (need_save) { vtysh_config_save(); } if (cpld_save) { pd_sync_mode_set(); } return _csg_set_state_send(pkt, CSG_CONFIG_SET_ACK, 0, 1); } /* 查询用户参数查询报文处理. */ int32_t _csg_config_get_recv(char *pkt) { uint16_t len = sizeof(pd_config_old_t); int32_t rv = 0; _csg_head_init(pkt, CSG_CONFIG_GET_ACK, len); memcpy(pkt + CSG_HEAD_LEN, &pd_config.config, len); _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } return E_NONE; } /* 通道提交端口参数设置. */ int32_t _csg_port_config_set_recv(char *pkt) { uint8_t vport = *(uint8_t*)(pkt + CSG_HEAD_LEN); uint8_t unit = 0; uint8_t port = 0; if (dau_vport_to_port(vport, &unit, &port) != E_NONE) { DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", vport); return _csg_set_state_send(pkt, CSG_PORT_CONFIG_SET_ACK, vport, 0); } memcpy(&pd_config.port_config[unit][port].config, pkt + CSG_HEAD_LEN, sizeof(pd_port_config_old_t)); pd_config.port_config[unit][port].filter_cfg = pd_config.port_config[unit][port].config.filter; dau_port_config_set(unit, port); dau_reg_port_write(unit, port); vtysh_config_save(); return _csg_set_state_send(pkt, CSG_PORT_CONFIG_SET_ACK, vport, 1); } /* 按通道提交端口参数查询结果. */ int32_t _csg_port_config_get_recv(char *pkt) { uint8_t vport = *(uint8_t*)(pkt + CSG_HEAD_LEN); uint16_t len = sizeof(pd_port_config_old_t); uint8_t unit = 0; uint8_t port = 0; int32_t rv = 0; if (dau_vport_to_port(vport, &unit, &port) != E_NONE) { DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", vport); return E_ERROR; } _csg_head_init(pkt, CSG_PORT_CONFIG_GET_ACK, len); memcpy(pkt + CSG_HEAD_LEN, &pd_config.port_config[unit][port].config, len); _csg_cheaksum(pkt, len); rv = sendto(csg.fd, pkt, len + CSG_TOTLE_LEN, 0, (struct sockaddr*)&csg.server, sizeof(csg.server)); if (rv < 0) { DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno)); return E_SYS_CALL; } return E_NONE; } /* 召唤趋势数据. */ int32_t _csg_trend_get_recv(char *pkt) { #if 0 uint32_t time_start = *(uint32_t*)pkt; uint32_t time_end = *(uint32_t*)(pkt+4); struct tm *lt = localtime(&time_start); char basePath[256] = {0}; sprintf(basePath,"%s/%s/%d/%02d/",fixedHead,"Trend",lt->tm_year+1900,lt->tm_mon+1); img_num=0; if(!readFileList(basePath))LOG_ERR_RETURN int i = 0,fLen = 0; for(i = 0;i < img_num;i ++) { int fileUtc = getUctByFileName(img_path[i]); if(fileUtc >= startTime && fileUtc <= stopTime) { U8 *pFile = NULL; fLen = ReadHexFile(img_path[i],&pFile); if(fLen < sizeof(strTrendData))continue; csgAutoPostHufTrend((strTrendData *)pFile,true); } } #endif return E_NONE; } /* 解析HUF实时图谱召唤报文. */ void _csg_real_image_recv(char *pkt) { csg_real_image_get_t *data = (csg_real_image_get_t*)(pkt + CSG_HEAD_LEN); uint8_t unit = 0; uint8_t port = 0; if (dau_vport_to_port(data->vport, &unit, &port) != E_NONE) { DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", data->vport); return; } pd_config.port_config[unit][port].r_noise_reduction = data->r_noise_reduction; pd_config.port_config[unit][port].auto_noise_reduction = data->auto_noise_reduction; pd_config.port_config[unit][port].manual_noise_reduction = data->manual_noise_reduction * 10; pd_config.port_config[unit][port].is_concern = data->is_concern; if (data->is_concern) { BITMAP_SET(pd_config.concern_bitmap, data->vport - 1); if ((data->filter > 0 && data->filter < 5) && data->filter != pd_config.port_config[unit][port].filter_cfg) { pd_config.port_config[unit][port].filter_cfg = data->filter; dau_port_config_set(unit, port); dau_reg_port_write(unit, port); } } else { BITMAP_RESET(pd_config.concern_bitmap, data->vport - 1); if (pd_config.port_config[unit][port].filter_cfg != pd_config.port_config[unit][port].config.filter) { pd_config.port_config[unit][port].filter_cfg = pd_config.port_config[unit][port].config.filter; dau_port_config_set(unit, port); dau_reg_port_write(unit, port); } } } /* DAU 报文发送处理. */ int32_t _csg_recv_process(char *pkt, uint32_t len) { csg_pkt_head_t *head = (csg_pkt_head_t*)pkt; /* 报文头和 CRC 校验. */ LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_pkt_check(pkt, len)); /* 共有命令处理. */ switch (head->cmd) { case CSG_CONNECT_ACK: _csg_connect_recv(); break; case CSG_HEARTBEAT_ACK: _csg_heartbeat_recv(pkt); break; case CSG_ACITVE_CONNECT_REQ: _csg_acitve_connect_recv(pkt); break; case CSG_REBOOT_REQ: _csg_reboot_recv(pkt); break; case CSG_FACTORY_SET_REQ: _csg_factory_set_recv(pkt); break; case CSG_FACTORY_GET_REQ: _csg_factory_get_recv(pkt); break; case CSG_CONFIG_SET_REQ: _csg_config_set_recv(pkt); break; case CSG_CONFIG_GET_REQ: _csg_config_get_recv(pkt); break; case CSG_PORT_CONFIG_SET_REQ: _csg_port_config_set_recv(pkt); break; case CSG_PORT_CONFIG_GET_REQ: _csg_port_config_get_recv(pkt); break; case CSG_TREND_REQ: _csg_trend_get_recv(pkt); break; case CSG_REAL_IMAGE_REQ: _csg_real_image_recv(pkt); break; default: //DBG(DBG_M_PD_CSG_ERR, "Cmd %d error!\r\n", head->cmd); break; } csg.communication_time = time(NULL); return E_NONE; } /* 心跳和连接处理函数. */ void *_csg_recv_handle(void *arg) { struct sockaddr_in server; socklen_t server_len; int32_t addr = 0; uint16_t data_len = 0; while (!is_system_init) { sleep(1); } while(1) { /* 读取数据. */ data_len = recvfrom(csg.fd, csg.buf_recv, CSG_PKT_LEN, 0, (struct sockaddr*)&server, &server_len); if (data_len <= 0) { DBG(DBG_M_PD_CSG_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno)); continue; } addr = server.sin_addr.s_addr; if (addr != csg.server_ip) { continue; } _csg_recv_process(csg.buf_recv, data_len); } return NULL; } /* 向后台服务器发送报文处理函数. */ void *_csg_send_handle(void *arg) { pd_csg_msg_t *recv_msg = NULL; while(1) { if (fifo_read(csg.data_fifo_id, (void**)&recv_msg) != 0) { DBG(DBG_M_PD_CSG_ERR, "ERROR at fifo %d read!\r\n", csg.data_fifo_id); continue; } if (csg.is_connect) { /* 数据处理. */ switch(recv_msg->type) { case PD_SEND_TYPE_PRPS: _csg_real_image_send((pd_prps_t*)recv_msg->data); break; case PD_SEND_TYPE_TREND: _csg_trend_send((pd_trend_t*)recv_msg->data); break; case PD_SEND_TYPE_EVENT: _csg_event_send((pd_event_t*)recv_msg->data); break; default: break; } } /* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */ XFREE(MTYPE_CSG, recv_msg->data); fifo_push(csg.data_fifo_id); csg.communication_time = time(NULL); } return NULL; } /* 心跳和连接处理函数. */ void *_csg_heartbeat_handle(void *arg) { time_t now = 0; time_t t_connect = 0; time_t t_heartbeat = 0; while (!is_system_init) { sleep(1); } while(1) { sleep(1); now = time(NULL); /* 发送连接报文. */ if (!csg.is_connect) { if (now - t_connect >= 10) { _csg_connect_send(); t_connect = now; } continue; } /* 发送心跳包. */ if ((now - t_heartbeat) / 60 >= pd_config.config.heartbeat_period) { _csg_heartbeat_send(); t_heartbeat = now; } } return NULL; } /* 后台通讯公共部分初始化. */ int32_t _csg_handle_init_common(void) { struct sockaddr_in server; struct sched_param param; pthread_attr_t attr; pthread_t pid; int32_t rv = 0; int fd = 0; /* 创建协议 socket. */ if (0 == csg.fd) { /* 创建socket */ fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { log_err(LOG_CSG, "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_CSG, "ERROR at socket bind return %s!", safe_strerror(errno)); close(fd); return E_SYS_CALL; } /* 发送数据. */ csg.server_ip = inet_addr("192.168.1.30"); csg.server_port = 10000; bzero(&csg.server, sizeof(csg.server)); csg.server.sin_family = AF_INET; csg.server.sin_addr.s_addr = csg.server_ip; csg.server.sin_port = htons(csg.server_port); /* 保存数据. */ csg.fd = fd; } csg.data_fifo_id = fifo_create(CSG_DATA_FIFO, 128); if (csg.data_fifo_id < 0) { log_err(LOG_CSG, "Open fifo " CSG_DATA_FIFO " error!"); return E_ERROR; } pthread_mutex_init(&csg.mutex, NULL); /* 配置线程RR调度, 优先级70 */ pthread_attr_init(&attr); param.sched_priority = 70; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); rv = pthread_create(&pid, &attr, _csg_send_handle, NULL); if (rv != 0) { log_err(LOG_CSG, "PD can't create pthread %d!", rv); return E_SYS_CALL; } else { thread_m_add("CSG_SEND", pid); } pthread_attr_destroy(&attr); /* 配置线程RR调度, 优先级70 */ pthread_attr_init(&attr); param.sched_priority = 70; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); rv = pthread_create(&pid, &attr, _csg_heartbeat_handle, NULL); if (rv != 0) { log_err(LOG_CSG, "PD can't create heartbeat pthread %d!", rv); return E_SYS_CALL; } else { thread_m_add("CSG_HEARTBEAT", pid); } pthread_attr_destroy(&attr); /* 配置线程RR调度, 优先级70 */ pthread_attr_init(&attr); param.sched_priority = 70; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); rv = pthread_create(&pid, &attr, _csg_recv_handle, NULL); if (rv != 0) { log_err(LOG_CSG, "PD can't create recv pthread %d!", rv); return E_SYS_CALL; } else { thread_m_add("CSG_RCVE", pid); } pthread_attr_destroy(&attr); return E_NONE; } /* Interface functions -------------------------------------------------------*/ /* 后台通讯模块初始化. */ int32_t csg_handle_init(void) { int32_t rv = 0; #if 0 /* 初始化模块. */ LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_handle_init_common()); #endif cmd_install_element(CONFIG_NODE, &csg_server_set_cmd); #if 0 /* 注册配置保存函数 */ rv = cmd_config_node_config_register(CONFIG_PRI_CSG, _csg_config_save); if (rv != E_NONE) { log_err(LOG_CSG, "Command save register ERROR %d!", rv); return rv; } #endif return E_NONE; } #endif /************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/