diff --git a/CMakeLists.txt b/CMakeLists.txt index 62058ccc995e63c15f618d56aa375f3e52ebf415..3896eee0d3944abf2dbd40547a9a3d8c6783870c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,10 @@ if (USE_LUA_PROTOCOL) endif(USE_LUA_PROTOCOL) if (USE_XCOM_PROTOCOL) - target_include_directories(${MODULE} PUBLIC libxcom/include) - target_link_libraries(${MODULE} dbms utils libxcom) + target_include_directories(${MODULE} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libxcom/include) + target_link_libraries(${MODULE} dbms utils xcom) endif(USE_XCOM_PROTOCOL) -add_subdirectory(test) \ No newline at end of file + +if (PROJECT_ENABLE_TEST) + add_subdirectory(test) +endif() \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d6ddb5bb0313080c6ac39740f203fb6e971d606d..53c4084f0b5518d3d0ad2f97912e6d89e33521f1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,4 +12,9 @@ function(add_google_test test_target) endfunction() # add_google_test(lua_config) -add_google_test(xcom_parser) +add_google_test(xcom_parser_test) +add_google_test(xcom_process_test) + +install(FILES test_xcom_parser.xcom + DESTINATION $/testfiles/ + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ) diff --git a/test/test_xcom_parser.xcom b/test/test_xcom_parser.xcom index 9f3c57fcf8d6337fce7186d6d45ce5a43dbcbdd5..11439da092ca78e756fc001c4789e62946a4ccf8 100644 --- a/test/test_xcom_parser.xcom +++ b/test/test_xcom_parser.xcom @@ -4,13 +4,13 @@ protocol:{ ```xcom #型号 modbus(crc16) - def crc16: $crc($1,0x8005,0xffff,0x0000,0) + def crc_modbus: $crc16($1,0x8005,0xffff,0x0000,1,1) # 以上可以定义公共函数 - def modbus_read_req:[$addr $fcode $itom(2,$reg) $itom(2,$reglen) $crc16($group(0,$pos))] - def modbus_read_resp:[$addr $fcode $ditch(1,$assign(&dl,$0)) $data($ditch($dl)) $ditch(2,$chk($0,$crc16($group(0,$pos))))] - def modbus_write_req:[$addr $fcode $itom(2,$reg) $itom(2,$reglen) $len($1) $1 $crc16($group(0,$pos))] - def modbus_write_resp:[$addr $fcode $ditch(1,$assign(&dl,$0)) $data($ditch($dl)) $ditch(2,$chk($0,$crc16($group(0,$pos))))] + def modbus_read_req:[$num($addr) $fcode $itom(2,$reg) $itom(2,$reglen) $crc_modbus($group(0,$pos))] + def modbus_read_resp:[$num($addr) $fcode $ditch(1,{dl=$int($0)}) $ditch($dl, {data=$0}) $ditch(2,{$chk($0,$crc_modbus($group(0,$pos)))})] + def modbus_write_req:[$num($addr) $fcode $itom(2,$reg) $itom(2,$reglen) $len($1) $1 $crc_modbus($group(0,$pos))] + def modbus_write_resp:[$num($addr) $fcode $ditch(1,{dl=$int($0)}) $ditch($dl,{data=$0}) $ditch(2,{$chk($0,$crc_modbus($group(0,$pos)))})] ``` # read,write表示读写流程,名称可以自定义,但要与funcpoints的flow绑定名称一致 read:{ @@ -26,5 +26,37 @@ 11X:{flow:read, fcode:03H, reg: 0000H, reglen:2, result:$float($data)}, 12K:{flow:write, fcode:10H, reg: 0db8H, reglen:1, result:$int($data)} } + }, + P056934A925C21000T : { + name:雷优/485/多回路水表V2, + protocol:{ + ```xcom + def chksum: $itom(1,$sum($1)%256) + + # $addr $len 都是输入的参数 + def cj188_read_req: [68H $fcode $sbcd($addr) 01H 3 $itom(3,$seq) $chksum($group(0,$pos)) 16H] + def cj188_read_resp: [68H $fcode $sbcd($addr) 81H $ditch(1,{dl=$int($0)-3}) $itom(3,$seq) $ditch($dl,{data=$0}) $ditch(1) 16H] + ``` + # read,write表示读写流程,名称可以自定义,但要与funcpoints的flow绑定名称一致 + read:{ + send:$cj188_read_req() + recv:$cj188_read_resp() + }, + write:{ + send:$cj188_write_req() + recv:$cj188_write_resp() + } + }, + funcpoints:{ + 12L:{flow:read, fcode:10H, seq: 0x1f9001, result:$bcd($data,0,4)*0.001}, + 12P:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,4,4)*0.0001}, + 14Z:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,11,2)*0.1}, + 13B:{flow:12L, fcode:10H, seq: 0x1f9001, result:$int8($data,13,1)}, + 401:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,4,4)}, + 402:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,4,4)}, + 403:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,4,4)}, + 404:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,4,4)}, + 405:{flow:12L, fcode:10H, seq: 0x1f9001, result:$bcd($data,4,4)}, + } } } \ No newline at end of file diff --git a/test/xcom_parser.cpp b/test/xcom_parser_test.cpp similarity index 53% rename from test/xcom_parser.cpp rename to test/xcom_parser_test.cpp index d7dcb480780ecf90a4c877b68b64613623e5821f..c749f6214b63decdef052fbd11ba3d12df74a090 100644 --- a/test/xcom_parser.cpp +++ b/test/xcom_parser_test.cpp @@ -7,10 +7,15 @@ class XComParserTest : public ::testing::Test { public: void SetUp() override { - load = xcomParser_.LoadXComFile("./test_xcom_parser.xcom"); + load = xcomParser_.LoadXComFile( + VENDOR_TEST_PATH + "/test_xcom_parser.xcom"); } - void TearDown() override { xcomParser_.Clear(); } + void TearDown() override + { + xcomParser_.Clear(); + load = false; + } XComParser xcomParser_; bool load = false; @@ -52,24 +57,62 @@ TEST_F(XComParserTest, LoadXComFileFlow) EXPECT_EQ(writeFlow.procList.at(1).call, "recv"); } +TEST_F(XComParserTest, LoadXComFileFlow2) +{ + std::shared_ptr xcomNode = + xcomParser_.GetXComNode("P056934A925C21000T"); + + const Flow_t &readFlow = xcomNode->GetFlow("read"); + EXPECT_EQ(readFlow.procList.size(), 2); + EXPECT_EQ(readFlow.procList.at(0).call, "send"); + EXPECT_EQ(readFlow.procList.at(1).call, "recv"); + + const Flow_t &flow = xcomNode->GetFlow("12L"); + EXPECT_EQ(flow.procList.size(), 2); + EXPECT_EQ(flow.procList.at(0).call, "send"); + EXPECT_EQ(flow.procList.at(1).call, "recv"); +} + TEST_F(XComParserTest, LoadXComFileFunctions) { std::shared_ptr xcomNode = xcomParser_.GetXComNode("P0046F56202C21000T"); const FuncParam_t &funcpoints = xcomNode->GetFuncParam("11X"); EXPECT_EQ(funcpoints.flow, "read"); - EXPECT_EQ(funcpoints.resultExpr->funcName(), "$float($data)"); + EXPECT_EQ(funcpoints.resultExpr->ToExprString(), "$float($data)"); EXPECT_EQ(funcpoints.vars.size(), 3); + EXPECT_NE(funcpoints.vars.find("reg"), funcpoints.vars.end()); EXPECT_NE(funcpoints.vars.find("reglen"), funcpoints.vars.end()); EXPECT_NE(funcpoints.vars.find("fcode"), funcpoints.vars.end()); - EXPECT_EQ(funcpoints.vars.at("reg"), - libxcom::OpValue(static_cast(0000))); - EXPECT_EQ( - funcpoints.vars.at("reglen"), libxcom::OpValue(static_cast(2))); - EXPECT_EQ( - funcpoints.vars.at("fcode"), libxcom::OpValue(static_cast(3))); + libxcom::OpValue reg = funcpoints.vars.at("reg"); + libxcom::OpValue reglen = funcpoints.vars.at("reglen"); + libxcom::OpValue fcode = funcpoints.vars.at("fcode"); + reg.Show(); + reglen.Show(); + fcode.Show(); + EXPECT_EQ(reg, libxcom::OpValue(static_cast(0000))); + EXPECT_EQ(reglen, libxcom::OpValue(static_cast(2))); + EXPECT_EQ(fcode, libxcom::OpValue(static_cast(3))); +} + +TEST_F(XComParserTest, LoadXComFileFunctions2) +{ + std::shared_ptr xcomNode = + xcomParser_.GetXComNode("P056934A925C21000T"); + const FuncParam_t &funcpoints = xcomNode->GetFuncParam("12L"); + EXPECT_EQ(funcpoints.flow, "read"); + EXPECT_EQ(funcpoints.resultExpr->ToExprString(), "$bcd($data,0,4)*0.001"); + EXPECT_EQ(funcpoints.vars.size(), 2); + + EXPECT_EQ(funcpoints.vars.at("seq").As(), 0x1f9001); + EXPECT_EQ(funcpoints.vars.at("fcode").As(), 0x10); + + libxcom::OpValue seq = funcpoints.vars.at("seq"); + libxcom::OpValue fcode = funcpoints.vars.at("fcode"); + seq.Show(); + fcode.Show(); } } // namespace protocol diff --git a/test/xcom_process.cpp b/test/xcom_process.cpp deleted file mode 100644 index 60ddae7f0da5b6e8270b99c84ff2c99c2cac7cb7..0000000000000000000000000000000000000000 --- a/test/xcom_process.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include "xcom_process.h" -#include "xcom_handler.h" -#include "cmdvalue.h" - -namespace protocol { -class XComProcessTest : public ::testing::Test { -public: - void SetUp() override {} - - void TearDown() override {} - - XComHandler xcomHandler_; - bool load = false; -}; - -TEST_F(XComProcessTest, Process) -{ - std::shared_ptr xcomNode = - xcomHandler_.GetXComNode("P004C0F3E15821000T"); - XComProcess xcomProcess(xcomNode, "2014051809"); - xcomProcess.Process( - "12N", [](const libxcom::CmdValue &cmd) -> libxcom::CmdValue { - uint8_t buff[] = {0x68, 0x20, 0x09, 0x18, 0x05, 0x14, 0x20, 0x00, - 0x00, 0x81, 7, 0x1f, 0x90, 0x01, 0x0, 0x01, 0x22, 0x33, 0x55}; - libxcom::CmdValue cmdValue(buff, sizeof(buff)); - return cmdValue; - }); - // xcomProcess -} -} // namespace protocol - -int main(int argc, char *argv[]) -{ - utils::set_enable(true); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/test/xcom_process_test.cpp b/test/xcom_process_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12d914a519e6290a90a9c1f0f8dd3135ecceaef6 --- /dev/null +++ b/test/xcom_process_test.cpp @@ -0,0 +1,161 @@ +#include +#include +#include "xcom_process.h" +#include "xcom_handler.h" +#include "cmdvalue.h" + +#define TS(func) \ + do { \ + struct timeval t1, t2; \ + gettimeofday(&t1, NULL); \ + func; \ + gettimeofday(&t2, NULL); \ + printf(#func ": %.3fmsecs\n", (t2.tv_sec - t1.tv_sec) * 1000.0 + \ + (t2.tv_usec - t1.tv_usec) / 1000.0); \ + } while (0) +namespace protocol { +class XComProcessTest : public ::testing::Test { +public: + void SetUp() override + { + load = xcomParser_.LoadXComFile( + VENDOR_TEST_PATH + "/test_xcom_parser.xcom"); + } + + void TearDown() override + { + xcomParser_.Clear(); + load = false; + } + + XComParser xcomParser_; + bool load = false; +}; + +TEST_F(XComProcessTest, Process) +{ + std::shared_ptr xcomNode = + xcomParser_.GetXComNode("P056934A925C21000T"); + XComProcess xcomProcess(xcomNode, "00000024240033"); + bool result; + TS(result = xcomProcess.Process( + "12L", + [&](const libxcom::CmdValue &cmd, + const ParseRecv &parseRecv) -> bool { + EXPECT_EQ(cmd.Data(), std::vector({0x68, 0x10, 0x33, + 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 01, + 03, 0x1F, 0x90, 0x01, 0xA7, 0x16})); + std::vector data = {0x68, 0x10, 0x33, 0x00, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x81, 20, 0x1F, 0x90, 0x01, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0xA7, + 0x16}; + int result = parseRecv(data.data(), data.size()); + EXPECT_EQ(result, RECV_COMPLETE); + return true; + }, + {}, 1.00)); + xcomProcess.GetResult("dl").Show(); + bool flag = false; + EXPECT_TRUE(xcomProcess.Process( + "12P", + [&](const libxcom::CmdValue &cmd, const ParseRecv &parseRecv) -> bool { + flag = true; + return true; + }, + {}, 1.00)); + EXPECT_EQ(flag, false); + EXPECT_FLOAT_EQ(xcomProcess.GetResult("12L").As(), 0); + EXPECT_FLOAT_EQ(xcomProcess.GetResult("12P").As(), 0); + + EXPECT_EQ(xcomProcess.GetResult("data").As().Data(), + std::vector({00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00})); +} + +TEST_F(XComProcessTest, Process2) +{ + std::shared_ptr xcomNode = + xcomParser_.GetXComNode("P0046F56202C21000T"); + XComProcess xcomProcess(xcomNode, "01"); + bool result; + TS(result = xcomProcess.Process( + "11X", + [&](const libxcom::CmdValue &cmd, + const ParseRecv &parseRecv) -> bool { + EXPECT_EQ(cmd.Data(), std::vector({0x01, 0x03, 0x00, + 0x00, 0x00, 0x02, 0x0B, 0xC4})); + std::vector data = { + 0x01, 0x03, 0x04, 0x42, 0x07, 0x00, 0x00, 0x37, 0x25}; + int result = parseRecv(data.data(), data.size()); + EXPECT_EQ(result, RECV_COMPLETE); + return true; + }, + {}, 1.00)); + xcomProcess.GetResult("dl").Show(); + EXPECT_EQ(xcomProcess.GetResult("dl").As(), 4); + EXPECT_FLOAT_EQ(xcomProcess.GetResult("11X").As(), 33.75); + EXPECT_EQ(xcomProcess.GetResult("data").As().Data(), + std::vector({0x42, 0x07, 0x00, 0x00})); +} + +TEST_F(XComProcessTest, ProcessNotComplete) +{ + std::shared_ptr xcomNode = + xcomParser_.GetXComNode("P056934A925C21000T"); + XComProcess xcomProcess(xcomNode, "00000024240033"); + + auto func = [&](const libxcom::CmdValue &cmd, + const ParseRecv &parseRecv) -> bool { + EXPECT_EQ(cmd.Data(), + std::vector({0x68, 0x10, 0x33, 0x00, 0x24, 0x24, 0x00, + 0x00, 0x00, 01, 03, 0x1F, 0x90, 0x01, 0xA7, 0x16})); + std::vector data1 = {0x68, 0x10, 0x33, 0x00, 0x24}; + std::vector data2 = { + 0x24, 0x00, 0x00, 0x00, 0x81, 20, 0x1F, 0x90, 0x01, 00, 00, 00}; + std::vector data3 = { + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0xA7, 0x16}; + for (int32_t i = 0; i < 3; ++i) { + if (i == 0) { + int result = parseRecv(data1.data(), data1.size()); + EXPECT_EQ(result, RECV_NOT_COMPLETE); + } else if (i == 1) { + int result = parseRecv(data2.data(), data2.size()); + EXPECT_EQ(result, RECV_NOT_COMPLETE); + } else { + int result = parseRecv(data3.data(), data3.size()); + EXPECT_EQ(result, RECV_COMPLETE); + } + } + return true; + }; + EXPECT_TRUE(xcomProcess.Process("12L", func, {}, 1.00)); +} + +TEST_F(XComProcessTest, ProcessFail) +{ + std::shared_ptr xcomNode = + xcomParser_.GetXComNode("P056934A925C21000T"); + XComProcess xcomProcess(xcomNode, "00000024240033"); + EXPECT_FALSE(xcomProcess.Process( + "12L", + [&](const libxcom::CmdValue &cmd, const ParseRecv &parseRecv) -> bool { + EXPECT_EQ(cmd.Data(), + std::vector({0x68, 0x10, 0x33, 0x00, 0x24, 0x24, 0x00, + 0x00, 0x00, 01, 03, 0x1F, 0x90, 0x01, 0xA7, 0x16})); + std::vector data = {0x68, 0x10, 0x33, 0x00, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x81, 20, 0x1F, 0x91, 0x01, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0xA7, 0x16}; + int result = parseRecv(data.data(), data.size()); + EXPECT_EQ(result, RECV_FAILED); + return false; + }, + {}, 1.00)); +} +} // namespace protocol + +int main(int argc, char *argv[]) +{ + utils::set_enable(true); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/xcom_handler.cpp b/xcom_handler.cpp index 647b136c640db773977c28d9e2e4003a3f62e735..93908407116deee15e1ff85e0dcae16d937434a6 100644 --- a/xcom_handler.cpp +++ b/xcom_handler.cpp @@ -7,21 +7,17 @@ #include namespace protocol { -XComHandler::XComHandler() -{ - if (!xComParser_.LoadXComFile(VENDOR_CONFIG_PATH + "/protocol.xcom")) { - HTELINK_LOG_ERR("load protocol.xcom failed"); - } -} +XComHandler::XComHandler() {} XComHandler::~XComHandler() { xComParser_.Clear(); } std::shared_ptr XComHandler::GetXComInstance() { static std::shared_ptr staticXComHandler = nullptr; - if (staticXComHandler == nullptr) { - staticXComHandler = std::make_shared(); - } + static std::once_flag initFlag; + + std::call_once(initFlag, + [&]() { staticXComHandler = std::make_shared(); }); return staticXComHandler; } diff --git a/xcom_node.cpp b/xcom_node.cpp index f64df6a0b23e68042e54da454bd4bc8628298f8d..e35a977b6e1c4f28d2175e220acc8c6b5ad28240 100644 --- a/xcom_node.cpp +++ b/xcom_node.cpp @@ -1,7 +1,7 @@ #include "xcom_node.h" -#include #include - +#include +#include namespace protocol { void XComNode::SetName(const std::string &name) { name_ = name; } @@ -45,10 +45,20 @@ const std::string &XComNode::GetTemplate() const // TODO: insert return statement here return template_; } -const Flow_t &XComNode::GetFlow(const std::string &key) const +const Flow_t XComNode::GetFlow(const std::string &key) const { + if (mapFlow_.find(key) == mapFlow_.end()) { + if (funcPoints_.find(key) != funcPoints_.end()) { + return GetFlow(GetFuncParam(key).flow); + } + return Flow_t(); + } return mapFlow_.at(key); } +bool XComNode::HasFuncId(const std::string &id) +{ + return funcPoints_.find(id) != funcPoints_.end(); +}; const FuncParam_t &XComNode::GetFuncParam(const std::string &funcId) const { return funcPoints_.at(funcId); @@ -60,19 +70,18 @@ libxcom::OpValue XComNode::ExprToValue(const std::string &strExpr) if (expr == nullptr) { return libxcom::OpValue::Null(); } - libxcom::Operator oprator(nullptr); + libxcom::Operator oprator; - return expr->GenCmd(oprator); + libxcom::OpValue v = expr->GenCmd(oprator); + if (v.IsEmpty()) { + HTELINK_LOG_DEBUG("expr: %s -> %s", strExpr, v.toString()); + } + return v; } std::shared_ptr XComNode::WrapExpress(const std::string &str) { - libxcom::TempBuf tempBuf(str); - int32_t pos = 0; - libxcom::TempBuf::RESULT res = tempBuf.Parse(pos, true); - if ((res != libxcom::TempBuf::OK && res != libxcom::TempBuf::FIN)) - return NULL; - return tempBuf.ResultExpress(); + return libxcom::Template::instance()->StaticParse(str); } const std::string &XComNode::GetName() const { return name_; } } // namespace protocol diff --git a/xcom_node.h b/xcom_node.h index 66c96474ec120ac78eb70d9b004b163599a1fea5..1ee47ec17f7392d00dfd4604ec93046688ed139f 100644 --- a/xcom_node.h +++ b/xcom_node.h @@ -2,21 +2,19 @@ #define FOUNDATION_PROTOCOL_XCOMNODE_H #include #include -#include "template.h" #include "dbms.pb.h" -#include "express.h" +#include namespace protocol { - typedef struct { std::string flow; - std::shared_ptr resultExpr; + libxcom::XExpress resultExpr; std::unordered_map vars; } FuncParam_t; typedef struct { std::string call; - std::shared_ptr expr; + libxcom::XExpress expr; } Process_t; typedef struct { @@ -39,7 +37,8 @@ public: const std::string &GetName() const; const std::string &GetId() const; const std::string &GetTemplate() const; - const Flow_t &GetFlow(const std::string &key) const; + const Flow_t GetFlow(const std::string &key) const; + bool HasFuncId(const std::string &id); const FuncParam_t &GetFuncParam(const std::string &funcId) const; private: diff --git a/xcom_process.cpp b/xcom_process.cpp index 15fbf2cc86f11be37f5c71c40f6b9867d56a8b17..a915e66569381518f6cc6930c3921d58a6e1489a 100644 --- a/xcom_process.cpp +++ b/xcom_process.cpp @@ -2,23 +2,51 @@ #include "xcom_node.h" namespace protocol { -XComProcess::XComProcess( - std::shared_ptr xcomNode, const std::string &addr) +XComProcess::XComProcess(const std::shared_ptr &xcomNode, + const std::string &addr) : xcomNode_(xcomNode) , dataItem_(xcomNode->GetName(), xcomNode->GetTemplate()) { - dataItem_.SetVar("addr", addr); + dataItem_.SetVar("addr", libxcom::OpValue(addr)); } -bool XComProcess::Process(const std::string &funcId, XComSendFunc sendFunc, - const std::vector ¶ms) +XComProcess::~XComProcess() {} + +bool XComProcess::IsReadFlow(const std::string &funcId) { if (xcomNode_ == nullptr) { return false; } + if (!xcomNode_->HasFuncId(funcId)) { + HTELINK_LOG_ERR("not find funcId %s", funcId); + return false; + } const FuncParam_t &funcParam = xcomNode_->GetFuncParam(funcId); - const Flow_t &flow = xcomNode_->GetFlow(funcParam.flow); - dataItem_.SetDataExpr(funcParam.resultExpr, 1); + if (funcParam.flow.find("read") == funcParam.flow.npos) { + return false; + } + return true; +} + +bool XComProcess::Process(const std::string &funcId, XComSend sendFunc, + const std::vector ¶ms, float ratio) +{ + if (xcomNode_ == nullptr) { + return false; + } + if (dataItem_.HasVar(funcId)) { + return true; + } + + if (!xcomNode_->HasFuncId(funcId)) { + HTELINK_LOG_ERR("not find funcId %s", funcId); + return false; + } + + const FuncParam_t &funcParam = xcomNode_->GetFuncParam(funcId); + Flow_t flow = xcomNode_->GetFlow(funcParam.flow); + dataItem_.SetDataExpr(funcParam.resultExpr, ratio); + HTELINK_LOG_DEBUG("ratio: %f", ratio); for (auto &var : funcParam.vars) { // second 需要先转换成OpValue @@ -29,38 +57,45 @@ bool XComProcess::Process(const std::string &funcId, XComSendFunc sendFunc, for (auto &opValue : params) { dataItem_.PushParam(opValue); } - std::stack stackFlow; + if (dataItem_.HasVar(funcParam.flow)) { + dataItem_.SetVar(funcId, dataItem_.Result()); + return true; + } + libxcom::OpValue cmd; for (auto &proc : flow.procList) { if (proc.call == "send") { // 指令序列化, 绑定send函数 - libxcom::OpValue cmd = dataItem_.GenerateCmd(proc.expr); + cmd = dataItem_.GenerateCmd(proc.expr); if (cmd.IsEmpty()) { + HTELINK_LOG_ERR( + "cmd gen failed, %s", proc.expr->GetExprString()); return false; } - libxcom::CmdValue recv = sendFunc(cmd.GenCmd()); - stackFlow.push(std::move(recv)); } else if (proc.call == "recv") { - if (stackFlow.empty()) { - HTELINK_LOG_WARN("Need send process before recv"); - return false; - } - libxcom::RECV_RESULT result = - dataItem_.ParseRecvCmd(stackFlow.top(), proc.expr); - if (result != RECV_COMPLETE) { - HTELINK_LOG_ERR("receive cmd parse error, %d", result); + dataItem_.ParseRecvCmd(proc.expr); + auto func = [&](uint8_t *buf, int32_t len) -> libxcom::RECV_RESULT { + return dataItem_.ProcessRealRecv(buf, len); + }; + if (!sendFunc(cmd.GenCmd(), func)) { + HTELINK_LOG_ERR("process %s send failed", proc.call); return false; } - stackFlow.pop(); } else { HTELINK_LOG_ERR("Not support this process, %s", proc.call.c_str()); return false; } } - dataItem_.SetVar(funcId, dataItem_.Result()); + auto result = dataItem_.Result(); + result.Show(); + if (result.IsEmpty()) { + HTELINK_LOG_ERR("get result failed"); + return false; + } + dataItem_.SetVar(funcId, std::move(result)); return true; } -const libxcom::OpValue &XComProcess::GetResult(const std::string &var) const +libxcom::OpValue XComProcess::GetResult(const std::string &var) { return dataItem_.GetVar(var); } diff --git a/xcom_process.h b/xcom_process.h index d6ca7be285853ba06cdd0bc96f38990a2c6ecf34..325ee320f5320f9da63dc9b423e2dfb5bbcff325 100644 --- a/xcom_process.h +++ b/xcom_process.h @@ -2,7 +2,6 @@ #define FOUNDATION_PROTOCOL_XCOMPROCESS_H #include #include -#include "template.h" #include #include #include "xcom_node.h" @@ -11,19 +10,24 @@ namespace protocol { +using ParseRecv = std::function; +using XComSend = + std::function; class XComListener { public: std::function xComSendBuffer; }; -using XComSendFunc = - std::function; + class XComProcess { public: - XComProcess(std::shared_ptr xcomNode, const std::string &addr); - bool Process(const std::string &funcId, XComSendFunc sendFunc, - const std::vector ¶ms = {}); - const libxcom::OpValue &GetResult(const std::string &var) const; + XComProcess( + const std::shared_ptr &xcomNode, const std::string &addr); + ~XComProcess(); + bool IsReadFlow(const std::string &funcId); + bool Process(const std::string &funcId, XComSend sendFunc, + const std::vector ¶ms = {}, float ratio = 1); + libxcom::OpValue GetResult(const std::string &var); private: std::shared_ptr xcomNode_ = nullptr;