Add an initial Windows Universal App for OpenThread (#951)

* Add an initial Windows Universal App for OpenThread
This commit is contained in:
Nick Banks
2016-11-09 23:25:34 +08:00
committed by Jonathan Hui
parent a91c30d8c8
commit 851027d912
22 changed files with 1300 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
<!--
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.
-->
<Application
x:Class="Thread.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Thread"
RequestedTheme="Dark">
</Application>
+146
View File
@@ -0,0 +1,146 @@
/*
* 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.
*/
#include "pch.h"
#include "MainPage.xaml.h"
using namespace Thread;
using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
#if _DEBUG
// Show graphics profiling information while debugging.
if (IsDebuggerPresent())
{
// Display the current frame rate counters
DebugSettings->EnableFrameRateCounter = true;
}
#endif
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
rootFrame = ref new Frame();
rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);
if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
{
// TODO: Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}
if (e->PrelaunchActivated == false)
{
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
}
// Place the frame in the current Window
Window::Current->Content = rootFrame;
// Ensure the current window is active
Window::Current->Activate();
}
}
else
{
if (e->PrelaunchActivated == false)
{
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
}
// Ensure the current window is active
Window::Current->Activate();
}
}
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
//TODO: Save application state and stop any background activity
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
{
throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
}
+50
View File
@@ -0,0 +1,50 @@
/*
* 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 "App.g.h"
namespace Thread
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
ref class App sealed
{
protected:
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
internal:
App();
private:
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
};
}
+285
View File
@@ -0,0 +1,285 @@
<!--
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.
-->
<Page
x:Class="Thread.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Thread"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
IsTabStop="false"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!-- Interface List -->
<TextBlock
Text="Thread UX"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="20"
FontSize="50"
/>
<TextBlock
Text="Interfaces"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="60,90"
FontSize="25"
/>
<ListView
Name="InterfaceList"
Margin="60,130,20,150"
SelectionMode="None">
</ListView>
<!-- Interface Configuration -->
<Grid
x:Name="InterfaceConfiguration"
Background="#B2FFFFFF"
Visibility="Collapsed"
>
<StackPanel
Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
Width="600"
Height="360"
HorizontalAlignment="Center"
VerticalAlignment="Center"
>
<TextBlock
Text="Interface Configuration"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="20"
FontSize="25"
/>
<Grid Margin="40,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TextBlock
Text="Name"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBox
Name="InterfaceConfigName"
Text="Test Network"
Grid.Column="1"
FontSize="18"
VerticalAlignment="Center"
/>
<TextBlock
Text="Key"
FontSize="22"
VerticalAlignment="Center"
Grid.Row="1"
/>
<TextBox
Name="InterfaceConfigKey"
Text="Pas$W0rd"
Grid.Row="1"
Grid.Column="1"
FontSize="18"
VerticalAlignment="Center"
/>
<TextBlock
Text="Max Children"
FontSize="22"
VerticalAlignment="Center"
Grid.Row="2"
/>
<Slider
Name="InterfaceConfigMaxChildren"
Grid.Row="2"
Grid.Column="1"
Minimum="11"
Maximum="26"
Value="15"
VerticalAlignment="Center"
/>
<TextBlock
Text="Channel"
FontSize="22"
VerticalAlignment="Center"
Grid.Row="3"
/>
<Slider
Name="InterfaceConfigChannel"
Grid.Row="3"
Grid.Column="1"
Minimum="11"
Maximum="24"
Value="5"
VerticalAlignment="Center"
/>
<StackPanel
Grid.Row="5"
Grid.ColumnSpan="2"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button
Name="InterfaceConfigOkButton"
Content="Ok"
FontSize="22"
Margin="20,0"
/>
<Button
Name="InterfaceConfigCancelButton"
Content="Cancel"
FontSize="22"
Margin="20,0"
/>
</StackPanel>
</Grid>
</StackPanel>
</Grid>
<!-- Interface Details -->
<Grid
x:Name="InterfaceDetails"
Background="#B2FFFFFF"
Visibility="Collapsed"
>
<StackPanel
Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
Width="600"
Height="405"
HorizontalAlignment="Center"
VerticalAlignment="Center"
>
<TextBlock
Text="Interface Details"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="20"
FontSize="25"
/>
<Grid Margin="40,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TextBlock
Text="MAC"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceMacAddress"
Text="00:00:00:00:00:00:00:00"
Grid.Column="1"
FontSize="18"
VerticalAlignment="Center"
/>
<TextBlock
Text="ML-EID"
Grid.Row="1"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceML_EID"
Text="::01"
Grid.Row="1"
Grid.Column="1"
FontSize="18"
VerticalAlignment="Center"
/>
<TextBlock
Text="RLOC"
Grid.Row="2"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceRLOC"
Text="::01"
Grid.Row="2"
Grid.Column="1"
FontSize="18"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceNeighborsText"
Text="Neighbors"
Grid.Row="3"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceNeighbors"
Text="0"
Grid.Row="3"
Grid.Column="1"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceChildrenText"
Text="Children"
Grid.Row="4"
FontSize="22"
VerticalAlignment="Center"
/>
<TextBlock
Name="InterfaceChildren"
Text="0"
Grid.Row="4"
Grid.Column="1"
FontSize="22"
VerticalAlignment="Center"
/>
<Button
Name="InterfaceDetailsCloseButton"
Grid.Row="6"
Grid.ColumnSpan="2"
Content="Close"
HorizontalAlignment="Center"
FontSize="22"
/>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Page>
+407
View File
@@ -0,0 +1,407 @@
/*
* 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.
*/
#include "pch.h"
#include "MainPage.xaml.h"
using namespace Thread;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
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)
{
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";
}
return L"Unknown Role State";
}
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()
{
InitializeComponent();
MainPage::Current = this;
_isFullScreen = false;
_apiInstance = nullptr;
InterfaceConfigCancelButton->Click +=
ref new RoutedEventHandler(
[=](Platform::Object^, RoutedEventArgs^) {
InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
);
InterfaceConfigOkButton->Click +=
ref new RoutedEventHandler(
[=](Platform::Object^, RoutedEventArgs^) {
InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
ConnectNetwork(_currentInterface);
}
);
InterfaceDetailsCloseButton->Click +=
ref new RoutedEventHandler(
[=](Platform::Object^, RoutedEventArgs^) {
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)
{
// Register for device availability callbacks
otSetDeviceAvailabilityChangedCallback(ApiInstance, ThreadDeviceAvailabilityCallback, nullptr);
// Build the initial list
BuildInterfaceList();
}
}
void MainPage::OnUnloaded(Object^ sender, RoutedEventArgs^ e)
{
// Unregister for callbacks
otSetDeviceAvailabilityChangedCallback(ApiInstance, nullptr, nullptr);
// Clean up api handle
otApiFinalize(ApiInstance);
_apiInstance = nullptr;
}
void MainPage::OnResuming()
{
}
void MainPage::OnWindowSizeChanged(Object^ sender, SizeChangedEventArgs^ args)
{
_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 = otGetExtendedAddress(device);
if (extendedAddress)
{
WCHAR szMac[256] = { 0 };
swprintf_s(szMac, 256, MAC8_FORMAT, MAC8_ARG(extendedAddress));
InterfaceMacAddress->Text = ref new String(szMac);
otFreeMemory(extendedAddress);
}
else
{
InterfaceMacAddress->Text = L"ERROR";
}
auto ml_eid = otGetMeshLocalEid(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 = otGetRloc16(device);
WCHAR szRloc[16] = { 0 };
swprintf_s(szRloc, 16, L"%4x", rloc16);
InterfaceRLOC->Text = ref new String(szRloc);
if (otGetDeviceRole(device) > kDeviceRoleChild)
{
uint8_t index = 0;
otChildInfo childInfo;
while (kThreadError_None == otGetChildInfoByIndex(device, 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;
}
// Show the details
InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Visible;
otFreeMemory(device);
}
UIElement^ MainPage::CreateNewInterface(Platform::Guid InterfaceGuid)
{
GUID deviceGuid = InterfaceGuid;
auto device = otInstanceInit(ApiInstance, &deviceGuid);
auto deviceRole = otGetDeviceRole(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)
{
auto ConnectButton = ref new Button();
ConnectButton->Content = ref new String(L"Connect");
ConnectButton->Click +=
ref new RoutedEventHandler(
[=](Platform::Object^, RoutedEventArgs^) {
_currentInterface = InterfaceGuid;
InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Visible;
}
);
InterfaceStackPanel->Children->Append(ConnectButton);
}
else
{
auto DetailsButton = ref new Button();
DetailsButton->Content = ref new String(L"Details");
DetailsButton->Click +=
ref new RoutedEventHandler(
[=](Platform::Object^, RoutedEventArgs^) {
ShowInterfaceDetails(InterfaceGuid);
}
);
InterfaceStackPanel->Children->Append(DetailsButton);
auto DisconnectButton = ref new Button();
DisconnectButton->Content = ref new String(L"Disconnect");
DisconnectButton->Click +=
ref new RoutedEventHandler(
[=](Platform::Object^, RoutedEventArgs^) {
DisconnectNetwork(InterfaceGuid);
}
);
InterfaceStackPanel->Children->Append(DisconnectButton);
}
// 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)
{
// 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)
{
// 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)
{
if (ApiInstance == nullptr) return;
GUID deviceGuid = InterfaceGuid;
auto device = otInstanceInit(ApiInstance, &deviceGuid);
//
// Configure
//
otNetworkName networkName = {};
wcstombs(networkName.m8, InterfaceConfigName->Text->Data(), sizeof(networkName.m8));
otSetNetworkName(device, networkName.m8);
otMasterKey masterKey = {};
wcstombs((char*)masterKey.m8, InterfaceConfigKey->Text->Data(), sizeof(masterKey.m8));
otSetMasterKey(device, masterKey.m8, sizeof(masterKey.m8));
otSetChannel(device, (uint8_t)InterfaceConfigChannel->Value);
otSetMaxAllowedChildren(device, (uint8_t)InterfaceConfigMaxChildren->Value);
otSetPanId(device, 0x4567);
//
// Bring up the interface and start the Thread logic
//
otInterfaceUp(device);
otThreadStart(device);
// 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
//
otThreadStop(device);
otInterfaceDown(device);
// Cleanup
otFreeMemory(device);
}
+80
View File
@@ -0,0 +1,80 @@
/*
* 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 "MainPage.g.h"
namespace Thread
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
public:
MainPage();
void OnResuming();
void BuildInterfaceList();
void ConnectNetwork(Platform::Guid InterfaceGuid);
void ShowInterfaceDetails(Platform::Guid InterfaceGuid);
void DisconnectNetwork(Platform::Guid InterfaceGuid);
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
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 *_apiInstance;
#define ApiInstance ((otApiInstance*)_apiInstance)
std::vector<void*> _devices;
Platform::Guid _currentInterface;
internal:
static MainPage^ Current;
};
}
Binary file not shown.
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
<Identity Name="7926e3f9-835e-421c-94c1-2812f3569f4a" Publisher="CN=nibanks" Version="1.0.10.0" />
<mp:PhoneIdentity PhoneProductId="7926e3f9-835e-421c-94c1-2812f3569f4a" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>OpenThread</DisplayName>
<PublisherDisplayName>OpenThread</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="Thread.App">
<uap:VisualElements DisplayName="OpenThread" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="OpenThread" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<Capability Name="privateNetworkClientServer" />
<Capability Name="internetClientServer" />
</Capabilities>
</Package>
+29
View File
@@ -0,0 +1,29 @@
/*
* 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.
*/
#include "pch.h"
+46
View File
@@ -0,0 +1,46 @@
/*
* 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 _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <Windows.h>
#include <collection.h>
#include <ppltasks.h>
#include <ws2def.h>
#include <ws2ipdef.h>
#include <mstcpip.h>
#define OTDLL 1
#include <openthread.h>
#include <commissioning/commissioner.h>
#include <commissioning/joiner.h>
#include "App.xaml.h"