mirror of
https://github.com/espressif/openthread.git
synced 2026-07-26 22:09:05 +00:00
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:
@@ -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__
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[]);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user