#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 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& packetout) { // shared_ptr _packetout(new icps::Packet()); if (jin["protocol"] != "iflytopCanProtocolStackV1") { logger->error("create ICPSPacket failed, protocol not match,protocol:{}", jin["protocol"].get()); 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 packet) { // processCanMessageFromCanService(packet); }); }; void MainControlService::websocketServerInitialize() { /** * @brief * 对接下行消息 */ m_iflytopWSService->onMessage.connect([this](weak_ptr 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 packet) { // /** * @brief * 本地虚拟can上报消息给Websocket */ processCanMessageFromLocalCanService(packet); return; }); } /******************************************************************************* * 上行消息处理 * *******************************************************************************/ /** * @brief 处理从CanService接收到的上行消息 * * @param packet */ void MainControlService::processCanMessageFromCanService(shared_ptr 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 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 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); } } }