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