Add Thread Auto Start Support (#1268)

* Add Thread Auto Start Support

* Add compile-time option

* Return error in Windows API
This commit is contained in:
Nick Banks
2017-02-20 17:29:20 -08:00
committed by Jonathan Hui
parent 500dada64c
commit 64f5ab43fc
11 changed files with 230 additions and 13 deletions
@@ -677,9 +677,14 @@ typedef struct otCommissionConfig
#define IOCTL_OTLWF_OT_FACTORY_RESET \
OTLWF_CTL_CODE(192, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_THREAD_AUTO_START \
OTLWF_CTL_CODE(193, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aAutoStart
// OpenThread function IOCTL codes
#define MIN_OTLWF_IOCTL_FUNC_CODE 100
#define MAX_OTLWF_IOCTL_FUNC_CODE 192
#define MAX_OTLWF_IOCTL_FUNC_CODE 193
#endif //__OTLWFIOCTL_H__
+24
View File
@@ -1244,6 +1244,30 @@ otThreadStop(
return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_THREAD, (BOOLEAN)FALSE));
}
OTAPI
ThreadError
OTCALL
otThreadSetAutoStart(
_In_ otInstance *aInstance,
bool aStartAutomatically
)
{
if (aInstance == nullptr) return kThreadError_InvalidArgs;
return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_THREAD_AUTO_START, (BOOLEAN)(aStartAutomatically ? TRUE : FALSE)));
}
OTAPI
bool
OTCALL
otThreadGetAutoStart(
otInstance *aInstance
)
{
BOOLEAN Result = FALSE;
if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_THREAD_AUTO_START, &Result);
return Result != FALSE;
}
OTAPI
bool
OTCALL
+40 -1
View File
@@ -137,7 +137,8 @@ OTLWF_IOCTL_HANDLER IoCtls[] =
{ "IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_GET", REF_IOCTL_FUNC(otSendMgmtCommissionerGet) },
{ "IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_SET", REF_IOCTL_FUNC(otSendMgmtCommissionerSet) },
{ "IOCTL_OTLWF_OT_KEY_SWITCH_GUARDTIME", REF_IOCTL_FUNC_WITH_TUN(otKeySwitchGuardtime) },
{ "IOCTL_OTLWF_OT_FACTORY_RESET", REF_IOCTL_FUNC(otFactoryReset) }
{ "IOCTL_OTLWF_OT_FACTORY_RESET", REF_IOCTL_FUNC(otFactoryReset) },
{ "IOCTL_OTLWF_OT_THREAD_AUTO_START", REF_IOCTL_FUNC(otThreadAutoStart) }
};
static_assert(ARRAYSIZE(IoCtls) == (MAX_OTLWF_IOCTL_FUNC_CODE - MIN_OTLWF_IOCTL_FUNC_CODE) + 1,
@@ -6072,3 +6073,41 @@ otLwfTunIoCtl_otKeySwitchGuardtime_Handler(
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfIoCtl_otThreadAutoStart(
_In_ PMS_FILTER pFilter,
_In_reads_bytes_(InBufferLength)
PUCHAR InBuffer,
_In_ ULONG InBufferLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (InBufferLength >= sizeof(BOOLEAN))
{
status =
ThreadErrorToNtstatus(
otThreadSetAutoStart(
pFilter->otCtx,
*(BOOLEAN*)InBuffer != FALSE)
);
*OutBufferLength = 0;
}
else if (*OutBufferLength >= sizeof(BOOLEAN))
{
*(BOOLEAN*)OutBuffer = otThreadGetAutoStart(pFilter->otCtx) ? TRUE : FALSE;
*OutBufferLength = sizeof(BOOLEAN);
status = STATUS_SUCCESS;
}
else
{
*OutBufferLength = 0;
}
return status;
}
@@ -224,5 +224,6 @@ DECL_IOCTL_FUNC(otSendMgmtCommissionerGet);
DECL_IOCTL_FUNC(otSendMgmtCommissionerSet);
DECL_IOCTL_FUNC_WITH_TUN2(otKeySwitchGuardtime);
DECL_IOCTL_FUNC(otFactoryReset);
DECL_IOCTL_FUNC(otThreadAutoStart);
#endif // _IOCONTROL_H
+21
View File
@@ -315,6 +315,27 @@ OTAPI ThreadError OTCALL otThreadStart(otInstance *aInstance);
*/
OTAPI ThreadError OTCALL otThreadStop(otInstance *aInstance);
/**
* This function configures the Thread stack to automatically start on reinitialization.
* It has no effect on the current Thread state.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aStartAutomatically TRUE to automatically start; FALSE to not automatically start.
*
*/
OTAPI ThreadError OTCALL otThreadSetAutoStart(otInstance *aInstance, bool aStartAutomatically);
/**
* This function queries if the Thread stack is configured to automatically start on reinitialization.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval TRUE It is configured to automatically start.
* @retval FALSE It is not configured to automatically start.
*
*/
OTAPI bool OTCALL otThreadGetAutoStart(otInstance *aInstance);
/**
* This function indicates whether a node is the only router on the network.
*
+29
View File
@@ -7,6 +7,7 @@ OpenThread test scripts use the CLI to execute test cases.
## OpenThread Command List
* [autostart](#autostart)
* [blacklist](#blacklist)
* [channel](#channel)
* [child](#child-list)
@@ -63,6 +64,34 @@ OpenThread test scripts use the CLI to execute test cases.
## OpenThread Command Details
### autostart true
Automatically start Thread on initialization.
```bash
> autostart true
Done
```
### autostart false
Don't automatically start Thread on initialization.
```bash
> autostart false
Done
```
### autostart
Show the status of automatically starting Thread on initialization.
```bash
> autostart
false
Done
```
### blacklist
List the blacklist entries.
+32
View File
@@ -67,6 +67,7 @@ namespace Cli {
const struct Command Interpreter::sCommands[] =
{
{ "help", &Interpreter::ProcessHelp },
{ "autostart", &Interpreter::ProcessAutoStart },
{ "blacklist", &Interpreter::ProcessBlacklist },
{ "bufferinfo", &Interpreter::ProcessBufferInfo },
{ "channel", &Interpreter::ProcessChannel },
@@ -247,6 +248,37 @@ void Interpreter::ProcessHelp(int argc, char *argv[])
(void)argv;
}
void Interpreter::ProcessAutoStart(int argc, char *argv[])
{
ThreadError error = kThreadError_None;
if (argc == 0)
{
if (otThreadGetAutoStart(mInstance))
{
sServer->OutputFormat("true\r\n");
}
else
{
sServer->OutputFormat("false\r\n");
}
}
else if (strcmp(argv[0], "true") == 0)
{
error = otThreadSetAutoStart(mInstance, true);
}
else if (strcmp(argv[0], "false") == 0)
{
error = otThreadSetAutoStart(mInstance, false);
}
else
{
error = kThreadError_InvalidArgs;
}
AppendResult(error);
}
void Interpreter::ProcessBlacklist(int argc, char *argv[])
{
ThreadError error = kThreadError_None;
+1
View File
@@ -141,6 +141,7 @@ private:
void OutputBytes(const uint8_t *aBytes, uint8_t aLength);
void ProcessHelp(int argc, char *argv[]);
void ProcessAutoStart(int argc, char *argv[]);
void ProcessBufferInfo(int argc, char *argv[]);
void ProcessBlacklist(int argc, char *argv[]);
void ProcessChannel(int argc, char *argv[]);
+6 -5
View File
@@ -44,11 +44,12 @@ extern "C" {
*/
enum
{
kKeyActiveDataset = 0x0001,
kKeyPendingDataset = 0x0002,
kKeyNetworkInfo = 0x0003,
kKeyParentInfo = 0x0004,
kKeyChildInfo = 0x0005,
kKeyActiveDataset = 0x0001,
kKeyPendingDataset = 0x0002,
kKeyNetworkInfo = 0x0003,
kKeyParentInfo = 0x0004,
kKeyChildInfo = 0x0005,
kKeyThreadAutoStart = 0x0006,
};
#ifdef __cplusplus
+10
View File
@@ -589,4 +589,14 @@
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN 0
#endif
/**
* @def OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
*
* Define to 1 if you want to enable auto start logic.
*
*/
#ifndef OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
#define OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT 1
#endif
#endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_
+60 -6
View File
@@ -49,6 +49,7 @@
#include <common/logging.hpp>
#include <common/message.hpp>
#include <common/new.hpp>
#include <common/settings.hpp>
#include <common/tasklet.hpp>
#include <common/timer.hpp>
#include <crypto/mbedtls.hpp>
@@ -1207,6 +1208,31 @@ ThreadError otSetPreferredRouterId(otInstance *aInstance, uint8_t aRouterId)
return aInstance->mThreadNetif.GetMle().SetPreferredRouterId(aRouterId);
}
void otInstancePostConstructor(otInstance *aInstance)
{
// restore datasets and network information
otPlatSettingsInit(aInstance);
aInstance->mThreadNetif.GetMle().Restore();
#if OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
// If auto start is configured, do that now
if (otThreadGetAutoStart(aInstance))
{
if (otInterfaceUp(aInstance) == kThreadError_None)
{
// Only try to start Thread if we could bring up the interface
if (otThreadStart(aInstance) != kThreadError_None)
{
// Bring the interface down if Thread failed to start
otInterfaceDown(aInstance);
}
}
}
#endif
}
#ifdef OPENTHREAD_MULTIPLE_INSTANCE
otInstance *otInstanceInit(void *aInstanceBuffer, size_t *aInstanceBufferSize)
@@ -1226,9 +1252,8 @@ otInstance *otInstanceInit(void *aInstanceBuffer, size_t *aInstanceBufferSize)
// Construct the context
aInstance = new(aInstanceBuffer)otInstance();
// restore datasets and network information
otPlatSettingsInit(aInstance);
aInstance->mThreadNetif.GetMle().Restore();
// Execute post constructor operations
otInstancePostConstructor(aInstance);
exit:
@@ -1249,9 +1274,8 @@ otInstance *otInstanceInit()
// Construct the context
sInstance = new(&sInstanceRaw)otInstance();
// restore datasets and network information
otPlatSettingsInit(sInstance);
sInstance->mThreadNetif.GetMle().Restore();
// Execute post constructor operations
otInstancePostConstructor(sInstance);
exit:
@@ -1370,6 +1394,36 @@ ThreadError otThreadStop(otInstance *aInstance)
return error;
}
ThreadError otThreadSetAutoStart(otInstance *aInstance, bool aStartAutomatically)
{
#if OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
uint8_t autoStart = aStartAutomatically ? 1 : 0;
return otPlatSettingsSet(aInstance, kKeyThreadAutoStart, &autoStart, sizeof(autoStart));
#else
(void)aInstance;
(void)aStartAutomatically;
return kThreadError_NotImplemented;
#endif
}
bool otThreadGetAutoStart(otInstance *aInstance)
{
#if OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
uint8_t autoStart = 0;
uint16_t autoStartLength = sizeof(autoStart);
if (otPlatSettingsGet(aInstance, kKeyThreadAutoStart, 0, &autoStart, &autoStartLength) != kThreadError_None)
{
autoStart = 0;
}
return autoStart != 0;
#else
(void)aInstance;
return false;
#endif
}
bool otIsSingleton(otInstance *aInstance)
{
return aInstance->mThreadNetif.GetMle().IsSingleton();