diff --git a/tools/harness-thci/OpenThread.py b/tools/harness-thci/OpenThread.py index d536c9c31..0d94f8292 100644 --- a/tools/harness-thci/OpenThread.py +++ b/tools/harness-thci/OpenThread.py @@ -1145,6 +1145,10 @@ class OpenThreadTHCI(object): self, timeout * 2)) else: return False + + if self.IsBorderRouter: + self._waitBorderRoutingStabilize() + return True @API @@ -1609,6 +1613,30 @@ class OpenThreadTHCI(object): else: return False + @watched + def getNetworkData(self): + lines = self.__executeCommand('netdata show') + prefixes, routes, services = [], [], [] + classify = None + + for line in lines: + if line == 'Prefixes:': + classify = prefixes + elif line == 'Routes:': + classify = routes + elif line == 'Services:': + classify = services + elif line == 'Done': + classify = None + else: + classify.append(line) + + return { + 'Prefixes': prefixes, + 'Routes': routes, + 'Services': services, + } + @API def setNetworkIDTimeout(self, iNwkIDTimeOut): """set networkid timeout for Thread device @@ -3112,6 +3140,14 @@ class OpenThreadTHCI(object): def setLeaderWeight(self, iWeight=72): self.__executeCommand('leaderweight %d' % iWeight) + @watched + def isBorderRoutingEnabled(self): + try: + self.__executeCommand('br omrprefix') + return True + except CommandError: + return False + def __detectZephyr(self): """Detect if the device is running Zephyr and adapt in that case""" diff --git a/tools/harness-thci/OpenThread_BR.py b/tools/harness-thci/OpenThread_BR.py index b8566fe49..ac6747972 100644 --- a/tools/harness-thci/OpenThread_BR.py +++ b/tools/harness-thci/OpenThread_BR.py @@ -695,3 +695,30 @@ class OpenThread_BR(OpenThreadTHCI, IThci): """ self.externalCommissioner.MLR([sAddr], 0) return True + + @watched + def _waitBorderRoutingStabilize(self): + """ + Wait for Network Data to stabilize if BORDER_ROUTING is enabled. + """ + if not self.isBorderRoutingEnabled(): + return + + MAX_TIMEOUT = 30 + MIN_TIMEOUT = 15 + CHECK_INTERVAL = 3 + + time.sleep(MIN_TIMEOUT) + + lastNetData = self.getNetworkData() + for i in range((MAX_TIMEOUT - MIN_TIMEOUT) // CHECK_INTERVAL): + time.sleep(CHECK_INTERVAL) + curNetData = self.getNetworkData() + + # Wait until the Network Data is not changing, and there is OMR Prefix and External Routes available + if curNetData == lastNetData and len(curNetData['Prefixes']) > 0 and len(curNetData['Routes']) > 0: + break + + lastNetData = curNetData + + return lastNetData