Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 70a44a7

Browse files
author
Jay Logue
authored
Merge pull request #538 from erjiaqing/weave-br
[Thread] Support Weave thread border routing
2 parents d7939b3 + 143bab8 commit 70a44a7

File tree

3 files changed

+130
-8
lines changed

3 files changed

+130
-8
lines changed

src/adaptations/device-layer/LwIP/WarmSupport.cpp

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
#include <Weave/DeviceLayer/ThreadStackManager.h>
3737
#include <Weave/DeviceLayer/OpenThread/OpenThreadUtils.h>
3838
#include <openthread/ip6.h>
39+
#if WARM_CONFIG_SUPPORT_THREAD_ROUTING
40+
#include <openthread/border_router.h>
41+
#endif // WARM_CONFIG_SUPPORT_THREAD_ROUTING
3942
#endif // WARM_CONFIG_SUPPORT_THREAD
4043

4144

@@ -358,27 +361,132 @@ PlatformResult AddRemoveThreadAddress(InterfaceType inInterfaceType, const Inet:
358361

359362
#if WARM_CONFIG_SUPPORT_THREAD_ROUTING
360363

361-
#error "Weave Thread router support not implemented"
362-
363364
PlatformResult StartStopThreadAdvertisement(InterfaceType inInterfaceType, const Inet::IPPrefix &inPrefix, bool inStart)
364365
{
365-
// TODO: implement me
366+
WEAVE_ERROR err = WEAVE_NO_ERROR;
367+
otError otErr;
368+
otBorderRouterConfig brConfig;
369+
370+
VerifyOrExit(inInterfaceType == kInterfaceTypeThread, err = WEAVE_ERROR_INVALID_ARGUMENT);
371+
VerifyOrExit((inPrefix.Length & 7) == 0, err = WEAVE_ERROR_INVALID_ADDRESS);
372+
373+
ThreadStackMgrImpl().LockThreadStack();
374+
375+
brConfig.mConfigure = false;
376+
brConfig.mDefaultRoute = false;
377+
brConfig.mDhcp = false;
378+
brConfig.mOnMesh = true;
379+
brConfig.mPreference = 0;
380+
brConfig.mPreferred = true;
381+
brConfig.mPrefix.mLength = inPrefix.Length;
382+
brConfig.mRloc16 = otThreadGetRloc16(ThreadStackMgrImpl().OTInstance());
383+
brConfig.mSlaac = false;
384+
brConfig.mStable = true;
385+
memcpy(brConfig.mPrefix.mPrefix.mFields.m8, inPrefix.IPAddr.Addr, sizeof(brConfig.mPrefix.mPrefix.mFields));
386+
387+
if (inStart)
388+
{
389+
otErr = otBorderRouterAddOnMeshPrefix(ThreadStackMgrImpl().OTInstance(), &brConfig);
390+
}
391+
else
392+
{
393+
otErr = otBorderRouterRemoveOnMeshPrefix(ThreadStackMgrImpl().OTInstance(), &brConfig.mPrefix);
394+
if (otErr == OT_ERROR_NOT_FOUND)
395+
{
396+
WeaveLogProgress(DeviceLayer, "otBorderRouterRemoveOnMeshPrefix: already removed");
397+
otErr = OT_ERROR_NONE;
398+
}
399+
}
400+
401+
ThreadStackMgrImpl().UnlockThreadStack();
402+
403+
err = MapOpenThreadError(otErr);
404+
405+
exit:
406+
if (err == WEAVE_NO_ERROR)
407+
{
408+
#if WEAVE_PROGRESS_LOGGING
409+
char ipAddrStr[INET6_ADDRSTRLEN];
410+
inPrefix.IPAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
411+
WeaveLogProgress(DeviceLayer, "OpenThread OnMesh Prefix %s: %s/%d",
412+
(inStart) ? "Added" : "Removed",
413+
ipAddrStr, inPrefix.Length);
414+
#endif // WEAVE_PROGRESS_LOGGING
415+
}
416+
else
417+
{
418+
WeaveLogError(DeviceLayer, "StartStopThreadAdvertisement() failed: %s", ::nl::ErrorStr(err));
419+
}
420+
421+
return (err == WEAVE_NO_ERROR) ? kPlatformResultSuccess : kPlatformResultFailure;
366422
}
367423

368424
#endif // WARM_CONFIG_SUPPORT_THREAD_ROUTING
369425

370426
#if WARM_CONFIG_SUPPORT_BORDER_ROUTING
371427

372-
#error "Weave border router support not implemented"
373-
374428
PlatformResult AddRemoveThreadRoute(InterfaceType inInterfaceType, const Inet::IPPrefix &inPrefix, RoutePriority inPriority, bool inAdd)
375429
{
376-
// TODO: implement me
430+
otError otErr;
431+
otExternalRouteConfig routeConfig;
432+
433+
int ot_priority = OT_ROUTE_PREFERENCE_HIGH;
434+
switch (inPriority)
435+
{
436+
case kRoutePriorityLow:
437+
ot_priority = OT_ROUTE_PREFERENCE_LOW;
438+
break;
439+
case kRoutePriorityHigh:
440+
ot_priority = OT_ROUTE_PREFERENCE_HIGH;
441+
break;
442+
case kRoutePriorityMedium:
443+
// Let's set route priority to medium by default.
444+
default:
445+
ot_priority = OT_ROUTE_PREFERENCE_MED;
446+
break;
447+
}
448+
449+
ThreadStackMgrImpl().LockThreadStack();
450+
451+
otBorderRouterRegister(ThreadStackMgrImpl().OTInstance());
452+
453+
memcpy(routeConfig.mPrefix.mPrefix.mFields.m8, inPrefix.IPAddr.Addr, sizeof(routeConfig.mPrefix.mPrefix.mFields));
454+
routeConfig.mPrefix.mLength = inPrefix.Length;
455+
routeConfig.mStable = true;
456+
routeConfig.mPreference = ot_priority;
457+
458+
if (inAdd)
459+
{
460+
otErr = otBorderRouterAddRoute(ThreadStackMgrImpl().OTInstance(), &routeConfig);
461+
}
462+
else
463+
{
464+
otErr = otBorderRouterRemoveRoute(ThreadStackMgrImpl().OTInstance(), &routeConfig.mPrefix);
465+
}
466+
467+
ThreadStackMgrImpl().UnlockThreadStack();
468+
469+
if (otErr == OT_ERROR_NONE)
470+
{
471+
#if WEAVE_PROGRESS_LOGGING
472+
char ipAddrStr[INET6_ADDRSTRLEN];
473+
inPrefix.IPAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
474+
WeaveLogProgress(DeviceLayer, "OpenThread Border Router Route %s: %s/%d",
475+
(inAdd) ? "Added" : "Removed",
476+
ipAddrStr, inPrefix.Length);
477+
#endif // WEAVE_PROGRESS_LOGGING
478+
}
479+
else
480+
{
481+
WeaveLogError(DeviceLayer, "AddRemoveThreadRoute() failed: %s", ::nl::ErrorStr(MapOpenThreadError(otErr)));
482+
}
483+
484+
return (otErr == OT_ERROR_NONE) ? kPlatformResultSuccess : kPlatformResultFailure;
377485
}
378486

379487
PlatformResult SetThreadRoutePriority(InterfaceType inInterfaceType, const Inet::IPPrefix &inPrefix, RoutePriority inPriority)
380488
{
381-
// TODO: implement me
489+
return AddRemoveThreadRoute(inInterfaceType, inPrefix, inPriority, true);
382490
}
383491

384492
#endif // WARM_CONFIG_SUPPORT_BORDER_ROUTING

src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConnectivityManagerImpl_Thread.ipp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ void GenericConnectivityManagerImpl_Thread<ImplClass>::_OnPlatformEvent(const We
6262
{
6363
UpdateServiceConnectivity();
6464
}
65+
66+
#if WARM_CONFIG_SUPPORT_THREAD_ROUTING
67+
const bool threadRoleChanged = (event->Type == DeviceEventType::kThreadStateChange &&
68+
event->ThreadStateChange.RoleChanged);
69+
if (threadRoleChanged)
70+
{
71+
ConnectivityManager::ThreadDeviceType deviceType = ThreadStackMgr().GetThreadDeviceType();
72+
nl::Weave::Warm::InterfaceState interfaceState = (deviceType == ConnectivityManager::ThreadDeviceType::kThreadDeviceType_Router)
73+
? nl::Weave::Warm::kInterfaceStateUp
74+
: nl::Weave::Warm::kInterfaceStateDown;
75+
Warm::ThreadRoutingStateChange(interfaceState);
76+
}
77+
#endif // WARM_CONFIG_SUPPORT_THREAD_ROUTING
78+
6579
}
6680

6781
template<class ImplClass>

src/warm/WarmCore.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ static PlatformResult ThreadAdvertisementAction(ActionType inAction, bool inActi
836836
{
837837
Inet::IPPrefix prefix;
838838

839-
MakePrefix(inGlobalId, 0, kGlobalULAPrefixLength, prefix);
839+
MakePrefix(inGlobalId, kWeaveSubnetId_ThreadMesh, kThreadULAAddressPrefixLength, prefix);
840840

841841
return Platform::StartStopThreadAdvertisement(kInterfaceTypeThread, prefix, inActivate);
842842
}

0 commit comments

Comments
 (0)