mirror of
https://github.com/espressif/openthread.git
synced 2026-10-01 05:17:40 +00:00
[windows] remove unsupported platform (#3878)
This commit is contained in:
committed by
Jonathan Hui
parent
e482edb0f1
commit
c14cc60962
@@ -1,35 +0,0 @@
|
||||
<!--
|
||||
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="ot.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ot"
|
||||
RequestedTheme="Dark">
|
||||
|
||||
</Application>
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* 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 ot;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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 ot
|
||||
{
|
||||
/// <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);
|
||||
};
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public ref class ClientArgs sealed
|
||||
{
|
||||
public:
|
||||
property Windows::Networking::HostName^ ServerHostName;
|
||||
property Platform::String^ ServerPort;
|
||||
property Windows::Networking::HostName^ ClientHostName;
|
||||
property Platform::String^ ClientPort;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,142 +0,0 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<UserControl
|
||||
x:Class="ot.ClientControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ot"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Text="Server IP :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
x:Name="ServerIP"
|
||||
MinWidth="500"
|
||||
/>
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Text="Server Port :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
x:Name="ServerPort"
|
||||
Width="100"
|
||||
HorizontalAlignment="Left"
|
||||
/>
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Text="Client IP :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
x:Name="ClientIP"
|
||||
MinWidth="500"
|
||||
/>
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Text="Client Port :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="6"
|
||||
Grid.Column="2"
|
||||
x:Name="ClientPort"
|
||||
Width="100"
|
||||
HorizontalAlignment="Left"
|
||||
/>
|
||||
<Button
|
||||
Grid.Row="8"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Width="75"
|
||||
Content="Connect"
|
||||
Click="Connect_Click"
|
||||
/>
|
||||
<TextBlock
|
||||
Grid.Row="10"
|
||||
Grid.Column="0"
|
||||
Text="Input :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="10"
|
||||
Grid.Column="2"
|
||||
x:Name="Input"
|
||||
MinWidth="300"
|
||||
/>
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Top"
|
||||
Grid.Row="12"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
>
|
||||
<Button
|
||||
Width="75"
|
||||
Content="Send"
|
||||
Click="Send_Click"
|
||||
Margin="0,0,75,0"
|
||||
/>
|
||||
<Button
|
||||
Width="75"
|
||||
Content="Exit"
|
||||
Click="Exit_Click"
|
||||
/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include <algorithm>
|
||||
#include "ClientControl.xaml.h"
|
||||
#include "Factory.h"
|
||||
#include "TalkHelper.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI;
|
||||
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;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
std::atomic<int> ClientControl::_clientPort{ TalkConsts::DEF_CLIENT_PORT_INIT };
|
||||
|
||||
ClientControl::ClientControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ServerPort->Text = DEF_SERVER_PORT.ToString();
|
||||
auto clientPort = _clientPort.load();
|
||||
ClientPort->Text = clientPort.ToString();
|
||||
}
|
||||
|
||||
void
|
||||
ClientControl::Init(
|
||||
IAsyncThreadNotify^ notify,
|
||||
IMainPageUIElements^ mainPageUIElements)
|
||||
{
|
||||
_notify = std::move(notify);
|
||||
_mainPageUIElements = std::move(mainPageUIElements);
|
||||
}
|
||||
|
||||
void
|
||||
ClientControl::ProtocolChanged(
|
||||
Protocol protocol)
|
||||
{
|
||||
_protocol = protocol;
|
||||
}
|
||||
|
||||
void
|
||||
ClientControl::Connect_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto clientArgs = ref new ClientArgs();
|
||||
|
||||
auto serverIP = ServerIP->Text;
|
||||
if (serverIP->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Server IP");
|
||||
}
|
||||
|
||||
// check valid chars of Ipv6 Address
|
||||
if (!TalkHelper::AllValidIpv6Chars(serverIP->Data(), serverIP->Data() + serverIP->Length()))
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "Not a valid Server IPv6 address");
|
||||
}
|
||||
|
||||
clientArgs->ServerHostName = ref new HostName(serverIP);
|
||||
|
||||
if (ServerPort->Text->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Server Port");
|
||||
}
|
||||
clientArgs->ServerPort = ServerPort->Text;
|
||||
|
||||
auto clientIP = ClientIP->Text;
|
||||
if (clientIP->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Client IP");
|
||||
}
|
||||
|
||||
// check valid chars of Ipv6 Address
|
||||
if (!TalkHelper::AllValidIpv6Chars(clientIP->Data(), clientIP->Data() + clientIP->Length()))
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "Not a valid client IPv6 address");
|
||||
}
|
||||
|
||||
clientArgs->ClientHostName = ref new HostName(clientIP);
|
||||
|
||||
if (ClientPort->Text->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Client Port");
|
||||
}
|
||||
clientArgs->ClientPort = ClientPort->Text;
|
||||
|
||||
auto cleintContext = Factory::CreateClientContext(_notify, clientArgs, _protocol);
|
||||
cleintContext->Connect_Click(sender, e);
|
||||
|
||||
// fix Only usage of each socket address (protocol/network address/port)
|
||||
// is normally permitted.
|
||||
auto clientPort = ++_clientPort;
|
||||
ClientPort->Text = clientPort.ToString();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Connecting failed with input error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientControl::Send_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto input = Input->Text;
|
||||
if (input->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Input");
|
||||
}
|
||||
|
||||
if (!CoreApplication::Properties->HasKey("clientContext"))
|
||||
{
|
||||
throw Exception::CreateException(E_UNEXPECTED, "Not Connected");
|
||||
}
|
||||
|
||||
auto clientContext = dynamic_cast<IClientContext^>(
|
||||
CoreApplication::Properties->Lookup("clientContext"));
|
||||
if (clientContext == nullptr)
|
||||
{
|
||||
throw Exception::CreateException(E_UNEXPECTED, "No clientContext");
|
||||
}
|
||||
|
||||
clientContext->Send_Click(sender, e, input);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Sending message failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientControl::Exit_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
_mainPageUIElements->TalkGrid->Visibility = Xaml::Visibility::Collapsed;
|
||||
_mainPageUIElements->ThreadGrid->Visibility = Xaml::Visibility::Visible;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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 <atomic>
|
||||
#include "ClientControl.g.h"
|
||||
#include "TalkConsts.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "IMainPageUIElements.h"
|
||||
#include "Protocol.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class ClientControl sealed
|
||||
{
|
||||
public:
|
||||
ClientControl();
|
||||
|
||||
void Init(IAsyncThreadNotify^ notify, IMainPageUIElements^ mainPageUIElements);
|
||||
|
||||
void ProtocolChanged(Protocol protocol);
|
||||
|
||||
private:
|
||||
static constexpr unsigned short DEF_SERVER_PORT = TalkConsts::DEF_SERVER_PORT;
|
||||
|
||||
void Connect_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void Send_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void Exit_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
IAsyncThreadNotify^ _notify;
|
||||
IMainPageUIElements^ _mainPageUIElements;
|
||||
Protocol _protocol;
|
||||
static std::atomic<int> _clientPort;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include "DatagramClientContext.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Networking::Sockets;
|
||||
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;
|
||||
|
||||
DatagramClientContext::DatagramClientContext(
|
||||
IAsyncThreadNotify^ notify,
|
||||
DatagramSocket^ client,
|
||||
ClientArgs^ args) :
|
||||
_notify{ std::move(notify) },
|
||||
_client{ std::move(client) },
|
||||
_args{ std::move(args) }
|
||||
{
|
||||
}
|
||||
|
||||
DatagramClientContext::~DatagramClientContext()
|
||||
{
|
||||
// A Client can be closed in two ways:
|
||||
// - explicitly: using the 'delete' keyword (client is closed even if there are outstanding references to it).
|
||||
// - implicitly: removing the last reference to it (i.e., falling out-of-scope).
|
||||
//
|
||||
// When a Socket is closed implicitly, it can take several seconds for the local port being used
|
||||
// by it to be freed/reclaimed by the lower networking layers. During that time, other sockets on the machine
|
||||
// will not be able to use the port. Thus, it is strongly recommended that Socket instances be explicitly
|
||||
// closed before they go out of scope(e.g., before application exit). The call below explicitly closes the socket.
|
||||
if (_client != nullptr)
|
||||
{
|
||||
delete _client;
|
||||
_client = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DatagramClientContext::Connect_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
task<void> removeContext;
|
||||
|
||||
if (CoreApplication::Properties->HasKey("clientContext"))
|
||||
{
|
||||
auto clientContext = dynamic_cast<IClientContext^>(
|
||||
CoreApplication::Properties->Lookup("clientContext"));
|
||||
if (clientContext == nullptr)
|
||||
{
|
||||
throw ref new FailureException(L"No clientContext");
|
||||
}
|
||||
|
||||
removeContext = create_task(clientContext->CancelIO()).then(
|
||||
[]()
|
||||
{
|
||||
CoreApplication::Properties->Remove("clientContext");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
removeContext = create_task([]() {});
|
||||
}
|
||||
|
||||
_client->MessageReceived += ref new MessageHandler(
|
||||
this, &DatagramClientContext::OnMessage);
|
||||
|
||||
removeContext.then([this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
|
||||
// Events cannot be hooked up directly to the ScenarioInput2 object, as the object can fall out-of-scope and be
|
||||
// deleted. This would render any event hooked up to the object ineffective. The ClientContext guarantees that
|
||||
// both the socket and object that serves its events have the same lifetime.
|
||||
CoreApplication::Properties->Insert("clientContext", this);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Remove clientContext error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
}
|
||||
}).then([this]()
|
||||
{
|
||||
auto endpointPair = ref new EndpointPair(_args->ClientHostName, _args->ClientPort,
|
||||
_args->ServerHostName, _args->ServerPort);
|
||||
|
||||
_notify->NotifyFromAsyncThread("Start connecting", NotifyType::Status);
|
||||
|
||||
create_task(_client->ConnectAsync(endpointPair)).then(
|
||||
[this, endpointPair](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Connect from " + endpointPair->LocalHostName->CanonicalName +
|
||||
" to " + endpointPair->RemoteHostName->CanonicalName,
|
||||
NotifyType::Status);
|
||||
SetConnected(true);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Start binding failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
CoreApplication::Properties->Remove("clientContext");
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
CoreApplication::Properties->Remove("clientContext");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
DatagramClientContext::Send_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e,
|
||||
String^ input)
|
||||
{
|
||||
SendMessage(GetDataWriter(), input);
|
||||
}
|
||||
|
||||
IAsyncAction^
|
||||
DatagramClientContext::CancelIO()
|
||||
{
|
||||
return _client->CancelIOAsync();
|
||||
}
|
||||
|
||||
void
|
||||
DatagramClientContext::SetConnected(
|
||||
bool connected)
|
||||
{
|
||||
_connected = connected;
|
||||
}
|
||||
|
||||
bool
|
||||
ot::DatagramClientContext::IsConnected() const
|
||||
{
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void
|
||||
ot::DatagramClientContext::OnMessage(
|
||||
DatagramSocket^ socket,
|
||||
MessageReceivedEventArgs^ eventArgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto dataReader = eventArgs->GetDataReader();
|
||||
Receive(dataReader, dataReader->UnconsumedBufferLength);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
auto socketError = SocketError::GetStatus(ex->HResult);
|
||||
if (socketError == SocketErrorStatus::ConnectionResetByPeer)
|
||||
{
|
||||
// This error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Peer does not listen on the specific port. Please make sure that you run step 1 first "
|
||||
"or you have a server properly working on a remote server.",
|
||||
NotifyType::Error);
|
||||
}
|
||||
else if (socketError != SocketErrorStatus::Unknown)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Error happened when receiving a datagram: " + socketError.ToString(),
|
||||
NotifyType::Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DatagramClientContext::Receive(
|
||||
DataReader^ dataReader,
|
||||
unsigned int strLen)
|
||||
{
|
||||
if (!strLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = dataReader->ReadString(strLen);
|
||||
_notify->NotifyFromAsyncThread("Received data from server: \"" + msg + "\"",
|
||||
NotifyType::Status);
|
||||
}
|
||||
|
||||
void
|
||||
DatagramClientContext::SendMessage(
|
||||
DataWriter^ dataWriter,
|
||||
String^ msg)
|
||||
{
|
||||
if (!IsConnected())
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("This socket is not yet connected.", NotifyType::Error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dataWriter->WriteString(msg);
|
||||
_notify->NotifyFromAsyncThread("Sending - " + msg, NotifyType::Status);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Sending failed with error: " + ex->Message, NotifyType::Error);
|
||||
}
|
||||
|
||||
// Write the locally buffered data to the network. Please note that write operation will succeed
|
||||
// even if the server is not listening.
|
||||
create_task(dataWriter->StoreAsync()).then(
|
||||
[this](task<unsigned int> writeTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
writeTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Send failed with error: " + ex->Message, NotifyType::Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Windows::Storage::Streams::DataWriter^
|
||||
DatagramClientContext::GetDataWriter()
|
||||
{
|
||||
if (_dataWriter == nullptr)
|
||||
{
|
||||
_dataWriter = ref new DataWriter(_client->OutputStream);
|
||||
}
|
||||
|
||||
return _dataWriter;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* 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 "IClientContext.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "ClientArgs.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class DatagramClientContext sealed : public IClientContext
|
||||
{
|
||||
public:
|
||||
using DatagramSocket = Windows::Networking::Sockets::DatagramSocket;
|
||||
|
||||
DatagramClientContext(IAsyncThreadNotify^ notify, DatagramSocket^ client, ClientArgs^ args);
|
||||
virtual ~DatagramClientContext();
|
||||
|
||||
virtual void Connect_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
virtual void Send_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e, Platform::String^ input);
|
||||
|
||||
virtual Windows::Foundation::IAsyncAction^ CancelIO();
|
||||
|
||||
private:
|
||||
using MessageReceivedEventArgs = Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs;
|
||||
using MessageHandler = Windows::Foundation::TypedEventHandler<DatagramSocket^, MessageReceivedEventArgs^>;
|
||||
using DataReader = Windows::Storage::Streams::DataReader;
|
||||
using DataWriter = Windows::Storage::Streams::DataWriter;
|
||||
using Args = ClientArgs;
|
||||
|
||||
void SetConnected(bool connected);
|
||||
bool IsConnected() const;
|
||||
|
||||
void OnMessage(DatagramSocket^ socket, MessageReceivedEventArgs^ eventArgs);
|
||||
void Receive(DataReader^, unsigned int strLen);
|
||||
|
||||
void SendMessage(DataWriter^, String^ msg);
|
||||
|
||||
DataWriter^ GetDataWriter();
|
||||
|
||||
IAsyncThreadNotify^ _notify;
|
||||
DatagramSocket^ _client;
|
||||
Args^ _args;
|
||||
bool _connected = false;
|
||||
DataReader^ _dataReader;
|
||||
DataWriter^ _dataWriter;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include "DatagramListenerContext.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Networking::Sockets;
|
||||
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;
|
||||
|
||||
DatagramListenerContext::DatagramListenerContext(
|
||||
IAsyncThreadNotify^ notify,
|
||||
DatagramSocket^ listener,
|
||||
ListenerArgs^ args) :
|
||||
_notify{ std::move(notify) },
|
||||
_listener{ std::move(listener) },
|
||||
_args{ std::move(args) }
|
||||
{
|
||||
}
|
||||
|
||||
DatagramListenerContext::~DatagramListenerContext()
|
||||
{
|
||||
// A Listener can be closed in two ways:
|
||||
// - explicitly: using the 'delete' keyword (listener is closed even if there are outstanding references to it).
|
||||
// - implicitly: removing the last reference to it (i.e., falling out-of-scope).
|
||||
//
|
||||
// When a Socket is closed implicitly, it can take several seconds for the local port being used
|
||||
// by it to be freed/reclaimed by the lower networking layers. During that time, other sockets on the machine
|
||||
// will not be able to use the port. Thus, it is strongly recommended that Socket instances be explicitly
|
||||
// closed before they go out of scope(e.g., before application exit). The call below explicitly closes the socket.
|
||||
if (_listener != nullptr)
|
||||
{
|
||||
delete _listener;
|
||||
_listener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DatagramListenerContext::Listen_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
task<void> removeContext;
|
||||
|
||||
if (CoreApplication::Properties->HasKey("listenerContext"))
|
||||
{
|
||||
auto listenerContext = dynamic_cast<IListenerContext^>(
|
||||
CoreApplication::Properties->Lookup("listenerContext"));
|
||||
if (listenerContext == nullptr)
|
||||
{
|
||||
throw ref new FailureException(L"No listenerContext");
|
||||
}
|
||||
|
||||
removeContext = create_task(listenerContext->CancelIO()).then(
|
||||
[]()
|
||||
{
|
||||
CoreApplication::Properties->Remove("listenerContext");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
removeContext = create_task([]() {});
|
||||
}
|
||||
|
||||
_listener->MessageReceived += ref new MessageHandler(
|
||||
this, &DatagramListenerContext::OnMessage);
|
||||
|
||||
removeContext.then([this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
|
||||
// Events cannot be hooked up directly to the ScenarioInput1 object, as the object can fall out-of-scope and be
|
||||
// deleted. This would render any event hooked up to the object ineffective. The ListenerContext guarantees that
|
||||
// both the listener and object that serves its events have the same lifetime.
|
||||
CoreApplication::Properties->Insert("listenerContext", this);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Remove listenerContext error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
}
|
||||
}).then([this]()
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Start listening", NotifyType::Status);
|
||||
|
||||
create_task(_listener->BindEndpointAsync(_args->ServerHostName, _args->ServerPort)).then(
|
||||
[this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Listening on address " + _args->ServerHostName->CanonicalName,
|
||||
NotifyType::Status);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Start listening failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
CoreApplication::Properties->Remove("listenerContext");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
IAsyncAction^
|
||||
DatagramListenerContext::CancelIO()
|
||||
{
|
||||
return _listener->CancelIOAsync();
|
||||
}
|
||||
|
||||
void
|
||||
DatagramListenerContext::OnMessage(
|
||||
DatagramSocket^ socket,
|
||||
MessageReceivedEventArgs^ eventArgs)
|
||||
{
|
||||
if (_outputStream != nullptr)
|
||||
{
|
||||
auto dataReader = eventArgs->GetDataReader();
|
||||
Receive(dataReader, dataReader->UnconsumedBufferLength, GetDataWriter());
|
||||
return;
|
||||
}
|
||||
|
||||
// We do not have an output stream yet so create one.
|
||||
create_task(socket->GetOutputStreamAsync(eventArgs->RemoteAddress, eventArgs->RemotePort)).then(
|
||||
[this, socket, eventArgs](IOutputStream^ stream)
|
||||
{
|
||||
{
|
||||
std::lock_guard<mutex_t> lock(_mtx);
|
||||
|
||||
// It might happen that the OnMessage was invoked more than once before the GetOutputStreamAsync call
|
||||
// completed. In this case we will end up with multiple streams - just keep one of them.
|
||||
if (_outputStream == nullptr)
|
||||
{
|
||||
_outputStream = stream;
|
||||
}
|
||||
}
|
||||
|
||||
auto dataReader = eventArgs->GetDataReader();
|
||||
Receive(dataReader, dataReader->UnconsumedBufferLength, GetDataWriter());
|
||||
}).then([this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting all exceptions from the continuation chain above this point.
|
||||
prevTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("On message with an error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
// Do not print anything here - this will usually happen because user closed the client socket.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
DatagramListenerContext::Receive(
|
||||
DataReader^ dataReader,
|
||||
unsigned int strLen,
|
||||
DataWriter^ dataWriter)
|
||||
{
|
||||
if (!strLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = dataReader->ReadString(strLen);
|
||||
_notify->NotifyFromAsyncThread("Received data from client: \"" + msg + "\"",
|
||||
NotifyType::Status);
|
||||
auto echo = CreateEchoMessage(msg);
|
||||
EchoMessage(dataWriter, echo);
|
||||
}
|
||||
|
||||
String^
|
||||
DatagramListenerContext::CreateEchoMessage(
|
||||
String^ msg)
|
||||
{
|
||||
wchar_t buf[256];
|
||||
auto len = swprintf_s(buf, L"Server%s received data from client : \"%s\"",
|
||||
_args->ServerName->IsEmpty() ? L"" : (" " + _args->ServerName)->Data(), msg->Data());
|
||||
|
||||
len += swprintf_s(&buf[len], _countof(buf) - len, L" - got %d chars",
|
||||
msg->Length());
|
||||
return ref new String(buf);
|
||||
}
|
||||
|
||||
void
|
||||
DatagramListenerContext::EchoMessage(
|
||||
DataWriter^ dataWriter,
|
||||
String^ echo)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataWriter->WriteString(echo);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Echoing failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
|
||||
create_task(dataWriter->StoreAsync()).then(
|
||||
[this](task<unsigned int> writeTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting all exceptions from the continuation chain above this point.
|
||||
writeTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Echo message with an error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Windows::Storage::Streams::DataWriter^
|
||||
DatagramListenerContext::GetDataWriter()
|
||||
{
|
||||
if (_dataWriter == nullptr)
|
||||
{
|
||||
_dataWriter = ref new DataWriter(_outputStream);
|
||||
}
|
||||
|
||||
return _dataWriter;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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 <mutex>
|
||||
#include "IListenerContext.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "ListenerArgs.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class DatagramListenerContext sealed : public IListenerContext
|
||||
{
|
||||
public:
|
||||
using DatagramSocket = Windows::Networking::Sockets::DatagramSocket;
|
||||
|
||||
DatagramListenerContext(IAsyncThreadNotify^ notify, DatagramSocket^ listener, ListenerArgs^ args);
|
||||
virtual ~DatagramListenerContext();
|
||||
|
||||
virtual void Listen_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
virtual Windows::Foundation::IAsyncAction^ CancelIO();
|
||||
|
||||
private:
|
||||
using MessageReceivedEventArgs = Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs;
|
||||
using MessageHandler = Windows::Foundation::TypedEventHandler<DatagramSocket^, MessageReceivedEventArgs^>;
|
||||
using DataReader = Windows::Storage::Streams::DataReader;
|
||||
using DataWriter = Windows::Storage::Streams::DataWriter;
|
||||
using IOutputStream = Windows::Storage::Streams::IOutputStream;
|
||||
using Listener = DatagramSocket;
|
||||
using Args = ListenerArgs;
|
||||
using mutex_t = std::mutex;
|
||||
|
||||
void OnMessage(DatagramSocket^ socket, MessageReceivedEventArgs^ eventArgs);
|
||||
void Receive(DataReader^, unsigned int strLen, DataWriter^);
|
||||
String^ CreateEchoMessage(String^ msg);
|
||||
void EchoMessage(DataWriter^, String^ echo);
|
||||
|
||||
DataWriter^ GetDataWriter();
|
||||
|
||||
IAsyncThreadNotify^ _notify;
|
||||
Listener^ _listener;
|
||||
Args^ _args;
|
||||
DataWriter^ _dataWriter;
|
||||
|
||||
mutable mutex_t _mtx;
|
||||
// mutex protected data
|
||||
IOutputStream^ _outputStream;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* 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 "Factory.h"
|
||||
#include "StreamListenerContext.h"
|
||||
#include "DatagramListenerContext.h"
|
||||
#include "StreamClientContext.h"
|
||||
#include "DatagramClientContext.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Networking::Sockets;
|
||||
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;
|
||||
|
||||
IListenerContext^
|
||||
Factory::CreateListenerContext(
|
||||
IAsyncThreadNotify^ notify,
|
||||
ListenerArgs^ listenerArgs,
|
||||
Protocol protocol)
|
||||
{
|
||||
if (protocol == Protocol::TCP)
|
||||
{
|
||||
auto listener = ref new StreamSocketListener();
|
||||
return ref new StreamListenerContext(notify, listener, listenerArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto listener = ref new DatagramSocket();
|
||||
return ref new DatagramListenerContext(notify, listener, listenerArgs);
|
||||
}
|
||||
}
|
||||
|
||||
IClientContext^
|
||||
Factory::CreateClientContext(
|
||||
IAsyncThreadNotify^ notify,
|
||||
ClientArgs^ clientArgs,
|
||||
Protocol protocol)
|
||||
{
|
||||
if (protocol == Protocol::TCP)
|
||||
{
|
||||
auto client = ref new StreamSocket();
|
||||
return ref new StreamClientContext(notify, client, clientArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto client = ref new DatagramSocket();
|
||||
return ref new DatagramClientContext(notify, client, clientArgs);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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 "IAsyncThreadNotify.h"
|
||||
#include "ListenerArgs.h"
|
||||
#include "IListenerContext.h"
|
||||
#include "ClientArgs.h"
|
||||
#include "IClientContext.h"
|
||||
#include "Protocol.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
static IListenerContext^ CreateListenerContext(IAsyncThreadNotify^, ListenerArgs^, Protocol);
|
||||
|
||||
static IClientContext^ CreateClientContext(IAsyncThreadNotify^, ClientArgs^, Protocol);
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public enum class NotifyType
|
||||
{
|
||||
Status,
|
||||
Error,
|
||||
};
|
||||
|
||||
public interface struct IAsyncThreadNotify
|
||||
{
|
||||
void NotifyFromAsyncThread(Platform::String^ message, NotifyType type);
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public interface struct IClientContext
|
||||
{
|
||||
void Connect_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void Send_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e, Platform::String^ input);
|
||||
|
||||
Windows::Foundation::IAsyncAction^ CancelIO();
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public interface struct IListenerContext
|
||||
{
|
||||
void Listen_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
Windows::Foundation::IAsyncAction^ CancelIO();
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public interface struct IMainPageUIElements
|
||||
{
|
||||
property Windows::UI::Xaml::UIElement^ ThreadGrid
|
||||
{
|
||||
Windows::UI::Xaml::UIElement^ get();
|
||||
}
|
||||
|
||||
property Windows::UI::Xaml::UIElement^ TalkGrid
|
||||
{
|
||||
Windows::UI::Xaml::UIElement^ get();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public ref class ListenerArgs sealed
|
||||
{
|
||||
public:
|
||||
property Platform::String^ ServerName;
|
||||
property Windows::Networking::HostName^ ServerHostName;
|
||||
property Platform::String^ ServerPort;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,307 +0,0 @@
|
||||
<!--
|
||||
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="ot.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ot"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
IsTabStop="false"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource="ms-appx:///Assets/Wide310x150Logo.png" Opacity="0.25" Stretch="Uniform"/>
|
||||
</Grid.Background>
|
||||
<!-- Interface List -->
|
||||
<Grid
|
||||
x:Name="ThrdGrid"
|
||||
>
|
||||
<TextBlock
|
||||
Text="Thread UX"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Margin="20"
|
||||
FontSize="50"
|
||||
/>
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Top"
|
||||
>
|
||||
<TextBlock
|
||||
Text="Interfaces"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Margin="60,90"
|
||||
FontSize="25"
|
||||
/>
|
||||
<Button
|
||||
x:Name="Talk"
|
||||
Content="Talk"
|
||||
Margin="10,0"
|
||||
/>
|
||||
</StackPanel>
|
||||
<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="00112233445566778899aabbccddeeff"
|
||||
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="0"
|
||||
Maximum="32"
|
||||
Value="16"
|
||||
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="11"
|
||||
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>
|
||||
<local:TalkGrid
|
||||
x:Name="TlkGrid"
|
||||
Margin="20"
|
||||
Visibility="Collapsed"
|
||||
/>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,419 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "TalkGrid.xaml.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
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;
|
||||
|
||||
#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]
|
||||
|
||||
void otLog(PCSTR aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, aFormat);
|
||||
|
||||
CHAR logString[512] = { 0 };
|
||||
int charsWritten = vsprintf_s(logString, sizeof(logString), aFormat, args);
|
||||
if (charsWritten > 0) OutputDebugStringA(logString);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
MainPage::MainPage() : _otApi(nullptr)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
InterfaceConfigCancelButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
this->InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->_curAdapter = nullptr;
|
||||
}
|
||||
);
|
||||
InterfaceConfigOkButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
this->InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->ConnectNetwork(_curAdapter);
|
||||
this->_curAdapter = nullptr;
|
||||
}
|
||||
);
|
||||
InterfaceDetailsCloseButton->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
this->InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
}
|
||||
);
|
||||
Talk->Click +=
|
||||
ref new RoutedEventHandler(
|
||||
[=](Platform::Object^, RoutedEventArgs^) {
|
||||
this->ThreadGrid->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
this->TalkGrid->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
);
|
||||
|
||||
TlkGrid->Init(this);
|
||||
}
|
||||
|
||||
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
|
||||
{
|
||||
Loaded += ref new RoutedEventHandler(this, &MainPage::OnLoaded);
|
||||
Unloaded += ref new RoutedEventHandler(this, &MainPage::OnUnloaded);
|
||||
}
|
||||
|
||||
void MainPage::OnLoaded(Object^ sender, RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Initialize api handle
|
||||
_otApi = ref new otApi();
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (_otApi)
|
||||
{
|
||||
// Unregister
|
||||
_otApi->AdapterArrival -= _adapterArrivalToken;
|
||||
|
||||
// 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::ShowInterfaceDetails(otAdapter^ adapter)
|
||||
{
|
||||
try
|
||||
{
|
||||
InterfaceMacAddress->Text = otApi::MacToString(adapter->ExtendedAddress);
|
||||
InterfaceML_EID->Text = adapter->MeshLocalEid->ToString();
|
||||
InterfaceRLOC->Text = otApi::Rloc16ToString(adapter->Rloc16);
|
||||
|
||||
if (adapter->State > otThreadState::Child)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
otChildInfo childInfo;
|
||||
while (OT_ERROR_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;
|
||||
}
|
||||
|
||||
// Show the details
|
||||
InterfaceDetails->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::AddAdapterToList(otAdapter^ adapter)
|
||||
{
|
||||
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^) {
|
||||
this->_curAdapter = adapter;
|
||||
this->InterfaceConfiguration->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
}
|
||||
);
|
||||
InterfaceStackPanel->Children->Append(ConnectButton);
|
||||
|
||||
// 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^) {
|
||||
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^) {
|
||||
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::ThreadStateToString(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);
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
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^)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::DisconnectNetwork(otAdapter^ adapter)
|
||||
{
|
||||
try
|
||||
{
|
||||
GUID interfaceGuid = adapter->InterfaceGuid;
|
||||
WCHAR szName[256] = { 0 };
|
||||
swprintf_s(szName, 256, GUID_FORMAT, GUID_ARG(interfaceGuid));
|
||||
otLog("%S disconnecting...\n", szName);
|
||||
|
||||
// Stop the Thread network and bring down the interface
|
||||
adapter->ThreadEnabled = false;
|
||||
adapter->IpEnabled = false;
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::UIElement^
|
||||
MainPage::ThreadGrid::get()
|
||||
{
|
||||
return ThrdGrid;
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::UIElement^
|
||||
MainPage::TalkGrid::get()
|
||||
{
|
||||
return TlkGrid;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "IMainPageUIElements.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public ref class MainPage sealed : public IMainPageUIElements
|
||||
{
|
||||
public:
|
||||
MainPage();
|
||||
|
||||
void OnResuming();
|
||||
|
||||
void ConnectNetwork(otAdapter^ adapter);
|
||||
void ShowInterfaceDetails(otAdapter^ adapter);
|
||||
void DisconnectNetwork(otAdapter^ adapter);
|
||||
|
||||
property Windows::UI::Xaml::UIElement^ ThreadGrid
|
||||
{
|
||||
virtual Windows::UI::Xaml::UIElement^ get();
|
||||
}
|
||||
|
||||
property Windows::UI::Xaml::UIElement^ TalkGrid
|
||||
{
|
||||
virtual Windows::UI::Xaml::UIElement^ get();
|
||||
}
|
||||
|
||||
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 AddAdapterToList(otAdapter^ adapter);
|
||||
|
||||
otApi^ _otApi;
|
||||
|
||||
Windows::Foundation::EventRegistrationToken _adapterArrivalToken;
|
||||
|
||||
otAdapter^ _curAdapter;
|
||||
|
||||
};
|
||||
}
|
||||
Binary file not shown.
@@ -1,30 +0,0 @@
|
||||
<?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.12.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="ot.App">
|
||||
<uap:VisualElements DisplayName="OpenThread" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="OpenThread" BackgroundColor="white">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="white" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<Capability Name="privateNetworkClientServer" />
|
||||
<Capability Name="internetClientServer" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
public enum class Protocol
|
||||
{
|
||||
TCP,
|
||||
UDP,
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,26 +0,0 @@
|
||||
# OpenThread App for Windows #
|
||||
|
||||
This sample app provides an example of how to interface with the OpenThread API and talk to each other 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.
|
||||
|
||||

|
||||
|
||||
The "Talk" button of main page switches the user interface to the talk fuctionality. This app acts
|
||||
either as a server or a client role and talks to each other over a TCP or a UDP protocol.
|
||||
|
||||
The server listens to the clients.
|
||||
|
||||

|
||||
|
||||
The client sends a message to the server and the server echos that message back to the client.
|
||||
|
||||

|
||||
@@ -1,106 +0,0 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<UserControl
|
||||
x:Class="ot.ServerControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ot"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Text="Server Name :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
x:Name="ServerName"
|
||||
Width="300"
|
||||
HorizontalAlignment="Left"
|
||||
/>
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Text="Server IP :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
x:Name="ServerIP"
|
||||
MinWidth="500"
|
||||
/>
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Text="Server Port :"
|
||||
/>
|
||||
<TextBox
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
x:Name="ServerPort"
|
||||
Width="100"
|
||||
HorizontalAlignment="Left"
|
||||
/>
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Top"
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
>
|
||||
<Button
|
||||
Width="75"
|
||||
Content="Listen"
|
||||
Click="Listen_Click"
|
||||
Margin="0,0,75,0"
|
||||
/>
|
||||
<Button
|
||||
Width="75"
|
||||
Content="Exit"
|
||||
Click="Exit_Click"
|
||||
/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include <algorithm>
|
||||
#include "ServerControl.xaml.h"
|
||||
#include "Factory.h"
|
||||
#include "TalkHelper.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI;
|
||||
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;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
ServerControl::ServerControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ServerPort->Text = DEF_PORT.ToString();
|
||||
}
|
||||
|
||||
void
|
||||
ServerControl::Init(
|
||||
IAsyncThreadNotify^ notify,
|
||||
IMainPageUIElements^ mainPageUIElements)
|
||||
{
|
||||
_notify = std::move(notify);
|
||||
_mainPageUIElements = std::move(mainPageUIElements);
|
||||
}
|
||||
|
||||
void
|
||||
ServerControl::ProtocolChanged(
|
||||
Protocol protocol)
|
||||
{
|
||||
_protocol = protocol;
|
||||
}
|
||||
|
||||
void
|
||||
ServerControl::Listen_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto listenerArgs = ref new ListenerArgs();
|
||||
|
||||
listenerArgs->ServerName = ServerName->Text;
|
||||
|
||||
auto serverIP = ServerIP->Text;
|
||||
if (serverIP->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Server IP");
|
||||
}
|
||||
|
||||
// check valid chars of Ipv6 Address
|
||||
if (!TalkHelper::AllValidIpv6Chars(serverIP->Data(), serverIP->Data() + serverIP->Length()))
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "Not a valid Server IPv6 address");
|
||||
}
|
||||
|
||||
listenerArgs->ServerHostName = ref new HostName(serverIP);
|
||||
|
||||
if (ServerPort->Text->IsEmpty())
|
||||
{
|
||||
throw Exception::CreateException(E_INVALIDARG, "No Server Port");
|
||||
}
|
||||
listenerArgs->ServerPort = ServerPort->Text;
|
||||
|
||||
auto listenerContext = Factory::CreateListenerContext(_notify, listenerArgs, _protocol);
|
||||
listenerContext->Listen_Click(sender, e);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Listening failed with input error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerControl::Exit_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
_mainPageUIElements->TalkGrid->Visibility = Xaml::Visibility::Collapsed;
|
||||
_mainPageUIElements->ThreadGrid->Visibility = Xaml::Visibility::Visible;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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 "ServerControl.g.h"
|
||||
#include "TalkConsts.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "IMainPageUIElements.h"
|
||||
#include "Protocol.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class ServerControl sealed
|
||||
{
|
||||
public:
|
||||
ServerControl();
|
||||
|
||||
void Init(IAsyncThreadNotify^ notify, IMainPageUIElements^ mainPageUIElements);
|
||||
|
||||
void ProtocolChanged(Protocol protocol);
|
||||
|
||||
private:
|
||||
static constexpr unsigned short DEF_PORT = TalkConsts::DEF_SERVER_PORT;
|
||||
|
||||
void Listen_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void Exit_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
IAsyncThreadNotify^ _notify;
|
||||
IMainPageUIElements^ _mainPageUIElements;
|
||||
Protocol _protocol;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include "StreamClientContext.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Networking::Sockets;
|
||||
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;
|
||||
|
||||
StreamClientContext::StreamClientContext(
|
||||
IAsyncThreadNotify^ notify,
|
||||
StreamSocket^ client,
|
||||
ClientArgs^ args) :
|
||||
_notify{ std::move(notify) },
|
||||
_client{ std::move(client) },
|
||||
_args{ std::move(args) }
|
||||
{
|
||||
}
|
||||
|
||||
StreamClientContext::~StreamClientContext()
|
||||
{
|
||||
// A Client can be closed in two ways:
|
||||
// - explicitly: using the 'delete' keyword (client is closed even if there are outstanding references to it).
|
||||
// - implicitly: removing the last reference to it (i.e., falling out-of-scope).
|
||||
//
|
||||
// When a Socket is closed implicitly, it can take several seconds for the local port being used
|
||||
// by it to be freed/reclaimed by the lower networking layers. During that time, other sockets on the machine
|
||||
// will not be able to use the port. Thus, it is strongly recommended that Socket instances be explicitly
|
||||
// closed before they go out of scope(e.g., before application exit). The call below explicitly closes the socket.
|
||||
if (_client != nullptr)
|
||||
{
|
||||
delete _client;
|
||||
_client = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamClientContext::Connect_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
task<void> removeContext;
|
||||
|
||||
if (CoreApplication::Properties->HasKey("clientContext"))
|
||||
{
|
||||
auto clientContext = dynamic_cast<IClientContext^>(
|
||||
CoreApplication::Properties->Lookup("clientContext"));
|
||||
if (clientContext == nullptr)
|
||||
{
|
||||
throw ref new FailureException(L"No clientContext");
|
||||
}
|
||||
|
||||
removeContext = create_task(clientContext->CancelIO()).then(
|
||||
[]()
|
||||
{
|
||||
CoreApplication::Properties->Remove("clientContext");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
removeContext = create_task([]() {});
|
||||
}
|
||||
|
||||
removeContext.then([this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
|
||||
// Events cannot be hooked up directly to the ScenarioInput2 object, as the object can fall out-of-scope and be
|
||||
// deleted. This would render any event hooked up to the object ineffective. The ClientContext guarantees that
|
||||
// both the socket and object that serves its events have the same lifetime.
|
||||
CoreApplication::Properties->Insert("clientContext", this);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Remove clientContext error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
}
|
||||
}).then([this]()
|
||||
{
|
||||
auto endpointPair = ref new EndpointPair(_args->ClientHostName, _args->ClientPort,
|
||||
_args->ServerHostName, _args->ServerPort);
|
||||
|
||||
_notify->NotifyFromAsyncThread("Start connecting", NotifyType::Status);
|
||||
|
||||
create_task(_client->ConnectAsync(endpointPair)).then(
|
||||
[this, endpointPair](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Connect from " + endpointPair->LocalHostName->CanonicalName +
|
||||
" to " + endpointPair->RemoteHostName->CanonicalName,
|
||||
NotifyType::Status);
|
||||
OnConnection(_client);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Start binding failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
CoreApplication::Properties->Remove("clientContext");
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
CoreApplication::Properties->Remove("clientContext");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ot::StreamClientContext::Send_Click(
|
||||
Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e,
|
||||
Platform::String^ input)
|
||||
{
|
||||
SendMessage(GetDataWriter(), input);
|
||||
}
|
||||
|
||||
IAsyncAction^
|
||||
ot::StreamClientContext::CancelIO()
|
||||
{
|
||||
return _client->CancelIOAsync();
|
||||
}
|
||||
|
||||
void
|
||||
StreamClientContext::OnConnection(
|
||||
StreamSocket^ streamSocket)
|
||||
{
|
||||
SetConnected(true);
|
||||
ReceiveLoop(streamSocket, GetDataReader());
|
||||
}
|
||||
|
||||
void
|
||||
StreamClientContext::SetConnected(
|
||||
bool connected)
|
||||
{
|
||||
_connected = connected;
|
||||
}
|
||||
|
||||
bool
|
||||
StreamClientContext::IsConnected() const
|
||||
{
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void
|
||||
StreamClientContext::ReceiveLoop(
|
||||
StreamSocket^ streamSocket,
|
||||
DataReader^ dataReader)
|
||||
{
|
||||
// Read first 4 bytes (length of the subsequent string).
|
||||
create_task(dataReader->LoadAsync(sizeof(UINT32))).then(
|
||||
[this, dataReader](unsigned int size)
|
||||
{
|
||||
if (size < sizeof(UINT32))
|
||||
{
|
||||
// The underlying socket was closed before we were able to read the whole data.
|
||||
cancel_current_task();
|
||||
}
|
||||
|
||||
auto strLen = dataReader->ReadUInt32();
|
||||
return create_task(dataReader->LoadAsync(strLen)).then(
|
||||
[this, dataReader, strLen](unsigned int actualStrLen)
|
||||
{
|
||||
if (actualStrLen != strLen)
|
||||
{
|
||||
// The underlying socket was closed before we were able to read the whole data.
|
||||
cancel_current_task();
|
||||
}
|
||||
|
||||
Receive(dataReader, strLen);
|
||||
});
|
||||
}).then([this, streamSocket, dataReader](task<void> previousTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting all exceptions from the continuation chain above this point.
|
||||
previousTask.get();
|
||||
|
||||
// Everything went ok, so try to receive another string. The receive will continue until the stream is
|
||||
// broken (i.e. peer closed the socket).
|
||||
ReceiveLoop(streamSocket, dataReader);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Read stream failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
|
||||
// Explicitly close the socket.
|
||||
delete streamSocket;
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
// Do not print anything here - this will usually happen because user closed the client socket.
|
||||
|
||||
// Explicitly close the socket.
|
||||
delete streamSocket;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
StreamClientContext::Receive(
|
||||
DataReader^ dataReader,
|
||||
unsigned int strLen)
|
||||
{
|
||||
if (!strLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = dataReader->ReadString(strLen);
|
||||
_notify->NotifyFromAsyncThread("Received data from server: \"" + msg + "\"",
|
||||
NotifyType::Status);
|
||||
}
|
||||
|
||||
void
|
||||
StreamClientContext::SendMessage(
|
||||
DataWriter^ dataWriter,
|
||||
String^ msg)
|
||||
{
|
||||
if (!IsConnected())
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("This socket is not yet connected.", NotifyType::Error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dataWriter->WriteUInt32(msg->Length());
|
||||
dataWriter->WriteString(msg);
|
||||
_notify->NotifyFromAsyncThread("Sending - " + msg, NotifyType::Status);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Sending failed with error: " + ex->Message, NotifyType::Error);
|
||||
}
|
||||
|
||||
// Write the locally buffered data to the network. Please note that write operation will succeed
|
||||
// even if the server is not listening.
|
||||
create_task(dataWriter->StoreAsync()).then(
|
||||
[this](task<unsigned int> writeTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
writeTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Send failed with error: " + ex->Message, NotifyType::Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Windows::Storage::Streams::DataReader^
|
||||
StreamClientContext::GetDataReader()
|
||||
{
|
||||
if (_dataReader == nullptr)
|
||||
{
|
||||
_dataReader = ref new DataReader(_client->InputStream);
|
||||
}
|
||||
|
||||
return _dataReader;
|
||||
}
|
||||
|
||||
Windows::Storage::Streams::DataWriter^
|
||||
StreamClientContext::GetDataWriter()
|
||||
{
|
||||
if (_dataWriter == nullptr)
|
||||
{
|
||||
_dataWriter = ref new DataWriter(_client->OutputStream);
|
||||
}
|
||||
|
||||
return _dataWriter;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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 "IClientContext.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "ClientArgs.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class StreamClientContext sealed : public IClientContext
|
||||
{
|
||||
public:
|
||||
using StreamSocket = Windows::Networking::Sockets::StreamSocket;
|
||||
|
||||
StreamClientContext(IAsyncThreadNotify^ notify, StreamSocket^ client, ClientArgs^ args);
|
||||
virtual ~StreamClientContext();
|
||||
|
||||
virtual void Connect_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
virtual void Send_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e, Platform::String^ input);
|
||||
|
||||
virtual Windows::Foundation::IAsyncAction^ CancelIO();
|
||||
|
||||
private:
|
||||
using DataReader = Windows::Storage::Streams::DataReader;
|
||||
using DataWriter = Windows::Storage::Streams::DataWriter;
|
||||
using Args = ClientArgs;
|
||||
|
||||
void OnConnection(StreamSocket^);
|
||||
|
||||
void SetConnected(bool connected);
|
||||
bool IsConnected() const;
|
||||
|
||||
void ReceiveLoop(StreamSocket^, DataReader^);
|
||||
void Receive(DataReader^, unsigned int strLen);
|
||||
|
||||
void SendMessage(DataWriter^, String^ msg);
|
||||
|
||||
DataReader^ GetDataReader();
|
||||
DataWriter^ GetDataWriter();
|
||||
|
||||
IAsyncThreadNotify^ _notify;
|
||||
StreamSocket^ _client;
|
||||
Args^ _args;
|
||||
bool _connected = false;
|
||||
DataReader^ _dataReader;
|
||||
DataWriter^ _dataWriter;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,288 +0,0 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include "StreamListenerContext.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Networking::Sockets;
|
||||
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;
|
||||
|
||||
StreamListenerContext::StreamListenerContext(
|
||||
IAsyncThreadNotify^ notify,
|
||||
StreamSocketListener^ listener,
|
||||
ListenerArgs^ args) :
|
||||
_notify{ std::move(notify) },
|
||||
_listener{ std::move(listener) },
|
||||
_args{ std::move(args) }
|
||||
{
|
||||
}
|
||||
|
||||
StreamListenerContext::~StreamListenerContext()
|
||||
{
|
||||
// A Listener can be closed in two ways:
|
||||
// - explicitly: using the 'delete' keyword (listener is closed even if there are outstanding references to it).
|
||||
// - implicitly: removing the last reference to it (i.e., falling out-of-scope).
|
||||
//
|
||||
// When a Socket is closed implicitly, it can take several seconds for the local port being used
|
||||
// by it to be freed/reclaimed by the lower networking layers. During that time, other sockets on the machine
|
||||
// will not be able to use the port. Thus, it is strongly recommended that Socket instances be explicitly
|
||||
// closed before they go out of scope(e.g., before application exit). The call below explicitly closes the socket.
|
||||
if (_listener != nullptr)
|
||||
{
|
||||
delete _listener;
|
||||
_listener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamListenerContext::Listen_Click(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
task<void> removeContext;
|
||||
|
||||
if (CoreApplication::Properties->HasKey("listenerContext"))
|
||||
{
|
||||
auto listenerContext = dynamic_cast<IListenerContext^>(
|
||||
CoreApplication::Properties->Lookup("listenerContext"));
|
||||
if (listenerContext == nullptr)
|
||||
{
|
||||
throw ref new FailureException(L"No listenerContext");
|
||||
}
|
||||
|
||||
removeContext = create_task(listenerContext->CancelIO()).then(
|
||||
[]()
|
||||
{
|
||||
CoreApplication::Properties->Remove("listenerContext");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
removeContext = create_task([]() {});
|
||||
}
|
||||
|
||||
_listener->ConnectionReceived += ref new ConnectionHandler(
|
||||
this, &StreamListenerContext::OnConnection);
|
||||
|
||||
removeContext.then([this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
|
||||
// Events cannot be hooked up directly to the ScenarioInput1 object, as the object can fall out-of-scope and be
|
||||
// deleted. This would render any event hooked up to the object ineffective. The ListenerContext guarantees that
|
||||
// both the listener and object that serves its events have the same lifetime.
|
||||
CoreApplication::Properties->Insert("listenerContext", this);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Remove listenerContext error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
}
|
||||
}).then([this]()
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Start listening", NotifyType::Status);
|
||||
|
||||
create_task(_listener->BindEndpointAsync(_args->ServerHostName, _args->ServerPort)).then(
|
||||
[this](task<void> prevTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting an exception.
|
||||
prevTask.get();
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Listening on address " + _args->ServerHostName->CanonicalName,
|
||||
NotifyType::Status);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread(
|
||||
"Start listening failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
CoreApplication::Properties->Remove("listenerContext");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
IAsyncAction^
|
||||
StreamListenerContext::CancelIO()
|
||||
{
|
||||
return _listener->CancelIOAsync();
|
||||
}
|
||||
|
||||
void
|
||||
StreamListenerContext::OnConnection(
|
||||
StreamSocketListener^ listener,
|
||||
ConnectionReceivedEventArgs^ args)
|
||||
{
|
||||
auto dataReader = ref new DataReader(args->Socket->InputStream);
|
||||
auto dataWriter = ref new DataWriter(args->Socket->OutputStream);
|
||||
|
||||
ReceiveLoop(args->Socket, dataReader, dataWriter);
|
||||
}
|
||||
|
||||
void
|
||||
StreamListenerContext::ReceiveLoop(
|
||||
StreamSocket^ streamSocket,
|
||||
DataReader^ dataReader,
|
||||
DataWriter^ dataWriter)
|
||||
{
|
||||
// Read first 4 bytes (length of the subsequent string).
|
||||
create_task(dataReader->LoadAsync(sizeof(UINT32))).then(
|
||||
[this, streamSocket, dataReader, dataWriter](unsigned int size)
|
||||
{
|
||||
if (size < sizeof(UINT32))
|
||||
{
|
||||
// The underlying socket was closed before we were able to read the whole data.
|
||||
cancel_current_task();
|
||||
}
|
||||
|
||||
unsigned int strLen = dataReader->ReadUInt32();
|
||||
return create_task(dataReader->LoadAsync(strLen)).then(
|
||||
[this, dataReader, dataWriter, strLen](unsigned int actualStrLen)
|
||||
{
|
||||
if (actualStrLen != strLen)
|
||||
{
|
||||
// The underlying socket was closed before we were able to read the whole data.
|
||||
cancel_current_task();
|
||||
}
|
||||
|
||||
Receive(dataReader, strLen, dataWriter);
|
||||
});
|
||||
}).then([this, streamSocket, dataReader, dataWriter](task<void> previousTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting all exceptions from the continuation chain above this point.
|
||||
previousTask.get();
|
||||
|
||||
// Everything went ok, so try to receive another string. The receive will continue until the stream is
|
||||
// broken (i.e. peer closed the socket).
|
||||
ReceiveLoop(streamSocket, dataReader, dataWriter);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Read stream failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
|
||||
// Explicitly close the socket.
|
||||
delete streamSocket;
|
||||
}
|
||||
catch (task_canceled&)
|
||||
{
|
||||
// Do not print anything here - this will usually happen because user closed the client socket.
|
||||
|
||||
// Explicitly close the socket.
|
||||
delete streamSocket;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
StreamListenerContext::Receive(
|
||||
DataReader^ dataReader,
|
||||
unsigned int strLen,
|
||||
DataWriter^ dataWriter)
|
||||
{
|
||||
if (!strLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = dataReader->ReadString(strLen);
|
||||
_notify->NotifyFromAsyncThread("Received data from client: \"" + msg + "\"",
|
||||
NotifyType::Status);
|
||||
auto echo = CreateEchoMessage(msg);
|
||||
EchoMessage(dataWriter, echo);
|
||||
}
|
||||
|
||||
String^
|
||||
StreamListenerContext::CreateEchoMessage(
|
||||
String^ msg)
|
||||
{
|
||||
wchar_t buf[256];
|
||||
auto len = swprintf_s(buf, L"Server%s received data from client : \"%s\"",
|
||||
_args->ServerName->IsEmpty() ? L"" : (" " + _args->ServerName)->Data(), msg->Data());
|
||||
|
||||
len += swprintf_s(&buf[len], _countof(buf) - len, L" - got %d chars",
|
||||
msg->Length());
|
||||
return ref new String(buf);
|
||||
}
|
||||
|
||||
void
|
||||
StreamListenerContext::EchoMessage(
|
||||
DataWriter^ dataWriter,
|
||||
String^ echo)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataWriter->WriteUInt32(echo->Length());
|
||||
dataWriter->WriteString(echo);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Echoing failed with error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
|
||||
create_task(dataWriter->StoreAsync()).then(
|
||||
[this](task<unsigned int> writeTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try getting all exceptions from the continuation chain above this point.
|
||||
writeTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
_notify->NotifyFromAsyncThread("Echo message with an error: " + ex->Message,
|
||||
NotifyType::Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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 "IListenerContext.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "ListenerArgs.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class StreamListenerContext sealed : public IListenerContext
|
||||
{
|
||||
public:
|
||||
using StreamSocketListener = Windows::Networking::Sockets::StreamSocketListener;
|
||||
|
||||
StreamListenerContext(IAsyncThreadNotify^ notify, StreamSocketListener^ listener, ListenerArgs^ args);
|
||||
virtual ~StreamListenerContext();
|
||||
|
||||
virtual void Listen_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
virtual Windows::Foundation::IAsyncAction^ CancelIO();
|
||||
|
||||
private:
|
||||
using ConnectionReceivedEventArgs = Windows::Networking::Sockets::StreamSocketListenerConnectionReceivedEventArgs;
|
||||
using ConnectionHandler = Windows::Foundation::TypedEventHandler<StreamSocketListener^, ConnectionReceivedEventArgs^>;
|
||||
using DataReader = Windows::Storage::Streams::DataReader;
|
||||
using DataWriter = Windows::Storage::Streams::DataWriter;
|
||||
using Listener = StreamSocketListener;
|
||||
using StreamSocket = Windows::Networking::Sockets::StreamSocket;
|
||||
using Args = ListenerArgs;
|
||||
|
||||
void OnConnection(StreamSocketListener^ listener, ConnectionReceivedEventArgs^ args);
|
||||
void ReceiveLoop(StreamSocket^, DataReader^, DataWriter^);
|
||||
void Receive(DataReader^, unsigned int strLen, DataWriter^);
|
||||
String^ CreateEchoMessage(String^ msg);
|
||||
void EchoMessage(DataWriter^, String^ echo);
|
||||
|
||||
IAsyncThreadNotify^ _notify;
|
||||
Listener^ _listener;
|
||||
Args^ _args;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
struct TalkConsts
|
||||
{
|
||||
static constexpr unsigned short DEF_SERVER_PORT = 51000;
|
||||
static constexpr unsigned short DEF_CLIENT_PORT_INIT = 51100;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,108 +0,0 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<Grid
|
||||
x:Class="ot.TalkGrid"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ot"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Top"
|
||||
>
|
||||
<RadioButton
|
||||
x:Name="TcpRadio"
|
||||
Content="TCP"
|
||||
GroupName="ProtocolGroup"
|
||||
Checked="Protocol_Changed"
|
||||
Margin="0,0,20,0"
|
||||
/>
|
||||
<RadioButton
|
||||
x:Name="UdpRadio"
|
||||
Content="UDP"
|
||||
GroupName="ProtocolGroup"
|
||||
Checked="Protocol_Changed"
|
||||
Margin="0,0,20,0"
|
||||
/>
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Top"
|
||||
>
|
||||
<RadioButton
|
||||
x:Name="ServerRadio"
|
||||
Content="Server"
|
||||
GroupName="RoleGroup"
|
||||
Checked="Role_Changed"
|
||||
Margin="0,0,20,0"
|
||||
/>
|
||||
<RadioButton
|
||||
x:Name="ClientRadio"
|
||||
Content="Client"
|
||||
GroupName="RoleGroup"
|
||||
Checked="Role_Changed"
|
||||
Margin="0,0,20,0"
|
||||
/>
|
||||
</StackPanel>
|
||||
<local:ServerControl
|
||||
x:Name="ServerRole"
|
||||
Grid.Row="4"
|
||||
Visibility="Collapsed"
|
||||
/>
|
||||
<local:ClientControl
|
||||
x:Name="ClientRole"
|
||||
Grid.Row="4"
|
||||
Visibility="Collapsed"
|
||||
/>
|
||||
<Border
|
||||
x:Name="StatusBorder"
|
||||
Grid.Row="6"
|
||||
>
|
||||
<TextBlock
|
||||
x:Name="StatusBlock"
|
||||
FontWeight="Bold"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
TextWrapping="Wrap"
|
||||
MaxHeight="80"
|
||||
/>
|
||||
</Border>
|
||||
</Grid>
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* 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 "TalkGrid.xaml.h"
|
||||
#include "ClientControl.xaml.h"
|
||||
#include "ServerControl.xaml.h"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Core;
|
||||
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;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
TalkGrid::TalkGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
TcpRadio->IsChecked = true;
|
||||
ServerRadio->IsChecked = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TalkGrid::Init(
|
||||
IMainPageUIElements^ mainPageUIElements)
|
||||
{
|
||||
ServerRole->Init(this, mainPageUIElements);
|
||||
ClientRole->Init(this, mainPageUIElements);
|
||||
}
|
||||
|
||||
void
|
||||
TalkGrid::NotifyFromAsyncThread(
|
||||
String^ message,
|
||||
NotifyType type)
|
||||
{
|
||||
Dispatcher->RunAsync(CoreDispatcherPriority::Normal,
|
||||
ref new DispatchedHandler([this, message, type]()
|
||||
{
|
||||
Notify(message, type);
|
||||
}));
|
||||
}
|
||||
|
||||
void
|
||||
TalkGrid::Notify(
|
||||
String^ message,
|
||||
NotifyType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NotifyType::Status:
|
||||
StatusBorder->Background = ref new SolidColorBrush(Colors::Green);
|
||||
break;
|
||||
case NotifyType::Error:
|
||||
StatusBorder->Background = ref new SolidColorBrush(Colors::Red);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
StatusBlock->Text = message;
|
||||
|
||||
// Collapse the StatusBlock if it has no text to conserve real estate.
|
||||
if (StatusBlock->Text != "")
|
||||
{
|
||||
StatusBorder->Visibility = Xaml::Visibility::Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBorder->Visibility = Xaml::Visibility::Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TalkGrid::Protocol_Changed(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
auto radioBtn = dynamic_cast<RadioButton^>(sender);
|
||||
if (!radioBtn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto protocol = (radioBtn == TcpRadio) ? Protocol::TCP : Protocol::UDP;
|
||||
|
||||
ServerRole->ProtocolChanged(protocol);
|
||||
ClientRole->ProtocolChanged(protocol);
|
||||
}
|
||||
|
||||
void
|
||||
TalkGrid::Role_Changed(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e)
|
||||
{
|
||||
auto radioBtn = dynamic_cast<RadioButton^>(sender);
|
||||
if (!radioBtn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (radioBtn == ServerRadio)
|
||||
{
|
||||
// switch to server role UI
|
||||
ClientRole->Visibility = Xaml::Visibility::Collapsed;
|
||||
ServerRole->Visibility = Xaml::Visibility::Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
// switch to client role UI
|
||||
ServerRole->Visibility = Xaml::Visibility::Collapsed;
|
||||
ClientRole->Visibility = Xaml::Visibility::Visible;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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 "TalkGrid.g.h"
|
||||
#include "IAsyncThreadNotify.h"
|
||||
#include "IMainPageUIElements.h"
|
||||
#include "Protocol.h"
|
||||
|
||||
namespace ot
|
||||
{
|
||||
|
||||
[Windows::Foundation::Metadata::WebHostHidden]
|
||||
public ref class TalkGrid sealed : public IAsyncThreadNotify
|
||||
{
|
||||
public:
|
||||
TalkGrid();
|
||||
|
||||
void Init(IMainPageUIElements^ mainPageUIElements);
|
||||
|
||||
// IAsyncThreadMessage
|
||||
virtual void NotifyFromAsyncThread(String^ message, NotifyType type);
|
||||
|
||||
void Notify(String^ message, NotifyType type);
|
||||
|
||||
private:
|
||||
// change protocol
|
||||
// TCP <-> UDP
|
||||
void Protocol_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
// change role from server client (or vice versa)
|
||||
void Role_Changed(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace ot
|
||||
{
|
||||
ref class ClientControl;
|
||||
ref class ServerControl;
|
||||
|
||||
class TalkHelper
|
||||
{
|
||||
private:
|
||||
friend ref class ClientControl;
|
||||
friend ref class ServerControl;
|
||||
|
||||
// this is a private method for specific usage, not a general purpose one
|
||||
// checks all chars are valid Ipv6 chars in the range [begin, end)
|
||||
static bool AllValidIpv6Chars(const wchar_t* begin, const wchar_t* end)
|
||||
{
|
||||
for (auto it = begin; it != end; ++it)
|
||||
{
|
||||
auto c = *it;
|
||||
|
||||
if ((c >= '0' && c <= '9') || (c == ':') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,610 +0,0 @@
|
||||
/*
|
||||
* 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/border_router.h>
|
||||
#include <openthread/thread_ftd.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 ot
|
||||
{
|
||||
|
||||
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 FTD. 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*/ TransmitPower
|
||||
{
|
||||
signed int get() {
|
||||
int8_t value;
|
||||
ThrowOnFailure(otPlatRadioGetTransmitPower(DeviceInstance, &value));
|
||||
return value;
|
||||
}
|
||||
void set(signed int value)
|
||||
{
|
||||
if (value > 127) throw Exception::CreateException(E_INVALIDARG);
|
||||
ThrowOnFailure(otPlatRadioSetTransmitPower(DeviceInstance, (int8_t)value);
|
||||
}
|
||||
}
|
||||
|
||||
property uint32_t PollPeriod
|
||||
{
|
||||
uint32_t get() { return otLinkGetPollPeriod(DeviceInstance); }
|
||||
void set(uint32_t value) { ThrowOnFailure(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;
|
||||
otJoinerGetId(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' };
|
||||
auto key = otThreadGetMasterKey(DeviceInstance);
|
||||
WCHAR szKey[OT_MASTER_KEY_SIZE * 2 + 1] = { 0 };
|
||||
for (uint8_t i = 0; i < OT_MASTER_KEY_SIZE; i++)
|
||||
{
|
||||
szKey[2 * i] = hexmap[(key->m8[i] & 0xF0) >> 4];
|
||||
szKey[2 * i + 1] = hexmap[key->m8[i] & 0x0F];
|
||||
}
|
||||
otFreeMemory(key);
|
||||
return ref new String(szKey);
|
||||
}
|
||||
void set(String^ value)
|
||||
{
|
||||
otMasterKey key;
|
||||
uint8_t keyLen = 0;
|
||||
for (uint32_t i = 0; i < value->Length() - 1; i+=2)
|
||||
{
|
||||
key.m8[keyLen++] = (uint8_t)((charToValue(value->Data()[i]) << 4) |
|
||||
charToValue(value->Data()[i + 1]));
|
||||
}
|
||||
if (keyLen * 2 == value->Length() - 1)
|
||||
{
|
||||
key.m8[keyLen++] = (uint8_t)(charToValue(value->Data()[value->Length()-1])) << 4;
|
||||
}
|
||||
memset(key.m8 + keyLen, 0, sizeof(key) - keyLen);
|
||||
ThrowOnFailure(otThreadSetMasterKey(DeviceInstance, &key));
|
||||
}
|
||||
}
|
||||
|
||||
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 len = WideCharToMultiByte(CP_UTF8, 0, value->Data(), -1, name, ARRAYSIZE(name), nullptr, nullptr);
|
||||
if (len <= 0) throw Exception::CreateException(E_INVALIDARG);
|
||||
ThrowOnFailure(otThreadSetNetworkName(DeviceInstance, name));
|
||||
}
|
||||
}
|
||||
|
||||
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_CHANGED_IP6_ADDRESS_ADDED)
|
||||
{
|
||||
pThis->IpAddressAdded(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_IP6_ADDRESS_REMOVED)
|
||||
{
|
||||
pThis->IpAddressRemoved(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_RLOC_ADDED)
|
||||
{
|
||||
pThis->IpRlocAdded(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_RLOC_REMOVED)
|
||||
{
|
||||
pThis->IpRlocRemoved(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_LL_ADDR)
|
||||
{
|
||||
pThis->IpLinkLocalAddresChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_ML_ADDR)
|
||||
{
|
||||
pThis->IpMeshLocalAddresChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_ROLE)
|
||||
{
|
||||
pThis->NetRoleChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_PARTITION_ID)
|
||||
{
|
||||
pThis->NetPartitionIdChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER)
|
||||
{
|
||||
pThis->NetKeySequenceCounterChanged(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_CHILD_ADDED)
|
||||
{
|
||||
pThis->ThreadChildAdded(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_CHILD_REMOVED)
|
||||
{
|
||||
pThis->ThreadChildRemoved(pThis);
|
||||
}
|
||||
|
||||
if (aFlags & OT_CHANGED_THREAD_NETDATA)
|
||||
{
|
||||
pThis->ThreadNetDataUpdated(pThis);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
TheadErrorToHResult(
|
||||
int /* otError */ error
|
||||
)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case OT_ERROR_NO_BUFS: return E_OUTOFMEMORY;
|
||||
case OT_ERROR_DROP:
|
||||
case OT_ERROR_NO_ROUTE: return HRESULT_FROM_WIN32(ERROR_NETWORK_UNREACHABLE);
|
||||
case OT_ERROR_INVALID_ARGS: return E_INVALIDARG;
|
||||
case OT_ERROR_SECURITY: return E_ACCESSDENIED;
|
||||
case OT_ERROR_NOT_CAPABLE:
|
||||
case OT_ERROR_NOT_IMPLEMENTED: return E_NOTIMPL;
|
||||
case OT_ERROR_INVALID_STATE: return E_NOT_VALID_STATE;
|
||||
case OT_ERROR_NOT_FOUND: return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||||
case OT_ERROR_ALREADY: return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
|
||||
case OT_ERROR_RESPONSE_TIMEOUT: return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
|
||||
default: return E_FAIL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* 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 ot
|
||||
{
|
||||
|
||||
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^ MacToString(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^ Rloc16ToString(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^ ThreadStateToString(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 ot
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#include "otApi.h"
|
||||
|
||||
#include "App.xaml.h"
|
||||
Reference in New Issue
Block a user