diff --git a/tools/harness-thci/OpenThread.py b/tools/harness-thci/OpenThread.py index db145ab5a..330a556c4 100644 --- a/tools/harness-thci/OpenThread.py +++ b/tools/harness-thci/OpenThread.py @@ -200,6 +200,7 @@ class OpenThreadTHCI(object): IsBorderRouter = False IsHost = False IsBeingTestedAsCommercialBBR = False + IsReference20200818 = False externalCommissioner = None _update_router_status = False @@ -441,6 +442,9 @@ class OpenThreadTHCI(object): self.UIStatusMsg) ModuleHelper.WriteIntoDebugLogger('Err: OpenThread device Firmware not matching..') + # Make this class compatible with Thread referenece 20200818 + self.__detectReference20200818() + def __repr__(self): if self.connectType == 'ip': return '[%s:%d]' % (self.telnetIp, self.telnetPort) @@ -602,11 +606,11 @@ class OpenThreadTHCI(object): # reset if self.isPowerDown: if self._addressfilterMode == 'allowlist': - if self.__setAddressfilterMode('allowlist'): + if self.__setAddressfilterMode(self.__replaceCommands['allowlist']): for addr in self._addressfilterSet: self.addAllowMAC(addr) elif self._addressfilterMode == 'denylist': - if self.__setAddressfilterMode('denylist'): + if self.__setAddressfilterMode(self.__replaceCommands['denylist']): for addr in self._addressfilterSet: self.addBlockedMAC(addr) @@ -975,14 +979,16 @@ class OpenThreadTHCI(object): True: successful to set the Thread network key False: fail to set the Thread network key """ + cmdName = self.__replaceCommands['networkkey'] + if not isinstance(key, str): networkKey = self.__convertLongToHex(key, 32) - cmd = 'networkkey %s' % networkKey - datasetCmd = 'dataset networkkey %s' % networkKey + cmd = '%s %s' % (cmdName, networkKey) + datasetCmd = 'dataset %s %s' % (cmdName, networkKey) else: networkKey = key - cmd = 'networkkey %s' % networkKey - datasetCmd = 'dataset networkkey %s' % networkKey + cmd = '%s %s' % (cmdName, networkKey) + datasetCmd = 'dataset %s %s' % (cmdName, networkKey) self.networkKey = networkKey self.hasActiveDatasetToCommit = True @@ -1010,7 +1016,7 @@ class OpenThreadTHCI(object): return True if self._addressfilterMode != 'denylist': - if self.__setAddressfilterMode('denylist'): + if self.__setAddressfilterMode(self.__replaceCommands['denylist']): self._addressfilterMode = 'denylist' cmd = 'macfilter addr add %s' % macAddr @@ -1040,7 +1046,7 @@ class OpenThreadTHCI(object): macAddr = self.__convertLongToHex(xEUI) if self._addressfilterMode != 'allowlist': - if self.__setAddressfilterMode('allowlist'): + if self.__setAddressfilterMode(self.__replaceCommands['allowlist']): self._addressfilterMode = 'allowlist' cmd = 'macfilter addr add %s' % macAddr @@ -1168,6 +1174,9 @@ class OpenThreadTHCI(object): else: pass + if self.IsReference20200818: + mode = 's' if mode == '-' else mode + 's' + # set Thread device mode with a given role self.__setDeviceMode(mode) @@ -1323,8 +1332,14 @@ class OpenThreadTHCI(object): hop_limit: hop limit """ - cmd = 'ping %s %s 1 1 %d %d' % (strDestination, str(ilength), hop_limit, timeout) + cmd = 'ping %s %s' % (strDestination, str(ilength)) + if not self.IsReference20200818: + cmd += ' 1 1 %d %d' % (hop_limit, timeout) + self.__executeCommand(cmd) + if self.IsReference20200818: + # wait echo reply + self.sleep(6) # increase delay temporarily (+5s) to remedy TH's delay updates @API def multicast_Ping(self, destination, length=20): @@ -1588,7 +1603,8 @@ class OpenThreadTHCI(object): cmd = 'prefix remove %s/64' % prefixEntry if self.__executeCommand(cmd)[-1] == 'Done': # send server data ntf to leader - return self.__executeCommand('netdata register')[-1] == 'Done' + cmd = self.__replaceCommands['netdata register'] + return self.__executeCommand(cmd)[-1] == 'Done' else: return False @@ -1670,7 +1686,8 @@ class OpenThreadTHCI(object): return True else: # send server data ntf to leader - return self.__executeCommand('netdata register')[-1] == 'Done' + cmd = self.__replaceCommands['netdata register'] + return self.__executeCommand(cmd)[-1] == 'Done' else: return False @@ -1822,7 +1839,8 @@ class OpenThreadTHCI(object): if self.__executeCommand(cmd)[-1] == 'Done': # send server data ntf to leader - return self.__executeCommand('netdata register')[-1] == 'Done' + cmd = self.__replaceCommands['netdata register'] + return self.__executeCommand(cmd)[-1] == 'Done' @API def getNeighbouringRouters(self): @@ -1969,7 +1987,8 @@ class OpenThreadTHCI(object): True: successful to set the Partition ID False: fail to set the Partition ID """ - cmd = 'partitionid preferred %s' % (str(hex(partationId)).rstrip('L')) + cmd = self.__replaceCommands['partitionid preferred'] + ' ' + cmd += str(hex(partationId)).rstrip('L') return self.__executeCommand(cmd)[-1] == 'Done' @API @@ -2419,7 +2438,7 @@ class OpenThreadTHCI(object): if len(TLVs) != 0: tlvs = ''.join('%02x' % tlv for tlv in TLVs) - cmd += ' -x ' + cmd += ' ' + self.__replaceCommands['-x'] + ' ' cmd += tlvs return self.__executeCommand(cmd)[-1] == 'Done' @@ -2476,7 +2495,7 @@ class OpenThreadTHCI(object): cmd += str(sMeshLocalPrefix) if xMasterKey is not None: - cmd += ' networkkey ' + cmd += ' ' + self.__replaceCommands['networkkey'] + ' ' key = self.__convertLongToHex(xMasterKey, 32) cmd += key @@ -2492,7 +2511,7 @@ class OpenThreadTHCI(object): if (sPSKc is not None or listSecurityPolicy is not None or xCommissioningSessionId is not None or xTmfPort is not None or xSteeringData is not None or xBorderRouterLocator is not None or BogusTLV is not None): - cmd += ' -x ' + cmd += ' ' + self.__replaceCommands['-x'] + ' ' if sPSKc is not None: cmd += '0410' @@ -2602,7 +2621,7 @@ class OpenThreadTHCI(object): if len(TLVs) != 0: tlvs = ''.join('%02x' % tlv for tlv in TLVs) - cmd += ' -x ' + cmd += ' ' + self.__replaceCommands['-x'] + ' ' cmd += tlvs return self.__executeCommand(cmd)[-1] == 'Done' @@ -2651,7 +2670,7 @@ class OpenThreadTHCI(object): cmd += str(xPanId) if xMasterKey is not None: - cmd += ' networkkey ' + cmd += ' ' + self.__replaceCommands['networkkey'] + ' ' key = self.__convertLongToHex(xMasterKey, 32) cmd += key @@ -2665,7 +2684,7 @@ class OpenThreadTHCI(object): cmd += self._deviceEscapeEscapable(str(sNetworkName)) if xCommissionerSessionId is not None: - cmd += ' -x ' + cmd += ' ' + self.__replaceCommands['-x'] + ' ' cmd += '0b02' sessionid = str(hex(xCommissionerSessionId))[2:] @@ -2688,7 +2707,7 @@ class OpenThreadTHCI(object): if len(TLVs) != 0: tlvs = ''.join('%02x' % tlv for tlv in TLVs) - cmd += ' -x ' + cmd += ' ' + self.__replaceCommands['-x'] + ' ' cmd += tlvs return self.__executeCommand(cmd)[-1] == 'Done' @@ -2732,7 +2751,7 @@ class OpenThreadTHCI(object): cmd += str(hex(xBorderRouterLocator)) if xChannelTlv is not None: - cmd += ' -x ' + cmd += ' ' + self.__replaceCommands['-x'] + ' ' cmd += '000300' + '%04x' % xChannelTlv return self.__executeCommand(cmd)[-1] == 'Done' @@ -2878,7 +2897,8 @@ class OpenThreadTHCI(object): if ReRegDelay is not None: self.bbrReRegDelay = ReRegDelay - self.__executeCommand('netdata register') + cmd = self.__replaceCommands['netdata register'] + self.__executeCommand(cmd) return ret @@ -3209,6 +3229,31 @@ class OpenThreadTHCI(object): except CommandError: self._lineSepX = LINESEPX + def __detectReference20200818(self): + """Detect if the device is a Thread reference 20200818 """ + + # Running `version api` in Thread reference 20200818 is equivalent to running `version` + # It will not output an API number + self.IsReference20200818 = not self.__executeCommand('version api')[0].isdigit() + + if self.IsReference20200818: + self.__replaceCommands = { + '-x': 'binary', + 'allowlist': 'whitelist', + 'denylist': 'blacklist', + 'netdata register': 'netdataregister', + 'networkkey': 'masterkey', + 'partitionid preferred': 'leaderpartitionid', + } + else: + + class IdentityDict: + + def __getitem__(self, key): + return key + + self.__replaceCommands = IdentityDict() + def __discoverDeviceCapability(self): """Discover device capability according to version""" thver = self.__executeCommand('thread version')[0]