Procházet zdrojové kódy

重要修改:
FireTV的指令处理:0xFC.
未完成。

sat23 před 4 roky
rodič
revize
d3a137964d

+ 109 - 1
TCLCommand/TCLCommand/Command.cpp

@@ -446,7 +446,8 @@ bool TCLCommand::TheSecondPart(CommandParam& cmdPara, std::string data)
             utils::_dprintf("[%s] 带有脏数据:%s", __FUNCTION__, data.substr(nPacketLen));
 #endif
     }
-    else {
+    else 
+    {
 #if _MSC_VER >= 1200 && _MSC_VER < 1500
         cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
 #elif _MSC_VER >= 1500
@@ -458,6 +459,113 @@ bool TCLCommand::TheSecondPart(CommandParam& cmdPara, std::string data)
     return true;
 }
 
+bool TCLCommand::TheSecondPartFireTV(CommandParam& cmdPara, std::string data)
+{
+    // 数据起始位;
+    int nDataPos = 0;
+    // 数据包长度;
+    int nPacketLen = 0;
+    if ((byte)data[0] == cmdPara._rtnCode) {
+        // 获取长度;
+        if ((byte)data[1] == 0xFE) {
+            nDataPos = 4;
+            nPacketLen = (byte)data[2] << 8 | (byte)data[3];
+            if (data.size() < 255 && data[2] != 0) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+                cmdPara._rtnError = utils::_dprintf(_T("返回数据长度异常"));
+#elif _MSC_VER >= 1500
+                cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回数据长度异常"), __FUNCTION__);
+#endif
+                return false;
+            }
+        }
+        else
+        {
+            nDataPos = 2;
+            nPacketLen = (byte)data[1];
+#if 0 // 如果数据包含有非协议包内的数据,会判断异常;
+            if (data.size() > 255) {
+                //nPackageLen = data[1] << 8 | data[2];
+                cmdPara._rtnError = _dprintf(_T("长度异常"));
+                return false;
+            }
+#endif
+        }
+
+#if 1
+        // 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
+        if (nPacketLen > data.size())
+        {
+            cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的数据长度错误, 计算:%d > 实际:%d"), __FUNCTION__, nPacketLen, data.size());
+            return false;
+        }
+#endif
+
+        // FireTV的Code是与Write时一样;
+        if (_tcsicmp(cmdPara.code.c_str(), utils::ByteToChars((byte)data[nDataPos]).c_str()) != 0) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+            cmdPara._rtnError = utils::_dprintf(_T("返回的指令码错误, 正确:%02X, 当前:%02X"), utils::TwoHexCharToInteger(cmdPara.code[0],cmdPara.code[1]), (byte)data[nDataPos]);
+#elif _MSC_VER >= 1500
+            cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令码错误, 正确:%02X, 当前:%02X"), __FUNCTION__, utils::TwoHexCharToInteger(cmdPara.code[0],cmdPara.code[1]), (byte)data[nDataPos]);
+#endif
+            return false;
+        }
+
+        // 返回的数据;
+        ++nDataPos;// 返回码占一字节;
+#if 0 // FireTV的返回的指令参数与code没有规律对应;returnParam要外部根据协议来判断;
+        if (cmdPara.returnParam) {
+            // 返回的指令参数
+            std::string rtnParam = data.substr(nDataPos, cmdPara.param.size()/2);
+            rtnParam = utils::BytesToHexString((byte*)rtnParam.c_str(), rtnParam.size());
+            if (_tcsicmp(cmdPara.param.c_str(), rtnParam.c_str()) != 0) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+                cmdPara._rtnError = utils::_dprintf(_T("返回的指令参数错误, %s, %s"), cmdPara.param.c_str(), rtnParam.c_str());
+#elif _MSC_VER >= 1500
+                cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令参数错误, %s, %s"), __FUNCTION__, cmdPara.param.c_str(), rtnParam.c_str());
+#endif
+                return false;
+            }
+
+            nDataPos += rtnParam.size()/2;// 指令参数码占一字节;
+        }
+#endif
+
+        cmdPara._rtnData = data.substr(nDataPos, nPacketLen - nDataPos - 2); //2 = crc;
+        utils::_dprintf(_T("rtnData=%s"), utils::BytesToHexString((byte*)cmdPara._rtnData.c_str(), cmdPara._rtnData.size(), ' ').c_str());
+
+        // 校验crc;
+        unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPacketLen - 2);
+        if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPacketLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPacketLen - 1])
+        {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+            cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
+#elif _MSC_VER >= 1500
+            cmdPara._rtnError = utils::_dprintf("[%s] CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", __FUNCTION__, (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
+#endif
+            return false;
+        }
+
+        if (data.size() > nPacketLen)
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+            utils::_dprintf(_T("带有脏数据:%s"), data.substr(nPacketLen));
+#elif _MSC_VER >= 1500
+            utils::_dprintf("[%s] 带有脏数据:%s", __FUNCTION__, data.substr(nPacketLen));
+#endif
+    }
+    else 
+    {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
+#elif _MSC_VER >= 1500
+        cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
+#endif
+        return false;
+    }
+
+    return true;
+}
+
 void TCLCommand::PackingCommand(CommandParam& cmdPara, LPVOID data, const int& dataLen)
 {
     // Tag:[命令头][全命令长度][命令码]<命令码参数><附加数据>[crc1][crc2]

+ 2 - 1
TCLCommand/TCLCommand/Command.h

@@ -20,7 +20,8 @@ private:
     void parse_cmds_from_string(std::string str, std::vector<CommandParam>& vtCommandParams);
 
     bool TheFirstPart(CommandParam& cmdPara, std::string data);
-    bool TheSecondPart(CommandParam& cmdPara, std::string data);    
+    bool TheSecondPart(CommandParam& cmdPara, std::string data);
+    bool TheSecondPartFireTV(CommandParam& cmdPara, std::string data);
     bool ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen);
 public:
     void SetInternalCMDParams(DWORD dwResouceID);

+ 2 - 1
TCLCommand/TCLCommand/command.data

@@ -106,10 +106,11 @@ name=SetFireTVBTMac; option=None; head=AA; cmd=99; param=17; returnParam=false;
 name=SetFireTVDSN; option=None; head=AA; cmd=99; param=18; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=SetFireTVFairplay; option=None; head=AA FE; cmd=E9; param=0E; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=CreateFireTVDHA; option=None; head=AA; cmd=96; param=03; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
+name=SetBarcode; option=None; head=AA; cmd=71; param=/; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
+# FC指令需要另外处理;
 name=SetFireTVPlayready; option=None; head=AA FE; cmd=FC; param=00 00; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=SetFireTVLEK; option=None; head=AA FE; cmd=FC; param=00 02; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=SetFireTVPEK; option=None; head=AA FE; cmd=FC; param=00 01; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=SetFireTVHashkey; option=None; head=AA FE; cmd=FC; param=00 03; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
-name=SetBarcode; option=None; head=AA; cmd=71; param=/; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=SetFireTVPSN; option=None; head=AA; cmd=FC; param=00 05; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms
 name=SetFireTVYoutube; option=None; head=AA FE; cmd=FC; param=00 06; returnParam=false; readWaitTime=100ms; cmdWaitTime=100ms