From 8f022255826967b570aed7e66f76217144e02421 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Tue, 31 Oct 2023 13:33:08 +0800 Subject: [PATCH] update --- iflytoplinuxsdk | 2 +- src/extapi_service.cpp | 183 +++++++++++++++++++++++++++++++++++++++++-- src/extapi_service.hpp | 45 +++++++++-- src/main_control_service.cpp | 3 +- src/main_control_service.hpp | 7 +- 5 files changed, 222 insertions(+), 18 deletions(-) diff --git a/iflytoplinuxsdk b/iflytoplinuxsdk index 2d9b698..03155de 160000 --- a/iflytoplinuxsdk +++ b/iflytoplinuxsdk @@ -1 +1 @@ -Subproject commit 2d9b69895bc201c275121c6b48d556b47b2d5e6c +Subproject commit 03155dec4fafabcb38546e6b328269043815a4af diff --git a/src/extapi_service.cpp b/src/extapi_service.cpp index 0d57588..3074015 100644 --- a/src/extapi_service.cpp +++ b/src/extapi_service.cpp @@ -16,7 +16,7 @@ namespace iflytop {}; /******************************************************************************* * TOOLS * *******************************************************************************/ -static void getJsonValFromJson(json j, int& val) { +static void getJsonValFromJson(json j, int &val) { if (j.is_string()) { string valstr = j; val = atoi(valstr.c_str()); @@ -39,20 +39,189 @@ void ExtAPIService::dosystem(string order) { system(order.c_str()); } -void ExtAPIService::initialize() { +void ExtAPIService::initialize(string can_if_name, int baudrate, bool enablLoopback) { GET_TO_SERVICE(m_zconfig); + m_zcan_receiver_master.reset(new ZcanReceiverMaster()); + m_zcan_receiver_master->initialize(can_if_name, baudrate, enablLoopback); + + m_zmodule_device_manager.reset(new ZModuleDeviceManager()); + m_zmodule_device_manager->initialize(m_zcan_receiver_master.get()); + + m_zmodule_device_script_cmder_paser.reset(new ZModuleDeviceScriptCmderPaser()); + m_zmodule_device_script_cmder_paser->initialize(this, m_zmodule_device_manager.get()); + +#if 0 m_restfulServer.reset(new RestfulServer()); - m_restfulServer->regAPI("/hello_world", RESTFUL_SERVER_BIND(ExtAPIService::hello_world)); m_restfulServer->start(20000, 20001, "0.0.0.0"); - + m_restfulServer->regAPI( // + "/doscript", // + [this](HttpRequestPtr request, shared_ptr context, std::shared_ptr) { + string script = request->body; + // callcmd(script) + return std::make_shared(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world"); + }); m_iflytopwsService.reset(new IflytopFrontEndService()); m_iflytopwsService->initialize("0.0.0.0"); m_iflytopwsService->startListen(); +#endif + + /** + * @brief 脚本服务 + * + * + */ + m_script_server.reset(new WebSocketServer(19004, "0.0.0.0")); + m_script_server->setOnConnectionCallback([this](weak_ptr webSocket, shared_ptr connectionState) { + logger->info("Remote ip: {}", connectionState->getRemoteIp()); + auto ws = webSocket.lock(); + if (!ws) return; + ws->setOnMessageCallback([this, webSocket, connectionState](const ix::WebSocketMessagePtr &msg) { + processcmds(msg->str, [this, webSocket, connectionState](string cmd, ICmdParserACK *ack) { // + string ackstr; + if (ack->acktype == ICmdParserACK::kAckType_none) { + ackstr = fmt::format("{} -> ecode:{}({})\n", cmd, err::error2str(ack->ecode), ack->ecode); + } else if (ack->acktype == ICmdParserACK::kAckType_int32) { + ackstr = fmt::format("{} -> ecode:{}({})\n", cmd, err::error2str(ack->ecode), ack->ecode); + for (int32_t i = 0; i < ack->getAckInt32Num(); i++) { + ackstr += fmt::format(" ack[{}]{}\n", i, ack->getAckInt32Val(i)); + } + } else if (ack->acktype == ICmdParserACK::kAckType_buf) { + ackstr = fmt::format("{} -> ecode:{}({})\n", cmd, err::error2str(ack->ecode), ack->ecode); + ackstr = fmt::format(" ackbuf :{}", StringUtils().bytesToString(ack->rawdata, ack->rawlen)); + ackstr = fmt::format(" ackbufstr:{}", string((const char *)ack->rawdata)); + } + }); + }); + }); + + /** + * @brief CAN透传服务 + */ + m_can_passthrough_server.reset(new WebSocketServer(19005, "0.0.0.0")); + m_can_passthrough_server->setOnConnectionCallback([this](weak_ptr webSocket, shared_ptr connectionState) { + logger->info("m_can_passthrough_server on connect remote ip: {}", connectionState->getRemoteIp()); + auto ws = webSocket.lock(); + if (!ws) return; + ws->setOnMessageCallback([this, webSocket, connectionState](const ix::WebSocketMessagePtr &msg) { + // msg->binary; + if (msg->binary) { + logger->info("rx:{}({})", StringUtils().bytesToString(msg->str.data(), msg->wireSize), msg->wireSize); + m_zcan_receiver_master->sendraw((uint8_t *)msg->str.data(), msg->str.size()); + } else { + logger->info("rx:{}({})", msg->str, msg->wireSize); + vector rxbyte; + StringUtils().hexStringToBytes(msg->str, "", rxbyte); + m_zcan_receiver_master->sendraw(rxbyte.data(), rxbyte.size()); + } + }); + }); + + m_zcan_receiver_master->regPacketListener([this](int32_t fromboard, zcr_cmd_header_t *packet, int32_t datalen) { + auto clients = m_can_passthrough_server->getClients(); + string rx = StringUtils().bytesToString((uint8_t *)packet, datalen); + logger->info("tx:{}({})", rx, datalen); + for (auto &each : clients) { + if (each) each->sendText(rx); + } + }); + + m_zmodule_device_manager->regOnRegValChangeEvent([this](int32_t moduleid, int32_t regadd, int32_t toval) { // + logger->info("on reg change: moduleid:{} REG({}) to {}", moduleid, regadd, toval); + }); }; -HttpResponsePtr ExtAPIService::hello_world( // - HttpRequestPtr request, shared_ptr context, std::shared_ptr) { - return std::make_shared(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world"); +void ExtAPIService::regCMD(const char *cmdname, const char *helpinfo, int paraNum, ICmdFunction_t cmdimpl) { + cmd_container_t cmd_container; + cmd_container.cmdname = cmdname; + cmd_container.helpinfo = helpinfo; + cmd_container.paraNum = paraNum; + m_cmdmap[cmdname] = cmd_container; } +void ExtAPIService::processcmds(string script, function ackprocesser) { + /** + * @brief + * script: + * cmd val1 val2 val3 + * cmd val1 val2 val3 + */ + + vector cmdlines; + char *strcache = (char *)malloc(script.size() + 1); + strncpy(strcache, script.c_str(), script.size()); + int32_t stringlen = script.size(); + for (int32_t i = 0; i < stringlen; i++) { + if (strcache[i] == '\n' || strcache[i] == '\r') { + strcache[i] = '\0'; + } + } + + char *currentstr = nullptr; + for (int32_t i = 0; i < stringlen; i++) { + if (currentstr == nullptr) { + if (strcache[i] != '\0') { + currentstr = &strcache[i]; + } + } else { + if (strcache[i] == '\0') { + cmdlines.push_back(currentstr); + currentstr = nullptr; + } + } + } + + for (auto &cmdline : cmdlines) { + ICmdParserACK ack = {0}; + bool isnote = false; + callcmd(cmdline, &ack, isnote); + if (isnote) continue; + if (ackprocesser) ackprocesser(cmdline, &ack); + } + free(strcache); +} + +void removenote(char *buf); + +void ExtAPIService::callcmd(string cmd, ICmdParserACK *ack, bool &isnote) { + char *argv[10]; + int32_t argc = 0; + + char cmdcache[1024] = {0}; + strncmp(cmdcache, cmd.c_str(), 1023); + + // remove note + for (size_t i = 0; i < cmd.length(); i++) { + if (cmdcache[i] == '#') { + cmdcache[i] = '\0'; + if (i == 0) { + isnote = true; + return; + } + break; + } + } + + char *p = strtok(cmdcache, " "); + while (p != NULL) { + argv[argc] = p; + argc++; + p = strtok(NULL, " "); + } + + callcmd(argv[0], argc - 1, (const char **)(argv + 1), ack); +} +void ExtAPIService::callcmd(string cmdname, int32_t paramN, const char **paraV, ICmdParserACK *ack) { + std::lock_guard lock(m_cmdmaplock_); + auto it = m_cmdmap.find(cmdname); + if (it == m_cmdmap.end()) { + ack->ecode = err::kcmd_not_found; + return; + } + cmd_container_t cmd_container = it->second; + if (cmd_container.paraNum != paramN) { + ack->ecode = err::kcmd_param_num_error; + return; + } + cmd_container.cmdimpl(paramN, paraV, ack); +} diff --git a/src/extapi_service.hpp b/src/extapi_service.hpp index 9bd1b51..e850daa 100644 --- a/src/extapi_service.hpp +++ b/src/extapi_service.hpp @@ -13,20 +13,25 @@ #include #include +#include "iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" #include "iflytop/components/restful_server/restful_server.hpp" #include "iflytop/core/components/jobs/work_queue.hpp" #include "iflytop/core/components/timer/simple_timer.hpp" #include "iflytop/core/spdlogfactory/logger.hpp" -#include "iflytoplinuxsdk/src/iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" // #include "configs/gconfig.hpp" #include "iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" +#include "iflytop/zprotocols/zmodule_device_manager.hpp" +#include "iflytop/zprotocols/zmodule_device_script_cmder_paser.hpp" #include "zservice_container/zservice_container.hpp" // // +#include + #include "iflytop/components/zcanreceiver/zcanhost.hpp" +#include "iflytop/components/zcanreceiver/zcanreceiver_master.hpp" /** * @brief @@ -38,16 +43,38 @@ namespace iflytop { using namespace std; using namespace core; -class ExtAPIService : public enable_shared_from_this { +class ExtAPIService : public ICmdParser { ENABLE_LOGGER(ExtAPIService); shared_ptr m_zconfig; - shared_ptr m_restfulServer; - shared_ptr m_iflytopwsService; + shared_ptr m_restfulServer; // 20000,20001 + shared_ptr m_iflytopwsService; // 19001,19002 + shared_ptr m_can_passthrough_server; // 19003 + + shared_ptr m_script_server; // 19004 + // shared_ptr m_event_report_server; // 19005 + + shared_ptr m_zcan_receiver_master; + shared_ptr m_zmodule_device_manager; + shared_ptr m_zmodule_device_script_cmder_paser; + + // cmd + + typedef struct { + string cmdname; + string helpinfo; + int paraNum; + ICmdFunction_t cmdimpl; + } cmd_container_t; + + map m_cmdmap; + std::recursive_mutex m_cmdmaplock_; public: ExtAPIService(){}; - void initialize(); + void initialize(string can_if_name, int baudrate, bool enablLoopback); + + virtual void regCMD(const char *cmdname, const char *helpinfo, int paraNum, ICmdFunction_t cmdimpl); private: void dosystem(string order, bool dump) { @@ -56,7 +83,11 @@ class ExtAPIService : public enable_shared_from_this { } private: - HttpResponsePtr hello_world(HttpRequestPtr, shared_ptr, std::shared_ptr); - void dosystem(string order); + void dosystem(string order); + + void processcmds(string script, function ackprocesser); + void removenote(char *buf); + void callcmd(string cmd, ICmdParserACK *ack,bool &isnote); + void callcmd(string cmdname, int32_t paramN, const char **paraV, ICmdParserACK *ack); }; } // namespace iflytop \ No newline at end of file diff --git a/src/main_control_service.cpp b/src/main_control_service.cpp index 8662f4b..64f541c 100644 --- a/src/main_control_service.cpp +++ b/src/main_control_service.cpp @@ -23,5 +23,6 @@ void MainControlService::initialize() { GET_TO_SERVICE(m_deviceIoControlService); m_deviceIoControlService->startScan(); #endif -}; + m_extAPIService.initialize(m_zconfig->get_iflytopSubDeviceCanIFName(), m_zconfig->get_iflytopSubDeviceCanBitrate(), false); +}; diff --git a/src/main_control_service.hpp b/src/main_control_service.hpp index 168e60c..6ed84dd 100644 --- a/src/main_control_service.hpp +++ b/src/main_control_service.hpp @@ -26,6 +26,7 @@ // // +#include "extapi_service.hpp" #include "iflytop/components/zcanreceiver/zcanhost.hpp" /** @@ -46,12 +47,14 @@ using namespace core; class MainControlService : public enable_shared_from_this { ENABLE_LOGGER(MainControlService); - shared_ptr m_zconfig; + shared_ptr m_zconfig; + + ExtAPIService m_extAPIService; + public: MainControlService(){}; void initialize(); private: - }; } // namespace iflytop \ No newline at end of file