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
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);
|
|
}
|
|
}
|
|
}
|