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

218 lines
7.9 KiB

#include "main_control_service.hpp"
#include "configs/project_setting.hpp"
#include "iflytopcpp/core/components/stringutils.hpp"
#include "version.hpp"
using namespace iflytop;
using namespace core;
using namespace std;
class Trace {
logger_t m_logger;
string m_name;
public:
Trace(logger_t log, const string& name) : m_logger(log), m_name(name) { m_logger->info("TRACE::ENTER {}", m_name); }
~Trace() { m_logger->info("TRACE::EXIT {}", m_name); }
};
/***********************************************************************************************************************
* ======================================================宏定义======================================================= *
***********************************************************************************************************************/
/*********************************************************************************************************************
* ======================================================代码======================================================= *
*********************************************************************************************************************/
bool MainControlService::createIflytopHardwareWSPacket(shared_ptr<icps::Packet> packetin, json& jout) {
if (!packetin) return false;
#if 0
{
"channel":"can0",
"protocol":"iflytopCanProtocolStackV1",
"message": {
"attribute": "normal/gbroadcast/subbroadcast",
"priority": 4, //0->7,0最高
"type": "w/r/receipt/report/set_auto_report/heart_packet",
"targetId": 128, // 128->255
"sourceId": 1, // 默认为1
"seq": 0, //0-65535,
"regAdd": 0, //0-65535
"regValue": 100 // -2^31->2^31-1
}
}
#endif
if (packetin->getSourceId() == LINUX_HARDWARE_ID) {
jout["channel"] = "local";
} else {
jout["channel"] = "can0";
}
jout["protocol"] = "iflytopCanProtocolStackV1";
jout["message"]["attribute"] = packetin->getAttributeStr();
jout["message"]["priority"] = packetin->getPriority();
jout["message"]["type"] = packetin->getTypeStr();
jout["message"]["targetId"] = packetin->getTargetId();
jout["message"]["sourceId"] = packetin->getSourceId();
jout["message"]["seq"] = packetin->getSeq();
jout["message"]["regAdd"] = packetin->getRegAdd();
jout["message"]["regValue"] = packetin->getRegValue();
return true;
}
bool MainControlService::createICPSPacket(json jin, shared_ptr<icps::Packet>& packetout) { //
shared_ptr<icps::Packet> _packetout(new icps::Packet());
if (jin["protocol"] != "iflytopCanProtocolStackV1") {
logger->error("create ICPSPacket failed, protocol not match,protocol:{}", jin["protocol"].get<string>());
return false;
}
_packetout->setAttributeByStr(jin["message"]["attribute"]);
_packetout->setPriority(jin["message"]["priority"]);
_packetout->setTypeByStr(jin["message"]["type"]);
_packetout->setTargetId(jin["message"]["targetId"]);
_packetout->setSourceId(jin["message"]["sourceId"]);
_packetout->setSeq(jin["message"]["seq"]);
_packetout->setRegAdd(jin["message"]["regAdd"]);
_packetout->setRegValue(jin["message"]["regValue"]);
packetout = _packetout;
return true;
}
void MainControlService::initialize() {
GET_TO_SERVICE(m_zconfig);
GET_TO_SERVICE(m_iflytopWSService);
GET_TO_SERVICE(m_canService);
localVirtualCanSlaveInitialize();
websocketServerInitialize();
/*******************************************************************************
* 真实的CAN设备衔接 *
*******************************************************************************/
m_canService->onIflytopCanSubDevicePacket.connect([this](shared_ptr<icps::Packet> packet) { //
processCanMessageFromCanService(packet);
});
};
void MainControlService::websocketServerInitialize() {
/**
* @brief
* 对接下行消息
*/
m_iflytopWSService->onMessage.connect([this](weak_ptr<WebSocket> webSocket, const ix::WebSocketMessagePtr& msg) {
if (msg->binary) {
logger->warn("receive binary message,ignore");
return;
}
string msgtext = msg->str;
try {
json message = json::parse(msgtext);
processIflytopWSMsg(message);
} catch (const std::exception& e) {
logger->error("m_iflytopWSService:onMessag,parse json failed,exception:{},{}", e.what(), msgtext);
}
});
}
void MainControlService::localVirtualCanSlaveInitialize() {
m_localVirtualCanSlave.reset(new IflytopVirtualCanSlave());
m_localVirtualCanSlave->initialize(LINUX_HARDWARE_ID);
m_localVirtualCanSlave->activeReg(REG_REBOOT_FLAG, icps::kw | icps::kr, 0);
m_localVirtualCanSlave->activeReg(REG_EXCEPTION_FLAG, icps::kw | icps::kr, 0);
m_localVirtualCanSlave->setOnHostRegisterReadEvent( //
[this](icps::Reg_t& reg, int32_t& value) { //
return icps::kSuccess;
});
m_localVirtualCanSlave->setOnHostRegisterWriteEvent( //
[this](icps::Reg_t& reg, int32_t oldvalue, int32_t& newvalue) { //
return icps::kSuccess;
});
m_localVirtualCanSlave->setOnRegisterValueAutoReportEvent( //
[this](icps::Reg_t& reg, int32_t& value) { //
return;
});
m_localVirtualCanSlave->IflytopVirtualCanIF_setUpstream( //
[this](shared_ptr<icps::Packet> packet) { //
/**
* @brief
* 本地虚拟can上报消息给Websocket
*/
processCanMessageFromLocalCanService(packet);
return;
});
}
/*******************************************************************************
* 上行消息处理 *
*******************************************************************************/
/**
* @brief 处理从CanService接收到的上行消息
*
* @param packet
*/
void MainControlService::processCanMessageFromCanService(shared_ptr<icps::Packet> packet) {
/**
* @brief 处理从can收到的消息
*/
json uppacket;
bool suc = createIflytopHardwareWSPacket(packet, uppacket);
if (!suc) {
logger->error("{}|createIflytopHardwareWSPacket failed,packet:{}", __LINE__, packet->toString());
return;
}
m_iflytopWSService->sendMessage(uppacket.dump());
}
/**
* @brief 处理本地虚拟can的上行消息
*
* @param packet
*/
void MainControlService::processCanMessageFromLocalCanService(shared_ptr<icps::Packet> packet) {
json uppacket;
bool suc = createIflytopHardwareWSPacket(packet, uppacket);
if (!suc) {
logger->error("{}|createIflytopHardwareWSPacket failed,packet:{}", __LINE__, packet->toString());
return;
}
m_iflytopWSService->sendMessage(uppacket.dump());
}
/*******************************************************************************
* 下行消息处理 *
*******************************************************************************/
void MainControlService::processIflytopWSMsg(const json& in) {
/**
* @brief
* 路由消息到CAN,Local,或者其他服务
*
* 1. 消息由json转换成packet
* 2. 根据地址陆游消息到CAN,Local,或者其他服务
*/
shared_ptr<icps::Packet> packet;
createICPSPacket(in, packet);
if (packet == nullptr) {
logger->error("create ICPSPacket failed");
return;
}
if (packet->getTargetId() == LINUX_HARDWARE_ID) {
/**
* @brief
* 本地虚拟can设备
*/
m_localVirtualCanSlave->IflytopVirtualCanIF_feedPacket(packet);
} else {
/**
* @brief
* 转发给can设备
*/
SocketCan::SocketCanError_t error = m_canService->sendPacketToIflytopCanSubDevice(packet, 10);
if (error != SocketCan::SocketCanError_t::kSuccess) {
logger->error("sendPacketToIflytopCanSubDevice failed, error:{},({})", //
SocketCan::SocketCanError_t2Str(error), error);
IflytopCanProtocolStack().createErrorPacket(packet, icps::kOvertime);
}
}
}