[windows] remove unsupported platform (#3878)

This commit is contained in:
Kamil Sroka
2019-06-06 11:55:18 -07:00
committed by Jonathan Hui
parent e482edb0f1
commit c14cc60962
305 changed files with 1125 additions and 45292 deletions
-35
View File
@@ -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>
-146
View File
@@ -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);
}
-50
View File
@@ -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);
};
}
-43
View File
@@ -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
-142
View File
@@ -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
-86
View File
@@ -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);
}
}
-49
View File
@@ -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
-43
View File
@@ -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
-41
View File
@@ -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
-42
View File
@@ -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
-307
View File
@@ -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>
-419
View File
@@ -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;
}
-77
View File
@@ -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>
-40
View File
@@ -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
-26
View File
@@ -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.
![Interface List](../../../doc/images/windows-app-interface-list.png)
The details list provides some more information, including extended MAC address, RLOC16 and information
about the current children.
![Interface List](../../../doc/images/windows-app-details.png)
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.
![Talk Functionality](../../../doc/images/windows-app-talk-server.png)
The client sends a message to the server and the server echos that message back to the client.
![Talk Functionality](../../../doc/images/windows-app-talk-client.png)
-106
View File
@@ -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
-40
View File
@@ -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
-108
View File
@@ -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>
-150
View File
@@ -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;
}
}
-61
View File
@@ -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
-63
View File
@@ -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;
}
};
}
-610
View File
@@ -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
-252
View File
@@ -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
-29
View File
@@ -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"
-44
View File
@@ -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"