chenluhua1980
2026-01-09 570e812442a64360239f558ae4b55c0d204a5523
SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -12,6 +12,9 @@
#include <set>
#include <regex>
// ControlState values (keep in sync with Model::ControlState / VariableList.txt)
static constexpr uint8_t kControlStateOnlineRemote = 5;
const char ACK[2] = {0, 1};
const char* ACK0 = &ACK[0];
@@ -444,6 +447,21 @@
   return nullptr;
}
int CHsmsPassive::getCurrentControlState()
{
   auto v = getVariable("CurrentControlState");
   if (v != nullptr) {
      return static_cast<int>(v->getIntValue());
   }
   return 0;
}
bool CHsmsPassive::isHostCommandAllowed()
{
   // Only allow host control commands in OnlineRemote.
   return getCurrentControlState() == kControlStateOnlineRemote;
}
void CHsmsPassive::clearAllVariabel()
{
   for (auto item : m_variabels) {
@@ -507,26 +525,37 @@
void CHsmsPassive::setVariableValue(const char* pszName, __int64 value)
{
   auto v = getVariable(pszName);
   if (v != nullptr) {
   // Protect variable list updates; multiple threads may set SVs.
   Lock();
   if (auto v = getVariable(pszName)) {
      v->setValue(value);
   }
   Unlock();
}
void CHsmsPassive::setVariableValue(const char* pszName, const char* value)
{
   auto v = getVariable(pszName);
   if (v != nullptr) {
   Lock();
   if (auto v = getVariable(pszName)) {
      v->setValue(value);
   }
   Unlock();
}
void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars)
{
   auto v = getVariable(pszName);
   if (v != nullptr) {
   Lock();
   if (auto v = getVariable(pszName)) {
      v->setValue(vars);
   }
   Unlock();
}
void CHsmsPassive::withVariableLock(const std::function<void()>& fn)
{
   Lock();
   if (fn) fn();
   Unlock();
}
static bool isValidFormat(const std::string& fmt)
@@ -1784,9 +1813,14 @@
      goto MYREPLY;
   }
   if (!pBody->getSubItemU2(0, SVID)) {
      // also accept I2 or U4 to be tolerant with host implementations
      if (!pBody->getSubItemI2(0, (short&)SVID)) {
         pMessage->getBody()->addU1Item(SVU1, "SV");
         goto MYREPLY;
         unsigned int svidU4 = 0;
         if (!pBody->getSubItemU4(0, svidU4)) {
            pMessage->getBody()->addU1Item(SVU1, "SV");
            goto MYREPLY;
         }
         SVID = static_cast<unsigned short>(svidU4);
      }
   }
@@ -2216,6 +2250,13 @@
      goto MYREPLY;
   }
   if (!isHostCommandAllowed()) {
      CAACK = CAACK_5;
      ERRCODE = CAACK_5;
      strError = "rejected - ControlState not OnlineRemote";
      goto MYREPLY;
   }
   ISECS2Item* pBody = pRecv->getBody();
   if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
@@ -2419,6 +2460,13 @@
   ISECS2Item* pReplyItemAck = pReplyItemAcks->addU1Item(0, "OBJACK");
   ISECS2Item* pReplyItemErrs = pReplyItemAcks->addItem();
   if (!isHostCommandAllowed()) {
      ISECS2Item* pItemError = pReplyItemErrs->addItem();
      pItemError->addU4Item(2001, "ERRCODE");
      pItemError->addItem("rejected - ControlState not OnlineRemote", "ERRTEXT");
      goto MYREPLY;
   }
   // 当前只处理类各为ControlJob
   if (_strcmpi(pszObjType, "ControlJob") == 0) {
@@ -2533,6 +2581,25 @@
   ISECS2Item* pBody = pRecv->getBody();
   if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
   if (!isHostCommandAllowed()) {
      IMessage* pMessage = NULL;
      HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte);
      ASSERT(pMessage);
      ISECS2Item* pItemPrjobIds = pMessage->getBody()->addItem();
      ISECS2Item* pItemErrors = pMessage->getBody()->addItem();
      pItemErrors->addBoolItem(false, "ACKA");
      ISECS2Item* pItemErrors2 = pItemErrors->addItem();
      auto err = pItemErrors2->addItem();
      err->addU4Item(2001, "ERRCODE");
      err->addItem("rejected - ControlState not OnlineRemote", "ERRTEXT");
      m_pPassive->sendMessage(pMessage);
      LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
         pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
      LOGI("<HSMS>[SEND]%s", pMessage->toString());
      HSMS_Destroy1Message(pMessage);
      return 0;
   }
   // 解释数据,得到CProcessJob
   ISECS2Item* pItemPjs, * pItemPj,* pItemCarriers, * pItemCarrier, *pItemSlots, *pItemRecipes;