mirror of
https://github.com/espressif/openthread.git
synced 2026-09-17 22:50:07 +00:00
Windows App Updates (#1431)
* Initial new API helpers * Finish up API helper * Update App to use new API helpers * More cleanup and added support for preferred router ID * Clean up state change handlers * Add logging * Some more clean up and redesign * Added small readme for Windows App.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
@@ -59,6 +59,8 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\examples\apps\windows\otAdapter.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\otApi.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\pch.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\App.xaml.h">
|
||||
<DependentUpon>..\..\examples\apps\windows\App.xaml</DependentUpon>
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
<ClInclude Include="..\..\examples\apps\windows\pch.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\App.xaml.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\MainPage.xaml.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\otAdapter.h" />
|
||||
<ClInclude Include="..\..\examples\apps\windows\otApi.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\LockScreenLogo.scale-200.png">
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
/>
|
||||
<TextBox
|
||||
Name="InterfaceConfigKey"
|
||||
Text="Pas$W0rd"
|
||||
Text="00112233445566778899aabbccddeeff"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
FontSize="18"
|
||||
@@ -130,9 +130,9 @@
|
||||
Name="InterfaceConfigMaxChildren"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Minimum="11"
|
||||
Maximum="26"
|
||||
Value="15"
|
||||
Minimum="0"
|
||||
Maximum="32"
|
||||
Value="16"
|
||||
VerticalAlignment="Center"
|
||||
/>
|
||||
<TextBlock
|
||||
@@ -147,7 +147,7 @@
|
||||
Grid.Column="1"
|
||||
Minimum="11"
|
||||
Maximum="24"
|
||||
Value="5"
|
||||
Value="11"
|
||||
VerticalAlignment="Center"
|
||||
/>
|
||||
<StackPanel
|
||||
|
||||
@@ -42,366 +42,356 @@ using namespace Windows::UI::Xaml::Input;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
|
||||
MainPage^ MainPage::Current = nullptr;
|
||||
|
||||
#define GUID_FORMAT L"{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}"
|
||||
#define GUID_ARG(guid) guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]
|
||||
|
||||
#define MAC8_FORMAT L"%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X"
|
||||
#define MAC8_ARG(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]
|
||||
|
||||
PCWSTR ToString(otDeviceRole role)
|
||||
void otLog(PCSTR aFormat, ...)
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case kDeviceRoleOffline: return L"Offline";
|
||||
case kDeviceRoleDisabled: return L"Disabled";
|
||||
case kDeviceRoleDetached: return L"Disconnected";
|
||||
case kDeviceRoleChild: return L"Connected - Child";
|
||||
case kDeviceRoleRouter: return L"Connected - Router";
|
||||
case kDeviceRoleLeader: return L"Connected - Leader";
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, aFormat);
|
||||
|
||||
return L"Unknown Role State";
|
||||
CHAR logString[512] = { 0 };
|
||||
int charsWritten = vsprintf_s(logString, sizeof(logString), aFormat, args);
|
||||
if (charsWritten > 0) OutputDebugStringA(logString);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void OTCALL
|
||||
ThreadDeviceAvailabilityCallback(
|
||||
bool /* aAdded */,
|
||||
const GUID* /* aDeviceGuid */,
|
||||
_In_ void* /* aContext */
|
||||
)
|
||||
{
|
||||
// Trigger the interface list to update
|
||||
MainPage::Current->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(
|
||||
[=]() {
|
||||
MainPage::Current->BuildInterfaceList();
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void OTCALL
|
||||
ThreadStateChangeCallback(
|
||||
uint32_t aFlags,
|
||||
_In_ void* /* aContext */
|
||||
)
|
||||
{
|
||||
if ((aFlags & OT_NET_ROLE) != 0)
|
||||
{
|
||||
// Trigger the interface list to update
|
||||
MainPage::Current->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(
|
||||
[=]() {
|
||||
MainPage::Current->BuildInterfaceList();
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MainPage::MainPage()
|
||||
MainPage::MainPage() : _otApi(nullptr)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MainPage::Current = this;
|
||||
_isFullScreen = false;
|
||||
|
||||
_apiInstance = nullptr;
|
||||
InterfaceConfigCancelButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->_curAdapter = nullptr;
|
||||
}
|
||||
);
|
||||
InterfaceConfigOkButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
ConnectNetwork(_currentInterface);
|
||||
this->InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->ConnectNetwork(_curAdapter);
|
||||
this->_curAdapter = nullptr;
|
||||
}
|
||||
);
|
||||
InterfaceDetailsCloseButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
|
||||
{
|
||||
Window::Current->CoreWindow->VisibilityChanged += ref new TypedEventHandler<Windows::UI::Core::CoreWindow^, Windows::UI::Core::VisibilityChangedEventArgs^>(this, &MainPage::OnVisibilityChanged);
|
||||
|
||||
SizeChanged += ref new SizeChangedEventHandler(this, &MainPage::OnWindowSizeChanged);
|
||||
Loaded += ref new RoutedEventHandler(this, &MainPage::OnLoaded);
|
||||
Unloaded += ref new RoutedEventHandler(this, &MainPage::OnUnloaded);
|
||||
|
||||
_isVisible = Window::Current->CoreWindow->Visible;
|
||||
}
|
||||
|
||||
void MainPage::OnLoaded(Object^ sender, RoutedEventArgs^ e)
|
||||
{
|
||||
// Initialize api handle
|
||||
_apiInstance = otApiInit();
|
||||
if (_apiInstance)
|
||||
try
|
||||
{
|
||||
// Register for device availability callbacks
|
||||
otSetDeviceAvailabilityChangedCallback(ApiInstance, ThreadDeviceAvailabilityCallback, nullptr);
|
||||
// Initialize api handle
|
||||
_otApi = ref new otApi();
|
||||
|
||||
// Build the initial list
|
||||
BuildInterfaceList();
|
||||
// Register for state changes
|
||||
_adapterArrivalToken =
|
||||
_otApi->AdapterArrival +=
|
||||
ref new otAdapterArrivalDelegate(
|
||||
[=](otAdapter^ adapter) {
|
||||
// Update on the UI thread
|
||||
this->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(
|
||||
[=]() {
|
||||
this->AddAdapterToList(adapter);
|
||||
}));
|
||||
});
|
||||
|
||||
// Enumerate the adapter list
|
||||
auto adapters = _otApi->GetAdapters();
|
||||
for (auto&& adapter : adapters) {
|
||||
AddAdapterToList(adapter);
|
||||
}
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::OnUnloaded(Object^ sender, RoutedEventArgs^ e)
|
||||
{
|
||||
// Unregister for callbacks
|
||||
otSetDeviceAvailabilityChangedCallback(ApiInstance, nullptr, nullptr);
|
||||
if (_otApi)
|
||||
{
|
||||
// Unregister
|
||||
_otApi->AdapterArrival -= _adapterArrivalToken;
|
||||
|
||||
// Clean up api handle
|
||||
otApiFinalize(ApiInstance);
|
||||
_apiInstance = nullptr;
|
||||
// Clear current adapter
|
||||
_curAdapter = nullptr;
|
||||
|
||||
// Remove the adapter list
|
||||
auto adapters = _otApi->GetAdapters();
|
||||
for (auto&& adapter : adapters) {
|
||||
adapter->InvokeAdapterRemoval();
|
||||
}
|
||||
|
||||
// Free the api handle
|
||||
_otApi = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::OnResuming()
|
||||
{
|
||||
}
|
||||
|
||||
void MainPage::OnWindowSizeChanged(Object^ sender, SizeChangedEventArgs^ args)
|
||||
void MainPage::ShowInterfaceDetails(otAdapter^ adapter)
|
||||
{
|
||||
_windowSize = args->NewSize;
|
||||
}
|
||||
|
||||
void MainPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ coreWindow, Windows::UI::Core::VisibilityChangedEventArgs^ args)
|
||||
{
|
||||
// The Visible property is toggled when the app enters and exits minimized state.
|
||||
// But obscuring the app with another window does not change Visible state, oddly enough.
|
||||
_isVisible = args->Visible;
|
||||
}
|
||||
|
||||
void MainPage::ShowInterfaceDetails(Platform::Guid InterfaceGuid)
|
||||
{
|
||||
if (ApiInstance == nullptr) return;
|
||||
|
||||
GUID deviceGuid = InterfaceGuid;
|
||||
auto device = otInstanceInit(ApiInstance, &deviceGuid);
|
||||
|
||||
auto extendedAddress = otLinkGetExtendedAddress(device);
|
||||
if (extendedAddress)
|
||||
try
|
||||
{
|
||||
WCHAR szMac[256] = { 0 };
|
||||
swprintf_s(szMac, 256, MAC8_FORMAT, MAC8_ARG(extendedAddress));
|
||||
InterfaceMacAddress->Text = ref new String(szMac);
|
||||
InterfaceMacAddress->Text = otApi::ToString(adapter->ExtendedAddress);
|
||||
InterfaceML_EID->Text = adapter->MeshLocalEid->ToString();
|
||||
InterfaceRLOC->Text = otApi::ToString(adapter->Rloc16);
|
||||
|
||||
otFreeMemory(extendedAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterfaceMacAddress->Text = L"ERROR";
|
||||
}
|
||||
|
||||
auto ml_eid = otThreadGetMeshLocalEid(device);
|
||||
if (ml_eid)
|
||||
{
|
||||
WCHAR szAddress[46] = { 0 };
|
||||
RtlIpv6AddressToStringW((const PIN6_ADDR)ml_eid, szAddress);
|
||||
InterfaceML_EID->Text = ref new String(szAddress);
|
||||
|
||||
otFreeMemory(ml_eid);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterfaceML_EID->Text = L"ERROR";
|
||||
}
|
||||
|
||||
auto rloc16 = otThreadGetRloc16(device);
|
||||
WCHAR szRloc[16] = { 0 };
|
||||
swprintf_s(szRloc, 16, L"%4x", rloc16);
|
||||
InterfaceRLOC->Text = ref new String(szRloc);
|
||||
|
||||
if (otThreadGetDeviceRole(device) > kDeviceRoleChild)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
otChildInfo childInfo;
|
||||
while (kThreadError_None == otThreadGetChildInfoByIndex(device, index, &childInfo))
|
||||
if (adapter->State > otThreadState::Child)
|
||||
{
|
||||
index++;
|
||||
uint8_t index = 0;
|
||||
otChildInfo childInfo;
|
||||
while (kThreadError_None == otThreadGetChildInfoByIndex((otInstance*)(void*)adapter->RawHandle, index, &childInfo))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
WCHAR szText[64] = { 0 };
|
||||
swprintf_s(szText, 64, L"%d", index);
|
||||
InterfaceChildren->Text = ref new String(szText);
|
||||
|
||||
InterfaceNeighbors->Text = L"unknown";
|
||||
|
||||
InterfaceNeighbors->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
InterfaceNeighborsText->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
InterfaceChildren->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
InterfaceChildrenText->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
|
||||
WCHAR szText[64] = { 0 };
|
||||
swprintf_s(szText, 64, L"%d", index);
|
||||
InterfaceChildren->Text = ref new String(szText);
|
||||
|
||||
InterfaceNeighbors->Text = L"unknown";
|
||||
|
||||
InterfaceNeighbors->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
InterfaceNeighborsText->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
InterfaceChildren->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
InterfaceChildrenText->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
// Show the details
|
||||
InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
|
||||
// Show the details
|
||||
InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
|
||||
otFreeMemory(device);
|
||||
}
|
||||
}
|
||||
|
||||
UIElement^ MainPage::CreateNewInterface(Platform::Guid InterfaceGuid)
|
||||
void MainPage::AddAdapterToList(otAdapter^ adapter)
|
||||
{
|
||||
GUID deviceGuid = InterfaceGuid;
|
||||
|
||||
auto device = otInstanceInit(ApiInstance, &deviceGuid);
|
||||
auto deviceRole = otThreadGetDeviceRole(device);
|
||||
|
||||
WCHAR szText[256] = { 0 };
|
||||
swprintf_s(szText, 256, L"%s\r\n\t" GUID_FORMAT L"\r\n\t%s",
|
||||
L"openthread interface", // TODO ...
|
||||
GUID_ARG(deviceGuid),
|
||||
::ToString(deviceRole));
|
||||
|
||||
auto InterfaceStackPanel = ref new StackPanel();
|
||||
InterfaceStackPanel->Orientation = Orientation::Horizontal;
|
||||
|
||||
auto InterfaceTextBlock = ref new TextBlock();
|
||||
InterfaceTextBlock->Text = ref new String(szText);
|
||||
InterfaceTextBlock->FontSize = 16;
|
||||
InterfaceTextBlock->Margin = Thickness(10);
|
||||
InterfaceTextBlock->TextWrapping = TextWrapping::Wrap;
|
||||
InterfaceStackPanel->Children->Append(InterfaceTextBlock);
|
||||
|
||||
if (deviceRole == kDeviceRoleDisabled)
|
||||
try
|
||||
{
|
||||
GUID interfaceGuid = adapter->InterfaceGuid;
|
||||
WCHAR szName[256] = { 0 };
|
||||
swprintf_s(szName, 256, GUID_FORMAT, GUID_ARG(interfaceGuid));
|
||||
|
||||
auto InterfaceStackPanel = ref new StackPanel();
|
||||
InterfaceStackPanel->Name = ref new String(szName);
|
||||
InterfaceStackPanel->Orientation = Orientation::Horizontal;
|
||||
|
||||
otLog("%S arrival!\n", InterfaceStackPanel->Name->Data());
|
||||
|
||||
// Basic description text
|
||||
auto InterfaceTextBlock = ref new TextBlock();
|
||||
InterfaceTextBlock->Text = ref new String(L"openthread interface");
|
||||
InterfaceTextBlock->FontSize = 16;
|
||||
InterfaceTextBlock->Margin = Thickness(10);
|
||||
InterfaceTextBlock->TextWrapping = TextWrapping::Wrap;
|
||||
InterfaceStackPanel->Children->Append(InterfaceTextBlock);
|
||||
|
||||
// Connect button
|
||||
auto ConnectButton = ref new Button();
|
||||
ConnectButton->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
ConnectButton->Content = ref new String(L"Connect");
|
||||
ConnectButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
_currentInterface = InterfaceGuid;
|
||||
InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
this->_curAdapter = adapter;
|
||||
this->InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
);
|
||||
);
|
||||
InterfaceStackPanel->Children->Append(ConnectButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Details button
|
||||
auto DetailsButton = ref new Button();
|
||||
DetailsButton->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
DetailsButton->Content = ref new String(L"Details");
|
||||
DetailsButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
ShowInterfaceDetails(InterfaceGuid);
|
||||
this->ShowInterfaceDetails(adapter);
|
||||
}
|
||||
);
|
||||
);
|
||||
InterfaceStackPanel->Children->Append(DetailsButton);
|
||||
|
||||
// Disconnect button
|
||||
auto DisconnectButton = ref new Button();
|
||||
DisconnectButton->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
DisconnectButton->Content = ref new String(L"Disconnect");
|
||||
DisconnectButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
DisconnectNetwork(InterfaceGuid);
|
||||
this->DisconnectNetwork(adapter);
|
||||
}
|
||||
);
|
||||
);
|
||||
InterfaceStackPanel->Children->Append(DisconnectButton);
|
||||
|
||||
// Delegate for handling role changes
|
||||
auto OnAdapterRoleChanged =
|
||||
[=]() {
|
||||
GUID interfaceGuid = adapter->InterfaceGuid;
|
||||
auto state = adapter->State;
|
||||
auto stateStr = otApi::ToString(adapter->State);
|
||||
|
||||
WCHAR szText[256] = { 0 };
|
||||
swprintf_s(szText, 256, GUID_FORMAT L"\r\n\t%s\r\n\t%s",
|
||||
GUID_ARG(interfaceGuid),
|
||||
stateStr->Data(),
|
||||
state >= otThreadState::Child ?
|
||||
adapter->MeshLocalEid->ToString()->Data() :
|
||||
L"");
|
||||
|
||||
InterfaceTextBlock->Text = ref new String(szText);
|
||||
|
||||
otLog("%S state = %S\n", InterfaceStackPanel->Name->Data(), stateStr->Data());
|
||||
|
||||
if (state == otThreadState::Disabled)
|
||||
{
|
||||
ConnectButton->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
DetailsButton->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
DisconnectButton->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectButton->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
DetailsButton->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
DisconnectButton->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
};
|
||||
|
||||
// Register for role change callbacks
|
||||
auto adapterRoleChangedToken =
|
||||
adapter->NetRoleChanged +=
|
||||
ref new otNetRoleChangedDelegate(
|
||||
[=](auto sender) {
|
||||
// Update the text on the UI thread
|
||||
this->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(
|
||||
[=]() {
|
||||
OnAdapterRoleChanged();
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Register for address change callbacks
|
||||
auto adapterMeshLocalAddresChangedToken =
|
||||
adapter->IpMeshLocalAddresChanged +=
|
||||
ref new otIpMeshLocalAddresChangedDelegate(
|
||||
[=](auto sender) {
|
||||
// Update the text on the UI thread
|
||||
this->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(
|
||||
[=]() {
|
||||
OnAdapterRoleChanged();
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Register for adapter removal callbacks
|
||||
Windows::Foundation::EventRegistrationToken adapterRemovalToken;
|
||||
adapterRemovalToken =
|
||||
adapter->AdapterRemoval +=
|
||||
ref new otAdapterRemovalDelegate(
|
||||
[=](otAdapter^ adapter) {
|
||||
// Unregister
|
||||
adapter->NetRoleChanged -= adapterRoleChangedToken;
|
||||
adapter->IpMeshLocalAddresChanged -= adapterMeshLocalAddresChangedToken;
|
||||
adapter->AdapterRemoval -= adapterRemovalToken;
|
||||
|
||||
// Remove the item on the UI thread
|
||||
this->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(
|
||||
[=]() {
|
||||
for (uint32_t i = 0; i < this->InterfaceList->Items->Size; i++)
|
||||
{
|
||||
auto Item = dynamic_cast<StackPanel^>(this->InterfaceList->Items->GetAt(i));
|
||||
if (Item == InterfaceStackPanel)
|
||||
{
|
||||
otLog("%S removal!\n", InterfaceStackPanel->Name->Data());
|
||||
this->InterfaceList->Items->RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// Trigger the initial role change
|
||||
OnAdapterRoleChanged();
|
||||
|
||||
// Add the interface to the list
|
||||
InterfaceList->Items->Append(InterfaceStackPanel);
|
||||
}
|
||||
|
||||
// Register for callbacks on the device
|
||||
otSetStateChangedCallback(device, ThreadStateChangeCallback, nullptr);
|
||||
|
||||
// Cache the device
|
||||
_devices.push_back(device);
|
||||
|
||||
return InterfaceStackPanel;
|
||||
}
|
||||
|
||||
void MainPage::BuildInterfaceList()
|
||||
{
|
||||
if (ApiInstance == nullptr) return;
|
||||
|
||||
// Clear all existing children
|
||||
InterfaceList->Items->Clear();
|
||||
|
||||
// Clean up devices
|
||||
for each (auto device in _devices)
|
||||
catch (Exception^)
|
||||
{
|
||||
// Unregister for callbacks for the device
|
||||
otSetStateChangedCallback((otInstance*)device, nullptr, nullptr);
|
||||
|
||||
// Free the device
|
||||
otFreeMemory(device);
|
||||
}
|
||||
_devices.clear();
|
||||
}
|
||||
|
||||
// Enumerate the new device list
|
||||
auto deviceList = otEnumerateDevices(ApiInstance);
|
||||
if (deviceList)
|
||||
void MainPage::ConnectNetwork(otAdapter^ adapter)
|
||||
{
|
||||
try
|
||||
{
|
||||
GUID interfaceGuid = adapter->InterfaceGuid;
|
||||
WCHAR szName[256] = { 0 };
|
||||
swprintf_s(szName, 256, GUID_FORMAT, GUID_ARG(interfaceGuid));
|
||||
otLog("%S starting connection...\n", szName);
|
||||
|
||||
// Configure
|
||||
adapter->NetworkName = InterfaceConfigName->Text;
|
||||
adapter->MasterKey = InterfaceConfigKey->Text;
|
||||
adapter->Channel = (uint8_t)InterfaceConfigChannel->Value;
|
||||
adapter->MaxAllowedChildren = (uint8_t)InterfaceConfigMaxChildren->Value;
|
||||
adapter->PanId = 0x4567;
|
||||
|
||||
// Bring up the interface and start the Thread logic
|
||||
adapter->IpEnabled = true;
|
||||
adapter->ThreadEnabled = true;
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
// Dump the results to the console
|
||||
for (DWORD dwIndex = 0; dwIndex < deviceList->aDevicesLength; dwIndex++)
|
||||
{
|
||||
InterfaceList->Items->Append(
|
||||
CreateNewInterface(deviceList->aDevices[dwIndex]));
|
||||
}
|
||||
|
||||
otFreeMemory(deviceList);
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::ConnectNetwork(Platform::Guid InterfaceGuid)
|
||||
void MainPage::DisconnectNetwork(otAdapter^ adapter)
|
||||
{
|
||||
if (ApiInstance == nullptr) return;
|
||||
try
|
||||
{
|
||||
GUID interfaceGuid = adapter->InterfaceGuid;
|
||||
WCHAR szName[256] = { 0 };
|
||||
swprintf_s(szName, 256, GUID_FORMAT, GUID_ARG(interfaceGuid));
|
||||
otLog("%S disconnecting...\n", szName);
|
||||
|
||||
GUID deviceGuid = InterfaceGuid;
|
||||
auto device = otInstanceInit(ApiInstance, &deviceGuid);
|
||||
// Stop the Thread network and bring down the interface
|
||||
adapter->ThreadEnabled = false;
|
||||
adapter->IpEnabled = false;
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
|
||||
//
|
||||
// Configure
|
||||
//
|
||||
|
||||
otNetworkName networkName = {};
|
||||
wcstombs(networkName.m8, InterfaceConfigName->Text->Data(), sizeof(networkName.m8));
|
||||
otThreadSetNetworkName(device, networkName.m8);
|
||||
|
||||
otMasterKey masterKey = {};
|
||||
wcstombs((char*)masterKey.m8, InterfaceConfigKey->Text->Data(), sizeof(masterKey.m8));
|
||||
otThreadSetMasterKey(device, masterKey.m8, sizeof(masterKey.m8));
|
||||
|
||||
otLinkSetChannel(device, (uint8_t)InterfaceConfigChannel->Value);
|
||||
otThreadSetMaxAllowedChildren(device, (uint8_t)InterfaceConfigMaxChildren->Value);
|
||||
|
||||
otLinkSetPanId(device, 0x4567);
|
||||
|
||||
//
|
||||
// Bring up the interface and start the Thread logic
|
||||
//
|
||||
|
||||
otIp6SetEnabled(device, true);
|
||||
|
||||
otThreadSetEnabled(device, true);
|
||||
|
||||
// Cleanup
|
||||
otFreeMemory(device);
|
||||
}
|
||||
|
||||
void MainPage::DisconnectNetwork(Platform::Guid InterfaceGuid)
|
||||
{
|
||||
if (ApiInstance == nullptr) return;
|
||||
|
||||
GUID deviceGuid = InterfaceGuid;
|
||||
auto device = otInstanceInit(ApiInstance, &deviceGuid);
|
||||
|
||||
//
|
||||
// Start the Thread logic and the interface
|
||||
//
|
||||
|
||||
otThreadSetEnabled(device, false);
|
||||
|
||||
otIp6SetEnabled(device, false);
|
||||
|
||||
// Cleanup
|
||||
otFreeMemory(device);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,11 +42,9 @@ namespace Thread
|
||||
|
||||
void OnResuming();
|
||||
|
||||
void BuildInterfaceList();
|
||||
|
||||
void ConnectNetwork(Platform::Guid InterfaceGuid);
|
||||
void ShowInterfaceDetails(Platform::Guid InterfaceGuid);
|
||||
void DisconnectNetwork(Platform::Guid InterfaceGuid);
|
||||
void ConnectNetwork(otAdapter^ adapter);
|
||||
void ShowInterfaceDetails(otAdapter^ adapter);
|
||||
void DisconnectNetwork(otAdapter^ adapter);
|
||||
|
||||
protected:
|
||||
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
|
||||
@@ -56,25 +54,13 @@ namespace Thread
|
||||
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
void OnUnloaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void OnWindowSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ args);
|
||||
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ coreWindow, Windows::UI::Core::VisibilityChangedEventArgs^ args);
|
||||
|
||||
UIElement^ CreateNewInterface(Platform::Guid InterfaceGuid);
|
||||
|
||||
bool _isVisible;
|
||||
bool _isFullScreen;
|
||||
|
||||
Windows::Foundation::Size _windowSize;
|
||||
void AddAdapterToList(otAdapter^ adapter);
|
||||
|
||||
void *_apiInstance;
|
||||
#define ApiInstance ((otApiInstance*)_apiInstance)
|
||||
otApi^ _otApi;
|
||||
|
||||
std::vector<void*> _devices;
|
||||
Windows::Foundation::EventRegistrationToken _adapterArrivalToken;
|
||||
|
||||
Platform::Guid _currentInterface;
|
||||
|
||||
internal:
|
||||
static MainPage^ Current;
|
||||
otAdapter^ _curAdapter;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# OpenThread App for Windows #
|
||||
|
||||
This sample app provides an example of how to interface with the OpenThread API in a
|
||||
[Universal Windows App](https://developer.microsoft.com/en-us/windows/apps). The app is written in C++ /CX
|
||||
and provides a simple wrapper around the OpenThread API, hiding the raw C/C++ interface.
|
||||
|
||||
The main page of the App is a list of the available interfaces, their current connection state,
|
||||
their current ML-EID IPv6 address, and buttons to connect/disconnect and to view some more details.
|
||||
|
||||

|
||||
|
||||
The details list provides some more information, including extended MAC address, RLOC16 and information
|
||||
about the current children.
|
||||
|
||||

|
||||
@@ -0,0 +1,613 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define OTDLL 1
|
||||
#include <openthread/openthread.h>
|
||||
#include <openthread/commissioner.h>
|
||||
#include <openthread/joiner.h>
|
||||
|
||||
#include <wrl.h>
|
||||
#include <collection.h>
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Platform::Metadata;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Networking;
|
||||
|
||||
namespace Thread
|
||||
{
|
||||
|
||||
ref class otAdapter;
|
||||
|
||||
public delegate void otAdapterRemovalDelegate(otAdapter^ sender);
|
||||
|
||||
public delegate void otIpAddressAddedDelegate(otAdapter^ sender);
|
||||
public delegate void otIpAddressRemovedDelegate(otAdapter^ sender);
|
||||
public delegate void otIpRlocAddedDelegate(otAdapter^ sender);
|
||||
public delegate void otIpRlocRemovedDelegate(otAdapter^ sender);
|
||||
public delegate void otIpLinkLocalAddresChangedDelegate(otAdapter^ sender);
|
||||
public delegate void otIpMeshLocalAddresChangedDelegate(otAdapter^ sender);
|
||||
|
||||
public delegate void otNetRoleChangedDelegate(otAdapter^ sender);
|
||||
public delegate void otNetPartitionIdChangedDelegate(otAdapter^ sender);
|
||||
public delegate void otNetKeySequenceCounterChangedDelegate(otAdapter^ sender);
|
||||
|
||||
public delegate void otThreadChildAddedDelegate(otAdapter^ sender);
|
||||
public delegate void otThreadChildRemovedDelegate(otAdapter^ sender);
|
||||
public delegate void otThreadNetDataUpdatedDelegate(otAdapter^ sender);
|
||||
|
||||
[Flags]
|
||||
public enum class otLinkModeFlags : unsigned int
|
||||
{
|
||||
None = 0,
|
||||
RxOnWhenIdle = 0x1, /* 1, if the sender has its receiver on when not transmitting. 0, otherwise. */
|
||||
SecureDataRequests = 0x2, /* 1, if the sender will use IEEE 802.15.4 to secure all data requests. 0, otherwise. */
|
||||
DeviceType = 0x4, /* 1, if the sender is an FFD. 0, otherwise. */
|
||||
NetworkData = 0x8 /* 1, if the sender requires the full Network Data. 0, otherwise. */
|
||||
};
|
||||
|
||||
public enum class otThreadState
|
||||
{
|
||||
Offline,
|
||||
Disabled,
|
||||
Detached,
|
||||
Child,
|
||||
Router,
|
||||
Leader
|
||||
};
|
||||
|
||||
// Helper class for OpenThread Interface/Adapter specific APIs
|
||||
public ref class otAdapter sealed
|
||||
{
|
||||
private:
|
||||
|
||||
void *_Instance;
|
||||
#define DeviceInstance ((otInstance*)_Instance)
|
||||
|
||||
#define ThrowOnFailure(exp) \
|
||||
do { \
|
||||
auto res = exp; \
|
||||
if (res != 0) \
|
||||
throw Exception::CreateException(TheadErrorToHResult(res), #exp); \
|
||||
} while (false)
|
||||
|
||||
public:
|
||||
|
||||
#pragma region Events
|
||||
|
||||
event otAdapterRemovalDelegate^ AdapterRemoval;
|
||||
|
||||
event otIpAddressAddedDelegate^ IpAddressAdded;
|
||||
event otIpAddressRemovedDelegate^ IpAddressRemoved;
|
||||
event otIpRlocAddedDelegate^ IpRlocAdded;
|
||||
event otIpRlocRemovedDelegate^ IpRlocRemoved;
|
||||
event otIpLinkLocalAddresChangedDelegate^ IpLinkLocalAddresChanged;
|
||||
event otIpMeshLocalAddresChangedDelegate^ IpMeshLocalAddresChanged;
|
||||
|
||||
event otNetRoleChangedDelegate^ NetRoleChanged;
|
||||
event otNetPartitionIdChangedDelegate^ NetPartitionIdChanged;
|
||||
event otNetKeySequenceCounterChangedDelegate^ NetKeySequenceCounterChanged;
|
||||
|
||||
event otThreadChildAddedDelegate^ ThreadChildAdded;
|
||||
event otThreadChildRemovedDelegate^ ThreadChildRemoved;
|
||||
event otThreadNetDataUpdatedDelegate^ ThreadNetDataUpdated;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Properties
|
||||
|
||||
property IntPtr RawHandle
|
||||
{
|
||||
IntPtr get() { return _Instance; }
|
||||
}
|
||||
|
||||
property Guid InterfaceGuid
|
||||
{
|
||||
Guid get() { return otGetDeviceGuid(DeviceInstance); }
|
||||
}
|
||||
|
||||
property uint32_t IfIndex
|
||||
{
|
||||
uint32_t get() { return otGetDeviceIfIndex(DeviceInstance); }
|
||||
}
|
||||
|
||||
property uint32_t CompartmentId
|
||||
{
|
||||
uint32_t get() { return otGetCompartmentId(DeviceInstance); }
|
||||
}
|
||||
|
||||
#pragma region Link Layer
|
||||
|
||||
property signed int /*int8_t*/ MaxTransmitPower
|
||||
{
|
||||
signed int get() { return otLinkGetMaxTransmitPower(DeviceInstance); }
|
||||
void set(signed int value)
|
||||
{
|
||||
if (value > 127) throw Exception::CreateException(E_INVALIDARG);
|
||||
otLinkSetMaxTransmitPower(DeviceInstance, (int8_t)value);
|
||||
}
|
||||
}
|
||||
|
||||
property uint32_t PollPeriod
|
||||
{
|
||||
uint32_t get() { return otLinkGetPollPeriod(DeviceInstance); }
|
||||
void set(uint32_t value) { otLinkSetPollPeriod(DeviceInstance, value); }
|
||||
}
|
||||
|
||||
property uint8_t Channel
|
||||
{
|
||||
uint8_t get() { return otLinkGetChannel(DeviceInstance); }
|
||||
void set(uint8_t value) { ThrowOnFailure(otLinkSetChannel(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
property uint16_t PanId
|
||||
{
|
||||
uint16_t get() { return otLinkGetPanId(DeviceInstance); }
|
||||
void set(uint16_t value) { ThrowOnFailure(otLinkSetPanId(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
property uint16_t ShortAddress
|
||||
{
|
||||
uint16_t get() { return otLinkGetShortAddress(DeviceInstance); }
|
||||
}
|
||||
|
||||
property uint64_t ExtendedAddress
|
||||
{
|
||||
uint64_t get()
|
||||
{
|
||||
auto addr = otLinkGetExtendedAddress(DeviceInstance);
|
||||
auto ret = *(uint64_t*)addr;
|
||||
otFreeMemory(addr);
|
||||
return ret;
|
||||
}
|
||||
void set(uint64_t value)
|
||||
{
|
||||
ThrowOnFailure(otLinkSetExtendedAddress(DeviceInstance, (otExtAddress*)&value));
|
||||
}
|
||||
}
|
||||
|
||||
property uint64_t FactoryAssignedIeeeEui64
|
||||
{
|
||||
uint64_t get()
|
||||
{
|
||||
uint64_t addr;
|
||||
otLinkGetFactoryAssignedIeeeEui64(DeviceInstance, (otExtAddress*)&addr);
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
property uint64_t JoinerId
|
||||
{
|
||||
uint64_t get()
|
||||
{
|
||||
uint64_t addr;
|
||||
otLinkGetJoinerId(DeviceInstance, (otExtAddress*)&addr);
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IP Layer
|
||||
|
||||
property bool IpEnabled
|
||||
{
|
||||
bool get() { return otIp6IsEnabled(DeviceInstance); }
|
||||
void set(bool value) { ThrowOnFailure(otIp6SetEnabled(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Thread Layer
|
||||
|
||||
property uint64_t ExtendedPanId
|
||||
{
|
||||
uint64_t get()
|
||||
{
|
||||
auto panid = otThreadGetExtendedPanId(DeviceInstance);
|
||||
auto ret = *(uint64_t*)panid;
|
||||
otFreeMemory(panid);
|
||||
return ret;
|
||||
}
|
||||
void set(uint64_t value)
|
||||
{
|
||||
otThreadSetExtendedPanId(DeviceInstance, (uint8_t*)&value);
|
||||
}
|
||||
}
|
||||
|
||||
property otLinkModeFlags LinkMode
|
||||
{
|
||||
otLinkModeFlags get()
|
||||
{
|
||||
auto linkmode = otThreadGetLinkMode(DeviceInstance);
|
||||
otLinkModeFlags flags = otLinkModeFlags::None;
|
||||
if (linkmode.mRxOnWhenIdle) flags = flags | otLinkModeFlags::RxOnWhenIdle;
|
||||
if (linkmode.mSecureDataRequests) flags = flags | otLinkModeFlags::SecureDataRequests;
|
||||
if (linkmode.mDeviceType) flags = flags | otLinkModeFlags::DeviceType;
|
||||
if (linkmode.mNetworkData) flags = flags | otLinkModeFlags::NetworkData;
|
||||
return flags;
|
||||
}
|
||||
void set(otLinkModeFlags value)
|
||||
{
|
||||
otLinkModeConfig linkmode = { 0 };
|
||||
if ((value & otLinkModeFlags::RxOnWhenIdle) != otLinkModeFlags::None)
|
||||
linkmode.mRxOnWhenIdle = true;
|
||||
if ((value & otLinkModeFlags::SecureDataRequests) != otLinkModeFlags::None)
|
||||
linkmode.mSecureDataRequests = true;
|
||||
if ((value & otLinkModeFlags::DeviceType) != otLinkModeFlags::None)
|
||||
linkmode.mDeviceType = true;
|
||||
if ((value & otLinkModeFlags::NetworkData) != otLinkModeFlags::None)
|
||||
linkmode.mNetworkData = true;
|
||||
ThrowOnFailure(otThreadSetLinkMode(DeviceInstance, linkmode));
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t charToValue(wchar_t c)
|
||||
{
|
||||
if (c >= L'a' && c <= L'f')
|
||||
{
|
||||
return c - L'a';
|
||||
}
|
||||
else if (c >= L'A' && c <= L'F')
|
||||
{
|
||||
return c - L'A';
|
||||
}
|
||||
else if (c >= L'0' && c <= L'9')
|
||||
{
|
||||
return c - L'0';
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG);
|
||||
}
|
||||
}
|
||||
|
||||
property String^ MasterKey
|
||||
{
|
||||
String^ get()
|
||||
{
|
||||
constexpr char hexmap[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
uint8_t keyLen;
|
||||
auto key = otThreadGetMasterKey(DeviceInstance, &keyLen);
|
||||
WCHAR szKey[OT_MASTER_KEY_SIZE * 2 + 1] = { 0 };
|
||||
for (uint8_t i = 0; i < keyLen; i++)
|
||||
{
|
||||
szKey[2 * i] = hexmap[(key[i] & 0xF0) >> 4];
|
||||
szKey[2 * i + 1] = hexmap[key[i] & 0x0F];
|
||||
}
|
||||
otFreeMemory(key);
|
||||
return ref new String(szKey);
|
||||
}
|
||||
void set(String^ value)
|
||||
{
|
||||
uint8_t key[OT_MASTER_KEY_SIZE];
|
||||
uint8_t keyLen = 0;
|
||||
if (value->Length() % 2 == 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < value->Length(); i+=2)
|
||||
{
|
||||
key[keyLen++] = (uint8_t)((charToValue(value->Data()[i]) << 4) |
|
||||
charToValue(value->Data()[i + 1]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
key[keyLen++] = (uint8_t)(charToValue(value->Data()[0]));
|
||||
for (uint32_t i = 1; i < value->Length(); i += 2)
|
||||
{
|
||||
key[keyLen++] = (uint8_t)((charToValue(value->Data()[i]) << 4) |
|
||||
charToValue(value->Data()[i + 1]));
|
||||
}
|
||||
}
|
||||
ThrowOnFailure(otThreadSetMasterKey(DeviceInstance, key, keyLen));
|
||||
}
|
||||
}
|
||||
|
||||
property String^ NetworkName
|
||||
{
|
||||
String^ get()
|
||||
{
|
||||
auto _name = otThreadGetNetworkName(DeviceInstance);
|
||||
WCHAR name[OT_NETWORK_NAME_MAX_SIZE + 1];
|
||||
MultiByteToWideChar(CP_UTF8, 0, _name, -1, name, ARRAYSIZE(name));
|
||||
otFreeMemory(_name);
|
||||
return ref new String(name);
|
||||
}
|
||||
void set(String^ value)
|
||||
{
|
||||
char name[OT_NETWORK_NAME_MAX_SIZE + 1];
|
||||
auto err = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS, value->Data(), -1, name, ARRAYSIZE(name), nullptr, nullptr);
|
||||
if (err == 0) ThrowOnFailure(otThreadSetNetworkName(DeviceInstance, name));
|
||||
else throw Exception::CreateException(E_INVALIDARG);
|
||||
}
|
||||
}
|
||||
|
||||
property uint8_t MaxAllowedChildren
|
||||
{
|
||||
uint8_t get() { return otThreadGetMaxAllowedChildren(DeviceInstance); }
|
||||
void set(uint8_t value) { ThrowOnFailure(otThreadSetMaxAllowedChildren(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
property uint32_t ChildTimeout
|
||||
{
|
||||
uint32_t get() { return otThreadGetChildTimeout(DeviceInstance); }
|
||||
void set(uint32_t value) { otThreadSetChildTimeout(DeviceInstance, value); }
|
||||
}
|
||||
|
||||
property bool ThreadEnabled
|
||||
{
|
||||
//bool get() { return otIsThreadStarted(DeviceInstance); }
|
||||
void set(bool value) { ThrowOnFailure(otThreadSetEnabled(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
property bool AutoStart
|
||||
{
|
||||
bool get() { return otThreadGetAutoStart(DeviceInstance); }
|
||||
void set(bool value) { ThrowOnFailure(otThreadSetAutoStart(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
property bool Singleton
|
||||
{
|
||||
bool get() { return otThreadIsSingleton(DeviceInstance); }
|
||||
}
|
||||
|
||||
property bool RouterRoleEnabled
|
||||
{
|
||||
bool get() { return otThreadIsRouterRoleEnabled(DeviceInstance); }
|
||||
void set(bool value) { otThreadSetRouterRoleEnabled(DeviceInstance, value); }
|
||||
}
|
||||
|
||||
property uint8_t PreferredRouterId
|
||||
{
|
||||
void set(uint8_t value) { ThrowOnFailure(otThreadSetPreferredRouterId(DeviceInstance, value)); }
|
||||
}
|
||||
|
||||
property HostName^ MeshLocalEid
|
||||
{
|
||||
HostName^ get()
|
||||
{
|
||||
auto addr = otThreadGetMeshLocalEid(DeviceInstance);
|
||||
WCHAR szAddr[46];
|
||||
RtlIpv6AddressToString((IN6_ADDR*)addr, szAddr);
|
||||
otFreeMemory(addr);
|
||||
return ref new HostName(ref new String(szAddr));
|
||||
}
|
||||
}
|
||||
|
||||
property HostName^ LeaderRloc
|
||||
{
|
||||
HostName^ get()
|
||||
{
|
||||
IN6_ADDR addr;
|
||||
ThrowOnFailure(otThreadGetLeaderRloc(DeviceInstance, (otIp6Address*)&addr));
|
||||
WCHAR szAddr[46];
|
||||
RtlIpv6AddressToString(&addr, szAddr);
|
||||
return ref new HostName(ref new String(szAddr));
|
||||
}
|
||||
}
|
||||
|
||||
property uint8_t LocalLeaderWeight
|
||||
{
|
||||
uint8_t get() { return otThreadGetLocalLeaderWeight(DeviceInstance); }
|
||||
void set(uint8_t value) { otThreadSetLocalLeaderWeight(DeviceInstance, value); }
|
||||
}
|
||||
|
||||
property uint32_t LocalLeaderPartitionId
|
||||
{
|
||||
uint32_t get() { return otThreadGetLocalLeaderPartitionId(DeviceInstance); }
|
||||
void set(uint32_t value) { otThreadSetLocalLeaderPartitionId(DeviceInstance, value); }
|
||||
}
|
||||
|
||||
property uint8_t LeaderWeight
|
||||
{
|
||||
uint8_t get() { return otThreadGetLeaderWeight(DeviceInstance); }
|
||||
}
|
||||
|
||||
property uint32_t LeaderRouterId
|
||||
{
|
||||
uint32_t get() { return otThreadGetLeaderRouterId(DeviceInstance); }
|
||||
}
|
||||
|
||||
property uint32_t PartitionId
|
||||
{
|
||||
uint32_t get() { return otThreadGetPartitionId(DeviceInstance); }
|
||||
}
|
||||
|
||||
property uint16_t Rloc16
|
||||
{
|
||||
uint16_t get() { return otThreadGetRloc16(DeviceInstance); }
|
||||
}
|
||||
|
||||
property otThreadState State
|
||||
{
|
||||
otThreadState get()
|
||||
{
|
||||
return (otThreadState)otThreadGetDeviceRole(DeviceInstance);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Constructor/Destructor
|
||||
|
||||
otAdapter(_In_ IntPtr /*otInstance**/ aInstance)
|
||||
{
|
||||
_Instance = (void*)aInstance;
|
||||
|
||||
IInspectable* pInspectable = reinterpret_cast<IInspectable*>(this);
|
||||
|
||||
// Register for device availability callbacks
|
||||
otSetStateChangedCallback(DeviceInstance, ThreadStateChangeCallback, pInspectable);
|
||||
}
|
||||
|
||||
virtual ~otAdapter()
|
||||
{
|
||||
// Unregister for callbacks for the device
|
||||
otSetStateChangedCallback(DeviceInstance, nullptr, nullptr);
|
||||
|
||||
// Free the device
|
||||
otFreeMemory(DeviceInstance);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Functions
|
||||
|
||||
void PlatformReset()
|
||||
{
|
||||
otInstanceReset(DeviceInstance);
|
||||
}
|
||||
|
||||
void FactoryReset()
|
||||
{
|
||||
otInstanceFactoryReset(DeviceInstance);
|
||||
}
|
||||
|
||||
void BecomeRouter()
|
||||
{
|
||||
ThrowOnFailure(otThreadBecomeRouter(DeviceInstance));
|
||||
}
|
||||
|
||||
void BecomeLeader()
|
||||
{
|
||||
ThrowOnFailure(otThreadBecomeLeader(DeviceInstance));
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
internal:
|
||||
|
||||
void InvokeAdapterRemoval()
|
||||
{
|
||||
AdapterRemoval(this);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend ref class otApi;
|
||||
|
||||
static void OTCALL
|
||||
ThreadStateChangeCallback(
|
||||
uint32_t aFlags,
|
||||
_In_ void* aContext
|
||||
)
|
||||
{
|
||||
IInspectable* pInspectable = (IInspectable*)aContext;
|
||||
otAdapter^ pThis = reinterpret_cast<otAdapter^>(pInspectable);
|
||||
|
||||
if (aFlags & OT_IP6_ADDRESS_ADDED)
|
||||
{
|
||||
pThis->IpAddressAdded(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_IP6_ADDRESS_REMOVED)
|
||||
{
|
||||
pThis->IpAddressRemoved(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_IP6_RLOC_ADDED)
|
||||
{
|
||||
pThis->IpRlocAdded(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_IP6_RLOC_REMOVED)
|
||||
{
|
||||
pThis->IpRlocRemoved(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_IP6_LL_ADDR_CHANGED)
|
||||
{
|
||||
pThis->IpLinkLocalAddresChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_IP6_ML_ADDR_CHANGED)
|
||||
{
|
||||
pThis->IpMeshLocalAddresChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_NET_ROLE)
|
||||
{
|
||||
pThis->NetRoleChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_NET_PARTITION_ID)
|
||||
{
|
||||
pThis->NetPartitionIdChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_NET_KEY_SEQUENCE_COUNTER)
|
||||
{
|
||||
pThis->NetKeySequenceCounterChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_THREAD_CHILD_ADDED)
|
||||
{
|
||||
pThis->ThreadChildAdded(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_THREAD_CHILD_REMOVED)
|
||||
{
|
||||
pThis->ThreadChildRemoved(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_THREAD_NETDATA_UPDATED)
|
||||
{
|
||||
pThis->ThreadNetDataUpdated(pThis);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
TheadErrorToHResult(
|
||||
int /* ThreadError */ error
|
||||
)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case kThreadError_NoBufs: return E_OUTOFMEMORY;
|
||||
case kThreadError_Drop:
|
||||
case kThreadError_NoRoute: return HRESULT_FROM_WIN32(ERROR_NETWORK_UNREACHABLE);
|
||||
case kThreadError_InvalidArgs: return E_INVALIDARG;
|
||||
case kThreadError_Security: return E_ACCESSDENIED;
|
||||
case kThreadError_NotCapable:
|
||||
case kThreadError_NotImplemented: return E_NOTIMPL;
|
||||
case kThreadError_InvalidState: return E_NOT_VALID_STATE;
|
||||
case kThreadError_NotFound: return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||||
case kThreadError_Already: return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
|
||||
case kThreadError_ResponseTimeout: return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
|
||||
default: return E_FAIL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "otAdapter.h"
|
||||
#include <collection.h>
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
|
||||
#define MAC8_FORMAT L"%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X"
|
||||
#define MAC8_ARG(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]
|
||||
|
||||
namespace Thread
|
||||
{
|
||||
|
||||
public delegate void otAdapterArrivalDelegate(otAdapter^ aAdapter);
|
||||
|
||||
// Helper class for OpenThread API
|
||||
public ref class otApi sealed
|
||||
{
|
||||
private:
|
||||
|
||||
void *_apiInstance;
|
||||
#define ApiInstance ((otApiInstance*)_apiInstance)
|
||||
|
||||
CRITICAL_SECTION _cs;
|
||||
Vector<otAdapter^>^ _adapters;
|
||||
|
||||
public:
|
||||
|
||||
// Event for device availability changes
|
||||
event otAdapterArrivalDelegate^ AdapterArrival;
|
||||
|
||||
property IntPtr RawHandle
|
||||
{
|
||||
IntPtr get() { return _apiInstance; }
|
||||
}
|
||||
|
||||
// Constructor
|
||||
otApi() :
|
||||
_adapters(ref new Vector<otAdapter^>())
|
||||
{
|
||||
// Initialize the API handle
|
||||
_apiInstance = otApiInit();
|
||||
if (_apiInstance == nullptr)
|
||||
{
|
||||
throw Exception::CreateException(E_UNEXPECTED, L"otApiInit failed.");
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&_cs);
|
||||
|
||||
IInspectable* pInspectable = reinterpret_cast<IInspectable*>(this);
|
||||
|
||||
// Register for device availability callbacks
|
||||
otSetDeviceAvailabilityChangedCallback(ApiInstance, ThreadDeviceAvailabilityCallback, pInspectable);
|
||||
|
||||
// Query list of devices
|
||||
auto deviceList = otEnumerateDevices(ApiInstance);
|
||||
if (deviceList)
|
||||
{
|
||||
EnterCriticalSection(&_cs);
|
||||
|
||||
// Add each adapter to our cache unless it already was inserted from a notification
|
||||
for (DWORD i = 0; i < deviceList->aDevicesLength; i++)
|
||||
{
|
||||
if (GetAdapter(deviceList->aDevices[i]) == nullptr)
|
||||
{
|
||||
auto deviceInstance = otInstanceInit(ApiInstance, &deviceList->aDevices[i]);
|
||||
if (deviceInstance)
|
||||
{
|
||||
_adapters->Append(ref new otAdapter(deviceInstance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&_cs);
|
||||
|
||||
otFreeMemory(deviceList);
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
virtual ~otApi()
|
||||
{
|
||||
// Clear registration for callbacks
|
||||
otSetDeviceAvailabilityChangedCallback(ApiInstance, nullptr, nullptr);
|
||||
|
||||
DeleteCriticalSection(&_cs);
|
||||
|
||||
// Clean up api
|
||||
otApiFinalize(ApiInstance);
|
||||
_apiInstance = nullptr;
|
||||
}
|
||||
|
||||
// Returns the entire list of adapters
|
||||
IVectorView<otAdapter^>^ GetAdapters()
|
||||
{
|
||||
IVectorView<otAdapter^>^ adapters;
|
||||
EnterCriticalSection(&_cs);
|
||||
adapters = _adapters->GetView(); // TODO - Need to copy
|
||||
LeaveCriticalSection(&_cs);
|
||||
return adapters;
|
||||
}
|
||||
|
||||
// Helper to get an adapter, given its device guid
|
||||
otAdapter^ GetAdapter(Guid aDeviceGuid)
|
||||
{
|
||||
otAdapter^ ret = nullptr;
|
||||
|
||||
EnterCriticalSection(&_cs);
|
||||
|
||||
for (auto&& adapter : _adapters)
|
||||
{
|
||||
if (adapter->InterfaceGuid == aDeviceGuid)
|
||||
{
|
||||
ret = adapter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&_cs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Helper function to convert mac address to string
|
||||
static String^ ToString(uint64_t mac)
|
||||
{
|
||||
WCHAR szMac[64] = { 0 };
|
||||
swprintf_s(szMac, 64, MAC8_FORMAT, MAC8_ARG(((UCHAR*)&mac)));
|
||||
return ref new String(szMac);
|
||||
}
|
||||
|
||||
// Helper function to convert RLOC16/PANID to string
|
||||
static String^ ToString(uint16_t rloc)
|
||||
{
|
||||
WCHAR szRloc[16] = { 0 };
|
||||
swprintf_s(szRloc, 16, L"0x%X", rloc);
|
||||
return ref new String(szRloc);
|
||||
}
|
||||
|
||||
// Helper function to convert state to string
|
||||
static String^ ToString(otThreadState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
default:
|
||||
case otThreadState::Offline: return L"Offline";
|
||||
case otThreadState::Disabled: return L"Disabled";
|
||||
case otThreadState::Detached: return L"Disconnected";
|
||||
case otThreadState::Child: return L"Connected - Child";
|
||||
case otThreadState::Router: return L"Connected - Router";
|
||||
case otThreadState::Leader: return L"Connected - Leader";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Callback from OpenThread indicating arrival or removal of interfaces
|
||||
static void OTCALL
|
||||
ThreadDeviceAvailabilityCallback(
|
||||
bool aAdded,
|
||||
const GUID* aDeviceGuid,
|
||||
_In_ void* aContext
|
||||
)
|
||||
{
|
||||
IInspectable* pInspectable = (IInspectable*)aContext;
|
||||
otApi^ pThis = reinterpret_cast<otApi^>(pInspectable);
|
||||
|
||||
if (aAdded)
|
||||
{
|
||||
otAdapter^ adapter = nullptr;
|
||||
|
||||
// Add the device to the list, if it isn't already there
|
||||
EnterCriticalSection(&pThis->_cs);
|
||||
|
||||
if (pThis->GetAdapter(*aDeviceGuid) == nullptr)
|
||||
{
|
||||
auto deviceInstance = otInstanceInit((otApiInstance*)pThis->_apiInstance, aDeviceGuid);
|
||||
if (deviceInstance)
|
||||
{
|
||||
pThis->_adapters->Append(adapter = ref new otAdapter(deviceInstance));
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&pThis->_cs);
|
||||
|
||||
if (adapter)
|
||||
{
|
||||
// Send a notification of arrival
|
||||
pThis->AdapterArrival(adapter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
otAdapter^ ret = nullptr;
|
||||
Guid guid = *aDeviceGuid;
|
||||
|
||||
EnterCriticalSection(&pThis->_cs);
|
||||
|
||||
// Look up in the cached list of adapters to remove it
|
||||
uint32_t i = 0;
|
||||
for (auto&& adapter : pThis->_adapters)
|
||||
{
|
||||
if (adapter->InterfaceGuid == guid)
|
||||
{
|
||||
ret = adapter;
|
||||
pThis->_adapters->RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&pThis->_cs);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret->InvokeAdapterRemoval();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Thread
|
||||
@@ -38,9 +38,7 @@
|
||||
#include <ws2def.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <mstcpip.h>
|
||||
#define OTDLL 1
|
||||
#include <openthread/openthread.h>
|
||||
#include <openthread/commissioner.h>
|
||||
#include <openthread/joiner.h>
|
||||
|
||||
#include "otApi.h"
|
||||
|
||||
#include "App.xaml.h"
|
||||
|
||||
@@ -115,7 +115,7 @@ typedef enum _OTLWF_NOTIF_TYPE
|
||||
uint32_t ChannelMask;
|
||||
uint8_t EnergyListLength;
|
||||
uint8_t EnergyList[MAX_ENERGY_REPORT_LENGTH];
|
||||
|
||||
|
||||
} CommissionerEnergyReportPayload;
|
||||
|
||||
// Payload for OTLWF_NOTIF_COMMISSIONER_PANID_QUERY
|
||||
@@ -168,298 +168,298 @@ typedef enum _OTLWF_NOTIF_TYPE
|
||||
OTLWF_CTL_CODE(101, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// BOOLEAN - aUp
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_THREAD \
|
||||
OTLWF_CTL_CODE(102, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// BOOLEAN - aStarted
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ACTIVE_SCAN \
|
||||
OTLWF_CTL_CODE(103, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aScanChannels
|
||||
// uint16_t - aScanDuration
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_DISCOVER \
|
||||
OTLWF_CTL_CODE(104, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aScanChannels
|
||||
// uint16_t - aScanDuration
|
||||
// uint16_t - aPanid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CHANNEL \
|
||||
OTLWF_CTL_CODE(105, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aChannel
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CHILD_TIMEOUT \
|
||||
OTLWF_CTL_CODE(106, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aTimeout
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_EXTENDED_ADDRESS \
|
||||
OTLWF_CTL_CODE(107, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aExtendedAddress
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_EXTENDED_PANID \
|
||||
OTLWF_CTL_CODE(108, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtendedPanId - aExtendedPanId
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LEADER_RLOC \
|
||||
OTLWF_CTL_CODE(109, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otIp6Address - aLeaderRloc
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LINK_MODE \
|
||||
OTLWF_CTL_CODE(110, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otLinkModeConfig - aConfig
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MASTER_KEY \
|
||||
OTLWF_CTL_CODE(111, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otMasterKey - aKey
|
||||
// uint8_t - aKeyLength
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MESH_LOCAL_EID \
|
||||
OTLWF_CTL_CODE(112, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otIp6Address - aMeshLocalEid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MESH_LOCAL_PREFIX \
|
||||
OTLWF_CTL_CODE(113, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otMeshLocalPrefix - aPrefix
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_NETWORK_DATA_LEADER \
|
||||
OTLWF_CTL_CODE(114, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t[] - aData
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_NETWORK_DATA_LOCAL \
|
||||
OTLWF_CTL_CODE(115, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t[] - aData
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_NETWORK_NAME \
|
||||
OTLWF_CTL_CODE(116, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otNetworkName - aNetworkName
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_PAN_ID \
|
||||
OTLWF_CTL_CODE(117, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otPanId - aPanId
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ROUTER_ROLL_ENABLED \
|
||||
OTLWF_CTL_CODE(118, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// BOOLEAN - aEnabled
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SHORT_ADDRESS \
|
||||
OTLWF_CTL_CODE(119, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otShortAddress - aShortAddress
|
||||
|
||||
|
||||
/* NOT USED
|
||||
#define IOCTL_OTLWF_OT_UNICAST_ADDRESSES \
|
||||
OTLWF_CTL_CODE(120, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otNetifAddress[] - aAddresses
|
||||
*/
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ACTIVE_DATASET \
|
||||
OTLWF_CTL_CODE(121, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otOperationalDataset - aDataset
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_PENDING_DATASET \
|
||||
OTLWF_CTL_CODE(122, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otOperationalDataset - aDataset
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LOCAL_LEADER_WEIGHT \
|
||||
OTLWF_CTL_CODE(123, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aWeight
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ADD_BORDER_ROUTER \
|
||||
OTLWF_CTL_CODE(124, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otBorderRouterConfig - aConfig
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_REMOVE_BORDER_ROUTER \
|
||||
OTLWF_CTL_CODE(125, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otIp6Prefix - aPrefix
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ADD_EXTERNAL_ROUTE \
|
||||
OTLWF_CTL_CODE(126, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExternalRouteConfig - aConfig
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_REMOVE_EXTERNAL_ROUTE \
|
||||
OTLWF_CTL_CODE(127, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otIp6Prefix - aPrefix
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_SERVER_DATA \
|
||||
OTLWF_CTL_CODE(128, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CONTEXT_ID_REUSE_DELAY \
|
||||
OTLWF_CTL_CODE(129, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aDelay
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_KEY_SEQUENCE_COUNTER \
|
||||
OTLWF_CTL_CODE(130, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aKeySequenceCounter
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_NETWORK_ID_TIMEOUT \
|
||||
OTLWF_CTL_CODE(131, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aTimeout
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ROUTER_UPGRADE_THRESHOLD \
|
||||
OTLWF_CTL_CODE(132, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aThreshold
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_RELEASE_ROUTER_ID \
|
||||
OTLWF_CTL_CODE(133, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aRouterId
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MAC_WHITELIST_ENABLED \
|
||||
OTLWF_CTL_CODE(134, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// BOOLEAN - aEnabled
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ADD_MAC_WHITELIST \
|
||||
OTLWF_CTL_CODE(135, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aExtAddr
|
||||
// int8_t - aRssi (optional)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_REMOVE_MAC_WHITELIST \
|
||||
OTLWF_CTL_CODE(136, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aExtAddr
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MAC_WHITELIST_ENTRY \
|
||||
OTLWF_CTL_CODE(137, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aIndex (input)
|
||||
// otMacWhitelistEntry - aEntry (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CLEAR_MAC_WHITELIST \
|
||||
OTLWF_CTL_CODE(138, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_DEVICE_ROLE \
|
||||
OTLWF_CTL_CODE(139, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otDeviceRole - aRole
|
||||
// otMleAttachFilter - aFilter (only for kDeviceRoleChild)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CHILD_INFO_BY_ID \
|
||||
OTLWF_CTL_CODE(140, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint16_t - aChildId (input)
|
||||
// otChildInfo - aChildInfo (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CHILD_INFO_BY_INDEX \
|
||||
OTLWF_CTL_CODE(141, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aChildIndex (input)
|
||||
// otChildInfo - aChildInfo (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_EID_CACHE_ENTRY \
|
||||
OTLWF_CTL_CODE(142, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aIndex (input)
|
||||
// otEidCacheEntry - aEntry (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LEADER_DATA \
|
||||
OTLWF_CTL_CODE(143, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otLeaderData - aLeaderData
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LEADER_ROUTER_ID \
|
||||
OTLWF_CTL_CODE(144, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aRouterID
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LEADER_WEIGHT \
|
||||
OTLWF_CTL_CODE(145, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aWeight
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_NETWORK_DATA_VERSION \
|
||||
OTLWF_CTL_CODE(146, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aVersion
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_PARTITION_ID \
|
||||
OTLWF_CTL_CODE(147, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aPartition
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_RLOC16 \
|
||||
OTLWF_CTL_CODE(148, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint16_t - aRloc16
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ROUTER_ID_SEQUENCE \
|
||||
OTLWF_CTL_CODE(149, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aIdSequence
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ROUTER_INFO \
|
||||
OTLWF_CTL_CODE(150, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint16_t - aRouterId (input)
|
||||
// otRouterInfo - aRouterInfo (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_STABLE_NETWORK_DATA_VERSION \
|
||||
OTLWF_CTL_CODE(151, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aVersion
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MAC_BLACKLIST_ENABLED \
|
||||
OTLWF_CTL_CODE(152, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// BOOLEAN - aEnabled
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ADD_MAC_BLACKLIST \
|
||||
OTLWF_CTL_CODE(153, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aExtAddr
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_REMOVE_MAC_BLACKLIST \
|
||||
OTLWF_CTL_CODE(154, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aExtAddr
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MAC_BLACKLIST_ENTRY \
|
||||
OTLWF_CTL_CODE(155, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aIndex (input)
|
||||
// otMacBlacklistEntry - aEntry (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_CLEAR_MAC_BLACKLIST \
|
||||
OTLWF_CTL_CODE(156, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MAX_TRANSMIT_POWER \
|
||||
OTLWF_CTL_CODE(157, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// int8_t - aPower
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_NEXT_ON_MESH_PREFIX \
|
||||
OTLWF_CTL_CODE(158, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
@@ -467,37 +467,37 @@ typedef enum _OTLWF_NOTIF_TYPE
|
||||
// uint8_t - aIterator (input)
|
||||
// uint8_t - aNewIterator (output)
|
||||
// otBorderRouterConfig - aConfig (output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_POLL_PERIOD \
|
||||
OTLWF_CTL_CODE(159, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aPollPeriod
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_LOCAL_LEADER_PARTITION_ID \
|
||||
OTLWF_CTL_CODE(160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aPartitionId
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY \
|
||||
OTLWF_CTL_CODE(161, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aExtAddr (input)
|
||||
// uint8_t - aLinkQuality (input or output)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_PLATFORM_RESET \
|
||||
OTLWF_CTL_CODE(162, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_PARENT_INFO \
|
||||
OTLWF_CTL_CODE(163, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otRouterInfo - aParentInfo
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SINGLETON \
|
||||
OTLWF_CTL_CODE(164, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// BOOLEAN - aSingleton
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_MAC_COUNTERS \
|
||||
OTLWF_CTL_CODE(165, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
@@ -507,11 +507,11 @@ typedef enum _OTLWF_NOTIF_TYPE
|
||||
OTLWF_CTL_CODE(166, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aMaxChildren
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISIONER_START \
|
||||
OTLWF_CTL_CODE(167, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISIONER_STOP \
|
||||
OTLWF_CTL_CODE(168, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
@@ -531,38 +531,38 @@ typedef struct otCommissionConfig
|
||||
char VendorSwVersion[OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH + 1];
|
||||
char VendorData[OPENTHREAD_VENDOR_DATA_MAX_LENGTH + 1];
|
||||
} otCommissionConfig;
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_JOINER_START \
|
||||
OTLWF_CTL_CODE(169, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otCommissionConfig - aConfig
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_JOINER_STOP \
|
||||
OTLWF_CTL_CODE(170, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_FACTORY_EUI64 \
|
||||
OTLWF_CTL_CODE(171, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aEui64
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_HASH_MAC_ADDRESS \
|
||||
OTLWF_CTL_CODE(172, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otExtAddress - aEui64
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ROUTER_DOWNGRADE_THRESHOLD \
|
||||
OTLWF_CTL_CODE(173, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aThreshold
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISSIONER_PANID_QUERY \
|
||||
OTLWF_CTL_CODE(174, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint16_t - aPanId
|
||||
// uint32_t - aChannekMask
|
||||
// otIp6Address - aAddress
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISSIONER_ENERGY_SCAN \
|
||||
OTLWF_CTL_CODE(175, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
@@ -571,49 +571,49 @@ typedef struct otCommissionConfig
|
||||
// uint16_t - aPeriod
|
||||
// uint16_t - aScanDuration
|
||||
// otIp6Address - aAddress
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ROUTER_SELECTION_JITTER \
|
||||
OTLWF_CTL_CODE(176, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aRouterJitter
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_JOINER_UDP_PORT \
|
||||
OTLWF_CTL_CODE(177, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint16_t - aJoinerUdpPort
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_DIAGNOSTIC_GET \
|
||||
OTLWF_CTL_CODE(178, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otIp6Address - aDestination
|
||||
// uint8_t - aCount
|
||||
// uint8_t[aCount] - aTlvTypes
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_DIAGNOSTIC_RESET \
|
||||
OTLWF_CTL_CODE(179, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otIp6Address - aDestination
|
||||
// uint8_t - aCount
|
||||
// uint8_t[aCount] - aTlvTypes
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISIONER_ADD_JOINER \
|
||||
OTLWF_CTL_CODE(180, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aExtAddressValid
|
||||
// otExtAddress - aExtAddress (optional)
|
||||
// char[OPENTHREAD_PSK_MAX_LENGTH + 1] - aPSKd
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISIONER_REMOVE_JOINER \
|
||||
OTLWF_CTL_CODE(181, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aExtAddressValid
|
||||
// otExtAddress - aExtAddress (optional)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISIONER_PROVISIONING_URL \
|
||||
OTLWF_CTL_CODE(182, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// char[OPENTHREAD_PROV_URL_MAX_LENGTH + 1] - aProvisioningUrl (optional)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_COMMISIONER_ANNOUNCE_BEGIN \
|
||||
OTLWF_CTL_CODE(183, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
@@ -621,70 +621,75 @@ typedef struct otCommissionConfig
|
||||
// uint8_t - aCount
|
||||
// uint16_t - aPeriod
|
||||
// otIp6Address - aAddress
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_ENERGY_SCAN \
|
||||
OTLWF_CTL_CODE(184, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aScanChannels
|
||||
// uint16_t - aScanDuration
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_ACTIVE_GET \
|
||||
OTLWF_CTL_CODE(185, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aLength
|
||||
// uint8_t[aLength] - aTlvTypes
|
||||
// otIp6Address - aAddress (optional)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_ACTIVE_SET \
|
||||
OTLWF_CTL_CODE(186, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otOperationalDataset - aDataset
|
||||
// uint8_t - aLength
|
||||
// uint8_t[aLength] - aTlvTypes
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_PENDING_GET \
|
||||
OTLWF_CTL_CODE(187, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aLength
|
||||
// uint8_t[aLength] - aTlvTypes
|
||||
// otIp6Address - aAddress (optional)
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_PENDING_SET \
|
||||
OTLWF_CTL_CODE(188, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otOperationalDataset - aDataset
|
||||
// uint8_t - aLength
|
||||
// uint8_t[aLength] - aTlvTypes
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_GET \
|
||||
OTLWF_CTL_CODE(189, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aLength
|
||||
// uint8_t[aLength] - aTlvs
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_SET \
|
||||
OTLWF_CTL_CODE(190, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// otOperationalDataset - aDataset
|
||||
// uint8_t - aLength
|
||||
// uint8_t[aLength] - aTlvs
|
||||
|
||||
|
||||
#define IOCTL_OTLWF_OT_KEY_SWITCH_GUARDTIME \
|
||||
OTLWF_CTL_CODE(191, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint32_t - aKeySwitchGuardTime
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#define IOCTL_OTLWF_OT_PREFERRED_ROUTER_ID \
|
||||
OTLWF_CTL_CODE(194, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
// GUID - InterfaceGuid
|
||||
// uint8_t - aRouterId
|
||||
|
||||
// OpenThread function IOCTL codes
|
||||
#define MIN_OTLWF_IOCTL_FUNC_CODE 100
|
||||
#define MAX_OTLWF_IOCTL_FUNC_CODE 193
|
||||
#define MAX_OTLWF_IOCTL_FUNC_CODE 194
|
||||
|
||||
#endif //__OTLWFIOCTL_H__
|
||||
|
||||
@@ -1867,6 +1867,18 @@ otThreadSetRouterRoleEnabled(
|
||||
if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_ROLL_ENABLED, (BOOLEAN)aEnabled);
|
||||
}
|
||||
|
||||
OTAPI
|
||||
ThreadError
|
||||
OTCALL
|
||||
otThreadSetPreferredRouterId(
|
||||
_In_ otInstance *aInstance,
|
||||
uint8_t aRouterId
|
||||
)
|
||||
{
|
||||
if (aInstance == nullptr) return kThreadError_InvalidArgs;
|
||||
return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PAN_ID, aRouterId));
|
||||
}
|
||||
|
||||
OTAPI
|
||||
otShortAddress
|
||||
OTCALL
|
||||
|
||||
@@ -138,7 +138,8 @@ OTLWF_IOCTL_HANDLER IoCtls[] =
|
||||
{ "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_THREAD_AUTO_START", REF_IOCTL_FUNC(otThreadAutoStart) }
|
||||
{ "IOCTL_OTLWF_OT_THREAD_AUTO_START", REF_IOCTL_FUNC(otThreadAutoStart) },
|
||||
{ "IOCTL_OTLWF_OT_PREFERRED_ROUTER_ID", REF_IOCTL_FUNC(otThreadPreferredRouterId) },
|
||||
};
|
||||
|
||||
static_assert(ARRAYSIZE(IoCtls) == (MAX_OTLWF_IOCTL_FUNC_CODE - MIN_OTLWF_IOCTL_FUNC_CODE) + 1,
|
||||
@@ -6084,3 +6085,34 @@ otLwfIoCtl_otThreadAutoStart(
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
NTSTATUS
|
||||
otLwfIoCtl_otThreadPreferredRouterId(
|
||||
_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;
|
||||
|
||||
*OutBufferLength = 0;
|
||||
UNREFERENCED_PARAMETER(OutBuffer);
|
||||
|
||||
if (InBufferLength >= sizeof(uint8_t))
|
||||
{
|
||||
status =
|
||||
ThreadErrorToNtstatus(
|
||||
otThreadSetPreferredRouterId(
|
||||
pFilter->otCtx,
|
||||
*(uint8_t*)InBuffer != FALSE)
|
||||
);
|
||||
*OutBufferLength = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -225,5 +225,6 @@ DECL_IOCTL_FUNC(otSendMgmtCommissionerSet);
|
||||
DECL_IOCTL_FUNC_WITH_TUN2(otKeySwitchGuardtime);
|
||||
DECL_IOCTL_FUNC(otFactoryReset);
|
||||
DECL_IOCTL_FUNC(otThreadAutoStart);
|
||||
DECL_IOCTL_FUNC(otThreadPreferredRouterId);
|
||||
|
||||
#endif // _IOCONTROL_H
|
||||
|
||||
@@ -366,7 +366,7 @@ OTAPI void OTCALL otThreadSetRouterRoleEnabled(otInstance *aInstance, bool aEnab
|
||||
* @retval kThreadError_InvalidState Could not set (role is not detached or disabled)
|
||||
*
|
||||
*/
|
||||
ThreadError otThreadSetPreferredRouterId(otInstance *aInstance, uint8_t aRouterId);
|
||||
OTAPI ThreadError OTCALL otThreadSetPreferredRouterId(otInstance *aInstance, uint8_t aRouterId);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
Reference in New Issue
Block a user