Merge Windows Driver Code (#817)

This is the first of the Windows implementation code that will be merged. This is only the driver code.

Also note the updates to the appveyor configuration. It now builds, installs and queries the status of driver directly on the build machine. Then it builds an 'artifact' which is essentially the binaries packaged up.
This commit is contained in:
Nick Banks
2016-10-25 13:38:29 -07:00
committed by Jonathan Hui
parent b6adaaf758
commit f600840499
47 changed files with 13049 additions and 236 deletions
+48 -6
View File
@@ -1,3 +1,31 @@
#
# 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.
#
version: 0.1.{build}
image: Visual Studio 2015
configuration:
@@ -7,13 +35,27 @@ platform:
- x64
- x86
clone_depth: 10
install:
- cmd: Bcdedit.exe -set TESTSIGNING ON
# Configure logging
- cmd: reg import .appveyor\ThreadEtw.reg
- ps: Restart-Computer -Force
- ps: Start-Sleep -s 10
build:
project: etc/visual-studio/openthread.sln
verbosity: minimal
after_build:
- ps: $env:Platform2 = $env:Platform
- ps: If ($env:Platform2 -eq "x86") { $env:Platform2 = "Win32" }
# Set up the release directories
- cmd: .appveyor\make_release.cmd
# Install driver (only runs on x64)
- cmd: .appveyor\install_driver.cmd
test_script:
- cmd: >-
set Platform2=%Platform%
if %Platform2%==x86 set Platform2=Win32
vstest.console /logger:Appveyor /inIsolation /platform:%Platform% build\bin\%Platform2%\%Configuration%\dll\UnitTests.dll
# Run the unit tests
- cmd: vstest.console /logger:Appveyor /inIsolation /platform:%Platform% build\bin\%Platform2%\%Configuration%\dll\UnitTests.dll
# Run the tests for the driver (only runs on x64)
- cmd: .appveyor\test_driver.cmd
artifacts:
- path: release
name: release
Binary file not shown.
+43
View File
@@ -0,0 +1,43 @@
REM
REM Copyright (c) 2016, The OpenThread Authors.
REM All rights reserved.
REM
REM Redistribution and use in source and binary forms, with or without
REM modification, are permitted provided that the following conditions are met:
REM 1. Redistributions of source code must retain the above copyright
REM notice, this list of conditions and the following disclaimer.
REM 2. Redistributions in binary form must reproduce the above copyright
REM notice, this list of conditions and the following disclaimer in the
REM documentation and/or other materials provided with the distribution.
REM 3. Neither the name of the copyright holder nor the
REM names of its contributors may be used to endorse or promote products
REM derived from this software without specific prior written permission.
REM
REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
REM ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
REM LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
REM CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
REM SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
REM INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
REM CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
REM ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
REM POSSIBILITY OF SUCH DAMAGE.
REM
IF NOT "%Platform%"=="x64" GOTO :EOF
pushd %APPVEYOR_BUILD_FOLDER%\build\bin\%Platform2%\%Configuration%\sys
REM Install the certifications to the cert stores
certutil -addstore root otLwf.cer
certutil -addstore TrustedPublisher otLwf.cer
cd otLwf
REM Install the NDSI LWF driver, otLwf.sys
netcfg.exe -v -l otlwf.inf -c s -i otLwf
popd
+55
View File
@@ -0,0 +1,55 @@
REM
REM Copyright (c) 2016, The OpenThread Authors.
REM All rights reserved.
REM
REM Redistribution and use in source and binary forms, with or without
REM modification, are permitted provided that the following conditions are met:
REM 1. Redistributions of source code must retain the above copyright
REM notice, this list of conditions and the following disclaimer.
REM 2. Redistributions in binary form must reproduce the above copyright
REM notice, this list of conditions and the following disclaimer in the
REM documentation and/or other materials provided with the distribution.
REM 3. Neither the name of the copyright holder nor the
REM names of its contributors may be used to endorse or promote products
REM derived from this software without specific prior written permission.
REM
REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
REM ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
REM LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
REM CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
REM SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
REM INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
REM CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
REM ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
REM POSSIBILITY OF SUCH DAMAGE.
REM
pushd %APPVEYOR_BUILD_FOLDER%
REM Make the release directory
mkdir release
mkdir release\symbols
mkdir release\symbols\TraceFormat
mkdir release\logs
REM Copy the relavant binaries
copy build\bin\%Platform2%\%Configuration%\sys\otlwf\* release
copy build\bin\%Platform2%\%Configuration%\sys\otlwf.cer release
copy build\bin\%Platform2%\%Configuration%\sys\otlwf.pdb release\symbols
copy build\bin\%Platform2%\%Configuration%\dll\otApi.dll release
copy build\bin\%Platform2%\%Configuration%\dll\otApi.pdb release\symbols
copy build\bin\%Platform2%\%Configuration%\dll\otNodeApi.dll release
copy build\bin\%Platform2%\%Configuration%\dll\otNodeApi.pdb release\symbols
copy build\bin\%Platform2%\%Configuration%\exe\otCli.exe release
copy build\bin\%Platform2%\%Configuration%\exe\otCli.pdb release\symbols
copy build\bin\%Platform2%\%Configuration%\exe\otTestRunner.exe release
copy build\bin\%Platform2%\%Configuration%\exe\otTestRunner.pdb release\symbols
REM Generate the trace format files to decode the WPP logs
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\x64\TracePdb.exe" -f release\symbols\*.pdb -p release\symbols\TraceFormat
popd
+42
View File
@@ -0,0 +1,42 @@
REM
REM Copyright (c) 2016, The OpenThread Authors.
REM All rights reserved.
REM
REM Redistribution and use in source and binary forms, with or without
REM modification, are permitted provided that the following conditions are met:
REM 1. Redistributions of source code must retain the above copyright
REM notice, this list of conditions and the following disclaimer.
REM 2. Redistributions in binary form must reproduce the above copyright
REM notice, this list of conditions and the following disclaimer in the
REM documentation and/or other materials provided with the distribution.
REM 3. Neither the name of the copyright holder nor the
REM names of its contributors may be used to endorse or promote products
REM derived from this software without specific prior written permission.
REM
REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
REM ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
REM LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
REM CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
REM SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
REM INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
REM CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
REM ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
REM POSSIBILITY OF SUCH DAMAGE.
REM
IF NOT "%Platform%"=="x64" GOTO :EOF
pushd %APPVEYOR_BUILD_FOLDER%\release
REM Query the driver state
sc query otlwf
REM Grab the logs
logman stop Thread -ets
copy %SystemRoot%\System32\LogFiles\WMI\Thread.* logs
popd
+2 -1
View File
@@ -41,4 +41,5 @@ Makefile eol=lf
*.vcxproj eol=crlf
*.vcxproj.filters eol=crlf
*.sln eol=crlf
*.rc text eol=crlf
*.inf text eol=crlf
+1
View File
@@ -54,6 +54,7 @@ EXTRA_DIST = \
.astyle/astyle-wrap.sh \
.default-version \
bootstrap \
etc \
README.md \
NOTICE \
CONTRIBUTING.md \
@@ -228,6 +228,9 @@
<ClCompile Include="..\..\src\core\thread\announce_begin_server.cpp">
<Filter>Source Files\thread</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\common\crc16.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\core\openthreadcontext.h">
@@ -428,5 +431,8 @@
<ClInclude Include="..\..\src\core\meshcop\announce_begin_server.hpp">
<Filter>Header Files\thread</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\common\crc16.hpp">
<Filter>Header Files\common</Filter>
</ClInclude>
</ItemGroup>
</Project>
+70 -115
View File
@@ -18,6 +18,68 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9B33C190-5D07-40BF-9536-68843DC5D7AF}</ProjectGuid>
<TemplateGuid>{0a049372-4c4d-4ea0-a64e-dc6ad88ceca1}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>Thread</RootNamespace>
<DriverType>KMDF</DriverType>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>
%(PreprocessorDefinitions);
MBEDTLS_CONFIG_FILE="mbedtls-config.h";
OPENTHREAD_CONFIG_FILE="openthread-windows-config.h";
OPENTHREAD_PROJECT_CORE_CONFIG_FILE="openthread-core-windows-config.h";
WINDOWS_LOGGING;
OPENTHREAD_MULTIPLE_INSTANCE;
</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
%(AdditionalIncludeDirectories);
..\..\include;
..\..\examples\drivers\windows\include;
..\..\src\core;
..\..\src\missing\stdint;
..\..\src\missing\stdbool;
..\..\third_party\mbedtls;
..\..\third_party\mbedtls\repo\include;
</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4100;4706;4748;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>otCore</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\core\coap\coap_client.cpp" />
<ClCompile Include="..\..\src\core\coap\coap_header.cpp" />
@@ -77,6 +139,9 @@
<ClCompile Include="..\..\src\core\utils\global_address.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\openthread.h" />
<ClInclude Include="..\..\include\openthread-types.h" />
<ClInclude Include="..\..\include\openthread-windows-config.h" />
<ClInclude Include="..\..\src\core\coap\coap_client.hpp" />
<ClInclude Include="..\..\src\core\coap\coap_header.hpp" />
<ClInclude Include="..\..\src\core\coap\coap_server.hpp" />
@@ -117,7 +182,9 @@
<ClInclude Include="..\..\src\core\net\socket.hpp" />
<ClInclude Include="..\..\src\core\net\udp6.hpp" />
<ClInclude Include="..\..\src\core\openthread-core-config.h" />
<ClInclude Include="..\..\src\core\openthreadcontext.h" />
<ClInclude Include="..\..\src\core\openthread-core-default-config.h" />
<ClInclude Include="..\..\src\core\openthread-core-windows-config.h" />
<ClInclude Include="..\..\src\core\openthread-instance.h" />
<ClInclude Include="..\..\src\core\thread\address_resolver.hpp" />
<ClInclude Include="..\..\src\core\meshcop\announce_begin_server.hpp" />
<ClInclude Include="..\..\src\core\thread\energy_scan_server.hpp" />
@@ -145,118 +212,6 @@
<ClInclude Include="..\..\src\core\thread\topology.hpp" />
<ClInclude Include="..\..\src\core\utils\global_address.hpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9B33C190-5D07-40BF-9536-68843DC5D7AF}</ProjectGuid>
<TemplateGuid>{0a049372-4c4d-4ea0-a64e-dc6ad88ceca1}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>libopenthread_k</RootNamespace>
<DriverType>KMDF</DriverType>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions);MBEDTLS_CONFIG_FILE="mbedtls-config.h";OPENTHREAD_CONFIG_FILE="openthread-windows-config.h";WINDOWS_KERNEL;WINDOWS_LOGGING;OPENTHREAD_MULTIPLE_INSTANCE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4100;4706;4748;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>otCore</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);MBEDTLS_CONFIG_FILE="mbedtls-config.h";OPENTHREAD_CONFIG_FILE="openthread-windows-config.h";WINDOWS_KERNEL;WINDOWS_LOGGING;OPENTHREAD_MULTIPLE_INSTANCE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4100;4706;4748;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>otCore</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions);MBEDTLS_CONFIG_FILE="mbedtls-config.h";OPENTHREAD_CONFIG_FILE="openthread-windows-config.h";WINDOWS_KERNEL;WINDOWS_LOGGING;OPENTHREAD_MULTIPLE_INSTANCE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4100;4603;4627;4706;4986;4987;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>otCore</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);MBEDTLS_CONFIG_FILE="mbedtls-config.h";OPENTHREAD_CONFIG_FILE="openthread-windows-config.h";WINDOWS_KERNEL;WINDOWS_LOGGING;OPENTHREAD_MULTIPLE_INSTANCE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4100;4603;4627;4706;4986;4987;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>otCore</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
<ImportGroup Label="ExtensionTargets" />
</Project>
@@ -225,11 +225,11 @@
<ClCompile Include="..\..\src\core\meshcop\announce_begin_client.cpp">
<Filter>Source Files\meshcop</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\common\crc16.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\core\openthreadcontext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\openthread-core-config.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -425,5 +425,26 @@
<ClInclude Include="..\..\src\core\meshcop\announce_begin_client.hpp">
<Filter>Header Files\meshcop</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\common\crc16.hpp">
<Filter>Header Files\common</Filter>
</ClInclude>
<ClInclude Include="..\..\include\openthread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\openthread-types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\openthread-windows-config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\openthread-core-default-config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\openthread-core-windows-config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\openthread-instance.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+55 -97
View File
@@ -18,6 +18,60 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{69BE8E8C-CF1E-46D6-932B-DB435F47059B}</ProjectGuid>
<TemplateGuid>{0a049372-4c4d-4ea0-a64e-dc6ad88ceca1}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>Thread</RootNamespace>
<DriverType>KMDF</DriverType>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>
..\..\include;
..\..\src\core;
..\..\src\missing\stdint;
..\..\src\missing\stdbool;
..\..\third_party\mbedtls;
..\..\third_party\mbedtls\repo\include;
..\..\third_party\mbedtls\repo\include\mbedtls
</AdditionalIncludeDirectories>
<PreprocessorDefinitions>
%(PreprocessorDefinitions);
MBEDTLS_CONFIG_FILE="mbedtls-config.h";
OPENTHREAD_MULTIPLE_INSTANCE;
</PreprocessorDefinitions>
<DisableSpecificWarnings>4132;4242;4245;4603;4627;4986;4987;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\third_party\mbedtls\hardware_entropy.c" />
<ClCompile Include="..\..\third_party\mbedtls\repo\library\aes.c" />
@@ -44,102 +98,6 @@
<ClCompile Include="..\..\third_party\mbedtls\repo\library\ssl_ticket.c" />
<ClCompile Include="..\..\third_party\mbedtls\repo\library\ssl_tls.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{69BE8E8C-CF1E-46D6-932B-DB435F47059B}</ProjectGuid>
<TemplateGuid>{0a049372-4c4d-4ea0-a64e-dc6ad88ceca1}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>mbedtls_k</RootNamespace>
<DriverType>KMDF</DriverType>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4132;4242;4245;4748;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4132;4242;4245;4748;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4132;4242;4245;4603;4627;4986;4987;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4132;4242;4245;4603;4627;4986;4987;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ImportGroup Label="ExtensionTargets" />
</Project>
+17
View File
@@ -42,6 +42,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ot-ncp-spi", "ot-ncp-spi.vc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ot-ncp-uart", "ot-ncp-uart.vcxproj", "{9EEF9DCD-EA8F-4154-BD02-AB2B31CEC324}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "drivers", "drivers", "{61E8A4A0-8138-49DB-97B4-3BEC87C8E133}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "otLwf", "otLwf.vcxproj", "{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -150,6 +154,18 @@ Global
{9EEF9DCD-EA8F-4154-BD02-AB2B31CEC324}.Release|x64.Build.0 = Release|x64
{9EEF9DCD-EA8F-4154-BD02-AB2B31CEC324}.Release|x86.ActiveCfg = Release|Win32
{9EEF9DCD-EA8F-4154-BD02-AB2B31CEC324}.Release|x86.Build.0 = Release|Win32
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Debug|x64.ActiveCfg = Debug|x64
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Debug|x64.Build.0 = Debug|x64
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Debug|x64.Deploy.0 = Debug|x64
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Debug|x86.ActiveCfg = Debug|Win32
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Debug|x86.Build.0 = Debug|Win32
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Debug|x86.Deploy.0 = Debug|Win32
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Release|x64.ActiveCfg = Release|x64
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Release|x64.Build.0 = Release|x64
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Release|x64.Deploy.0 = Release|x64
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Release|x86.ActiveCfg = Release|Win32
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Release|x86.Build.0 = Release|Win32
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}.Release|x86.Deploy.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -167,5 +183,6 @@ Global
{D94867D2-6DAE-47E2-962A-5E8E658134D1} = {95BD0669-04C8-4EEB-B3CC-0535B03F4468}
{B4C744EC-B662-46C6-A076-FB58FA8FDF1B} = {76EA541E-CAB1-4DB5-A39F-E3DB2A78CDDD}
{9EEF9DCD-EA8F-4154-BD02-AB2B31CEC324} = {76EA541E-CAB1-4DB5-A39F-E3DB2A78CDDD}
{3F1F7F6C-2A33-4635-9880-08FC5BC4E435} = {61E8A4A0-8138-49DB-97B4-3BEC87C8E133}
EndGlobalSection
EndGlobal
+148
View File
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3F1F7F6C-2A33-4635-9880-08FC5BC4E435}</ProjectGuid>
<TemplateGuid>{8b1800b9-d017-4029-9785-13ef5e5b328e}</TemplateGuid>
<RootNamespace>Thread</RootNamespace>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Label="PropertySheets">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutputName>otlwf</OutputName>
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\sys\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreProcessorDefinitions>
%(PreProcessorDefinitions);
NDIS_WDM=1;
NDIS630=1;
OPENTHREAD_CONFIG_FILE="openthread-windows-config.h";
OPENTHREAD_PROJECT_CORE_CONFIG_FILE="openthread-core-windows-config.h";
OPENTHREAD_MULTIPLE_INSTANCE;
</PreProcessorDefinitions>
<AdditionalIncludeDirectories>
%(AdditionalIncludeDirectories);
..\..\include;
..\..\examples\drivers\windows\include;
..\..\examples\drivers\windows\otLwf;
..\..\src\core;
..\..\src\missing\stdint;
..\..\src\missing\stdbool;
</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>%(DisableSpecificWarnings);4201;4214</DisableSpecificWarnings>
<PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>otLwf</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..;.;</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>
%(AdditionalDependencies);
ndis.lib;
wdmsec.lib;
netio.lib;
uuid.lib;
cng.lib;
..\..\build\bin\$(Platform)\$(Configuration)\lib\libopenthread_k.lib;
..\..\build\bin\$(Platform)\$(Configuration)\lib\mbedtls_k.lib
</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<!--Leaf Item elements-->
<ClCompile Include="..\..\examples\drivers\windows\otLwf\address.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\alarm.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\datapath.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\driver.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\eventprocessing.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\iocontrol.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\oid.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\precomp.c">
<AdditionalIncludeDirectories>..;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreProcessorDefinitions>%(PreProcessorDefinitions);NDIS_WDM=1</PreProcessorDefinitions>
<PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
<PreCompiledHeader>Create</PreCompiledHeader>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\filter.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\device.c" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\radio.c" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\device.h" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\driver.h" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\iocontrol.h" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\nsihelper.h" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\oid.h" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\radio.h" />
<ClCompile Include="..\..\examples\drivers\windows\otLwf\settings.c" />
<ResourceCompile Include="..\..\examples\drivers\windows\otLwf\filter.rc" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\precomp.h" />
<ClInclude Include="..\..\examples\drivers\windows\otLwf\filter.h" />
<Inf Include="..\..\examples\drivers\windows\otLwf\otLwf.inf" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libopenthread_k.vcxproj">
<Project>{9b33c190-5d07-40bf-9536-68843dc5d7af}</Project>
</ProjectReference>
<ProjectReference Include="mbedtls_k.vcxproj">
<Project>{69be8e8c-cf1e-46d6-932b-db435f47059b}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
+95
View File
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Driver Files">
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
<Extensions>inf;inv;inx;mof;mc;</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Inf Include="..\..\examples\drivers\windows\otLwf\otLwf.inf">
<Filter>Driver Files</Filter>
</Inf>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\precomp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\filter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\driver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\device.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\nsihelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\oid.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\iocontrol.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\examples\drivers\windows\otLwf\radio.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\filter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\device.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\precomp.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\alarm.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\radio.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\driver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\oid.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\iocontrol.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\eventprocessing.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\datapath.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\address.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\examples\drivers\windows\otLwf\settings.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\examples\drivers\windows\otLwf\filter.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
+4
View File
@@ -35,6 +35,10 @@ DIST_SUBDIRS = \
apps \
$(NULL)
EXTRA_DIST = \
drivers \
$(NULL)
# Always build (e.g. for 'make all') these subdirectories.
if OPENTHREAD_EXAMPLES
@@ -0,0 +1,79 @@
/*
* 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.
*/
/**
* @file
* This file includes Windows compile-time configuration constants
* for OpenThread.
*/
#ifndef OPENTHREAD_CORE_WINDOWS_CONFIG_H_
#define OPENTHREAD_CORE_WINDOWS_CONFIG_H_
/**
* @def OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS
*
* The number of message buffers in the buffer pool.
*
*/
#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 2048
/**
* @def OPENTHREAD_CONFIG_MAX_CHILDREN
*
* The maximum number of children.
*
*/
#define OPENTHREAD_CONFIG_MAX_CHILDREN 32
/**
* @def OPENTHREAD_CONFIG_IP_ADDRS_PER_CHILD
*
* The minimum number of supported IPv6 address registrations per child.
*
*/
#define OPENTHREAD_CONFIG_IP_ADDRS_PER_CHILD 6
/**
* @def OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES
*
* The maximum number of Joiner entries maintained by the Commissioner.
*
*/
#define OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES 16
/**
* @def OPENTHREAD_CONFIG_LOG_LEVEL
*
* The log level.
*
*/
#define OPENTHREAD_CONFIG_LOG_LEVEL OPENTHREAD_LOG_LEVEL_DEBG
#endif // OPENTHREAD_CORE_WINDOWS_CONFIG_H_
@@ -0,0 +1,662 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the IOCTL interface for otLwf.sys.
*/
#ifndef __OTLWFIOCTL_H__
#define __OTLWFIOCTL_H__
#include <openthread-types.h>
__inline LONG ThreadErrorToNtstatus(ThreadError error) { return (LONG)-((int)error); }
// User-mode IOCTL path for CreateFile
#define OTLWF_IOCLT_PATH TEXT("\\\\.\\\\otlwf")
//
// IOCLTs and Data Types
//
#define OTLWF_CTL_CODE(request, method, access) \
CTL_CODE(FILE_DEVICE_NETWORK, request, method, access)
// Different possible notification types
typedef enum _OTLWF_NOTIF_TYPE
{
OTLWF_NOTIF_UNSPECIFIED,
OTLWF_NOTIF_DEVICE_AVAILABILITY,
OTLWF_NOTIF_STATE_CHANGE,
OTLWF_NOTIF_DISCOVER,
OTLWF_NOTIF_ACTIVE_SCAN,
OTLWF_NOTIF_ENERGY_SCAN,
OTLWF_NOTIF_COMMISSIONER_ENERGY_REPORT,
OTLWF_NOTIF_COMMISSIONER_PANID_QUERY
} OTLWF_NOTIF_TYPE;
#define MAX_ENERGY_REPORT_LENGTH 64
//
// Queries (async) the next notification in the queue
//
#define IOCTL_OTLWF_QUERY_NOTIFICATION \
OTLWF_CTL_CODE(0, METHOD_BUFFERED, FILE_READ_DATA)
typedef struct _OTLWF_NOTIFICATION {
GUID InterfaceGuid;
OTLWF_NOTIF_TYPE NotifType;
union
{
// Payload for OTLWF_NOTIF_DEVICE_AVAILABILITY
struct
{
BOOLEAN Available;
} DeviceAvailabilityPayload;
// Payload for OTLWF_NOTIF_STATE_CHANGE
struct
{
uint32_t Flags;
} StateChangePayload;
// Payload for OTLWF_NOTIF_DISCOVER
struct
{
BOOLEAN Valid;
otActiveScanResult Results;
} DiscoverPayload;
// Payload for OTLWF_NOTIF_ACTIVE_SCAN
struct
{
BOOLEAN Valid;
otActiveScanResult Results;
} ActiveScanPayload;
// Payload for OTLWF_NOTIF_ENERGY_SCAN
struct
{
BOOLEAN Valid;
otEnergyScanResult Results;
} EnergyScanPayload;
// Payload for OTLWF_NOTIF_COMMISSIONER_ENERGY_REPORT
struct
{
uint32_t ChannelMask;
uint8_t EnergyListLength;
uint8_t EnergyList[MAX_ENERGY_REPORT_LENGTH];
} CommissionerEnergyReportPayload;
// Payload for OTLWF_NOTIF_COMMISSIONER_PANID_QUERY
struct
{
uint16_t PanId;
uint32_t ChannelMask;
} CommissionerPanIdQueryPayload;
};
} OTLWF_NOTIFICATION, *POTLWF_NOTIFICATION;
//
// Enumerates all the Thread interfaces guids
//
#define IOCTL_OTLWF_ENUMERATE_DEVICES \
OTLWF_CTL_CODE(1, METHOD_BUFFERED, FILE_READ_DATA)
typedef struct _OTLWF_INTERFACE_LIST
{
uint16_t cInterfaceGuids;
GUID InterfaceGuids[1];
} OTLWF_INTERFACE_LIST, *POTLWF_INTERFACE_LIST;
//
// Queries the detials of a given device Thread interfaces
//
#define IOCTL_OTLWF_QUERY_DEVICE \
OTLWF_CTL_CODE(2, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid (in)
typedef struct _OTLWF_DEVICE {
ULONG CompartmentID;
} OTLWF_DEVICE, *POTLWF_DEVICE;
//
// Proxies to ot* APIs in otLwf.sys
//
/* REMOVED
#define IOCTL_OTLWF_OT_ENABLED \
OTLWF_CTL_CODE(100, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aEnabled
*/
#define IOCTL_OTLWF_OT_INTERFACE \
OTLWF_CTL_CODE(101, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aUp
#define IOCTL_OTLWF_OT_THREAD \
OTLWF_CTL_CODE(102, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aStarted
#define IOCTL_OTLWF_OT_ACTIVE_SCAN \
OTLWF_CTL_CODE(103, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aScanChannels
// uint16_t - aScanDuration
#define IOCTL_OTLWF_OT_DISCOVER \
OTLWF_CTL_CODE(104, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aScanChannels
// uint16_t - aScanDuration
// uint16_t - aPanid
#define IOCTL_OTLWF_OT_CHANNEL \
OTLWF_CTL_CODE(105, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aChannel
#define IOCTL_OTLWF_OT_CHILD_TIMEOUT \
OTLWF_CTL_CODE(106, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aTimeout
#define IOCTL_OTLWF_OT_EXTENDED_ADDRESS \
OTLWF_CTL_CODE(107, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtAddress - aExtendedAddress
#define IOCTL_OTLWF_OT_EXTENDED_PANID \
OTLWF_CTL_CODE(108, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtendedPanId - aExtendedPanId
#define IOCTL_OTLWF_OT_LEADER_RLOC \
OTLWF_CTL_CODE(109, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otIp6Address - aLeaderRloc
#define IOCTL_OTLWF_OT_LINK_MODE \
OTLWF_CTL_CODE(110, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otLinkModeConfig - aConfig
#define IOCTL_OTLWF_OT_MASTER_KEY \
OTLWF_CTL_CODE(111, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otMasterKey - aKey
// uint8_t - aKeyLength
#define IOCTL_OTLWF_OT_MESH_LOCAL_EID \
OTLWF_CTL_CODE(112, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otIp6Address - aMeshLocalEid
#define IOCTL_OTLWF_OT_MESH_LOCAL_PREFIX \
OTLWF_CTL_CODE(113, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otMeshLocalPrefix - aPrefix
#define IOCTL_OTLWF_OT_NETWORK_DATA_LEADER \
OTLWF_CTL_CODE(114, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t[] - aData
#define IOCTL_OTLWF_OT_NETWORK_DATA_LOCAL \
OTLWF_CTL_CODE(115, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t[] - aData
#define IOCTL_OTLWF_OT_NETWORK_NAME \
OTLWF_CTL_CODE(116, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otNetworkName - aNetworkName
#define IOCTL_OTLWF_OT_PAN_ID \
OTLWF_CTL_CODE(117, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otPanId - aPanId
#define IOCTL_OTLWF_OT_ROUTER_ROLL_ENABLED \
OTLWF_CTL_CODE(118, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aEnabled
#define IOCTL_OTLWF_OT_SHORT_ADDRESS \
OTLWF_CTL_CODE(119, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otShortAddress - aShortAddress
#define IOCTL_OTLWF_OT_UNICAST_ADDRESSES \
OTLWF_CTL_CODE(120, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otNetifAddress[] - aAddresses
#define IOCTL_OTLWF_OT_ACTIVE_DATASET \
OTLWF_CTL_CODE(121, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otOperationalDataset - aDataset
#define IOCTL_OTLWF_OT_PENDING_DATASET \
OTLWF_CTL_CODE(122, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otOperationalDataset - aDataset
#define IOCTL_OTLWF_OT_LOCAL_LEADER_WEIGHT \
OTLWF_CTL_CODE(123, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aWeight
#define IOCTL_OTLWF_OT_ADD_BORDER_ROUTER \
OTLWF_CTL_CODE(124, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otBorderRouterConfig - aConfig
#define IOCTL_OTLWF_OT_REMOVE_BORDER_ROUTER \
OTLWF_CTL_CODE(125, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otIp6Prefix - aPrefix
#define IOCTL_OTLWF_OT_ADD_EXTERNAL_ROUTE \
OTLWF_CTL_CODE(126, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExternalRouteConfig - aConfig
#define IOCTL_OTLWF_OT_REMOVE_EXTERNAL_ROUTE \
OTLWF_CTL_CODE(127, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otIp6Prefix - aPrefix
#define IOCTL_OTLWF_OT_SEND_SERVER_DATA \
OTLWF_CTL_CODE(128, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_CONTEXT_ID_REUSE_DELAY \
OTLWF_CTL_CODE(129, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aDelay
#define IOCTL_OTLWF_OT_KEY_SEQUENCE_COUNTER \
OTLWF_CTL_CODE(130, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aKeySequenceCounter
#define IOCTL_OTLWF_OT_NETWORK_ID_TIMEOUT \
OTLWF_CTL_CODE(131, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aTimeout
#define IOCTL_OTLWF_OT_ROUTER_UPGRADE_THRESHOLD \
OTLWF_CTL_CODE(132, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aThreshold
#define IOCTL_OTLWF_OT_RELEASE_ROUTER_ID \
OTLWF_CTL_CODE(133, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aRouterId
#define IOCTL_OTLWF_OT_MAC_WHITELIST_ENABLED \
OTLWF_CTL_CODE(134, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aEnabled
#define IOCTL_OTLWF_OT_ADD_MAC_WHITELIST \
OTLWF_CTL_CODE(135, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtAddress - aExtAddr
// int8_t - aRssi (optional)
#define IOCTL_OTLWF_OT_REMOVE_MAC_WHITELIST \
OTLWF_CTL_CODE(136, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtAddress - aExtAddr
#define IOCTL_OTLWF_OT_MAC_WHITELIST_ENTRY \
OTLWF_CTL_CODE(137, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aIndex (input)
// otMacWhitelistEntry - aEntry (output)
#define IOCTL_OTLWF_OT_CLEAR_MAC_WHITELIST \
OTLWF_CTL_CODE(138, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_DEVICE_ROLE \
OTLWF_CTL_CODE(139, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otDeviceRole - aRole
// otMleAttachFilter - aFilter (only for kDeviceRoleChild)
#define IOCTL_OTLWF_OT_CHILD_INFO_BY_ID \
OTLWF_CTL_CODE(140, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint16_t - aChildId (input)
// otChildInfo - aChildInfo (output)
#define IOCTL_OTLWF_OT_CHILD_INFO_BY_INDEX \
OTLWF_CTL_CODE(141, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aChildIndex (input)
// otChildInfo - aChildInfo (output)
#define IOCTL_OTLWF_OT_EID_CACHE_ENTRY \
OTLWF_CTL_CODE(142, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aIndex (input)
// otEidCacheEntry - aEntry (output)
#define IOCTL_OTLWF_OT_LEADER_DATA \
OTLWF_CTL_CODE(143, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otLeaderData - aLeaderData
#define IOCTL_OTLWF_OT_LEADER_ROUTER_ID \
OTLWF_CTL_CODE(144, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aRouterID
#define IOCTL_OTLWF_OT_LEADER_WEIGHT \
OTLWF_CTL_CODE(145, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aWeight
#define IOCTL_OTLWF_OT_NETWORK_DATA_VERSION \
OTLWF_CTL_CODE(146, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aVersion
#define IOCTL_OTLWF_OT_PARTITION_ID \
OTLWF_CTL_CODE(147, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint32_t - aPartition
#define IOCTL_OTLWF_OT_RLOC16 \
OTLWF_CTL_CODE(148, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint16_t - aRloc16
#define IOCTL_OTLWF_OT_ROUTER_ID_SEQUENCE \
OTLWF_CTL_CODE(149, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aIdSequence
#define IOCTL_OTLWF_OT_ROUTER_INFO \
OTLWF_CTL_CODE(150, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint16_t - aRouterId (input)
// otRouterInfo - aRouterInfo (output)
#define IOCTL_OTLWF_OT_STABLE_NETWORK_DATA_VERSION \
OTLWF_CTL_CODE(151, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aVersion
#define IOCTL_OTLWF_OT_MAC_BLACKLIST_ENABLED \
OTLWF_CTL_CODE(152, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aEnabled
#define IOCTL_OTLWF_OT_ADD_MAC_BLACKLIST \
OTLWF_CTL_CODE(153, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtAddress - aExtAddr
#define IOCTL_OTLWF_OT_REMOVE_MAC_BLACKLIST \
OTLWF_CTL_CODE(154, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtAddress - aExtAddr
#define IOCTL_OTLWF_OT_MAC_BLACKLIST_ENTRY \
OTLWF_CTL_CODE(155, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// uint8_t - aIndex (input)
// otMacBlacklistEntry - aEntry (output)
#define IOCTL_OTLWF_OT_CLEAR_MAC_BLACKLIST \
OTLWF_CTL_CODE(156, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_MAX_TRANSMIT_POWER \
OTLWF_CTL_CODE(157, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// int8_t - aPower
#define IOCTL_OTLWF_OT_NEXT_ON_MESH_PREFIX \
OTLWF_CTL_CODE(158, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aLocal (input)
// uint8_t - aIterator (input)
// uint8_t - aNewIterator (output)
// otBorderRouterConfig - aConfig (output)
#define IOCTL_OTLWF_OT_POLL_PERIOD \
OTLWF_CTL_CODE(159, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aPollPeriod
#define IOCTL_OTLWF_OT_LOCAL_LEADER_PARTITION_ID \
OTLWF_CTL_CODE(160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aPartitionId
#define IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY \
OTLWF_CTL_CODE(161, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otExtAddress - aExtAddr (input)
// uint8_t - aLinkQuality (input or output)
#define IOCTL_OTLWF_OT_PLATFORM_RESET \
OTLWF_CTL_CODE(162, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_PARENT_INFO \
OTLWF_CTL_CODE(163, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otRouterInfo - aParentInfo
#define IOCTL_OTLWF_OT_SINGLETON \
OTLWF_CTL_CODE(164, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// BOOLEAN - aSingleton
#define IOCTL_OTLWF_OT_MAC_COUNTERS \
OTLWF_CTL_CODE(165, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otMacCounters - aCounters
#define IOCTL_OTLWF_OT_MAX_CHILDREN \
OTLWF_CTL_CODE(166, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aMaxChildren
#define IOCTL_OTLWF_OT_COMMISIONER_START \
OTLWF_CTL_CODE(167, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_COMMISIONER_STOP \
OTLWF_CTL_CODE(168, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define OPENTHREAD_PSK_MAX_LENGTH 32
#define OPENTHREAD_PROV_URL_MAX_LENGTH 64
typedef struct otCommissionConfig
{
uint8_t PSKd[OPENTHREAD_PSK_MAX_LENGTH + 1];
uint8_t ProvisioningUrl[OPENTHREAD_PROV_URL_MAX_LENGTH + 1];
} otCommissionConfig;
#define IOCTL_OTLWF_OT_JOINER_START \
OTLWF_CTL_CODE(169, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otCommissionConfig - aConfig
#define IOCTL_OTLWF_OT_JOINER_STOP \
OTLWF_CTL_CODE(170, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
#define IOCTL_OTLWF_OT_FACTORY_EUI64 \
OTLWF_CTL_CODE(171, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otExtAddress - aEui64
#define IOCTL_OTLWF_OT_HASH_MAC_ADDRESS \
OTLWF_CTL_CODE(172, METHOD_BUFFERED, FILE_READ_DATA)
// GUID - InterfaceGuid
// otExtAddress - aEui64
#define IOCTL_OTLWF_OT_ROUTER_DOWNGRADE_THRESHOLD \
OTLWF_CTL_CODE(173, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aThreshold
#define IOCTL_OTLWF_OT_COMMISSIONER_PANID_QUERY \
OTLWF_CTL_CODE(174, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint16_t - aPanId
// uint32_t - aChannekMask
// otIp6Address - aAddress
#define IOCTL_OTLWF_OT_COMMISSIONER_ENERGY_SCAN \
OTLWF_CTL_CODE(175, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aChannekMask
// uint8_t - aCount
// uint16_t - aPeriod
// uint16_t - aScanDuration
// otIp6Address - aAddress
#define IOCTL_OTLWF_OT_ROUTER_SELECTION_JITTER \
OTLWF_CTL_CODE(176, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aRouterJitter
#define IOCTL_OTLWF_OT_JOINER_UDP_PORT \
OTLWF_CTL_CODE(177, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint16_t - aJoinerUdpPort
#define IOCTL_OTLWF_OT_SEND_DIAGNOSTIC_GET \
OTLWF_CTL_CODE(178, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otIp6Address - aDestination
// uint8_t - aCount
// uint8_t[aCount] - aTlvTypes
#define IOCTL_OTLWF_OT_SEND_DIAGNOSTIC_RESET \
OTLWF_CTL_CODE(179, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otIp6Address - aDestination
// uint8_t - aCount
// uint8_t[aCount] - aTlvTypes
#define IOCTL_OTLWF_OT_COMMISIONER_ADD_JOINER \
OTLWF_CTL_CODE(180, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aExtAddressValid
// otExtAddress - aExtAddress (optional)
// char[OPENTHREAD_PSK_MAX_LENGTH + 1] - aPSKd
#define IOCTL_OTLWF_OT_COMMISIONER_REMOVE_JOINER \
OTLWF_CTL_CODE(181, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aExtAddressValid
// otExtAddress - aExtAddress (optional)
#define IOCTL_OTLWF_OT_COMMISIONER_PROVISIONING_URL \
OTLWF_CTL_CODE(182, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// char[OPENTHREAD_PROV_URL_MAX_LENGTH + 1] - aProvisioningUrl (optional)
#define IOCTL_OTLWF_OT_COMMISIONER_ANNOUNCE_BEGIN \
OTLWF_CTL_CODE(183, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aChannelMask
// uint8_t - aCount
// uint16_t - aPeriod
// otIp6Address - aAddress
#define IOCTL_OTLWF_OT_ENERGY_SCAN \
OTLWF_CTL_CODE(184, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aScanChannels
// uint16_t - aScanDuration
#define IOCTL_OTLWF_OT_SEND_ACTIVE_GET \
OTLWF_CTL_CODE(185, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aLength
// uint8_t[aLength] - aTlvTypes
#define IOCTL_OTLWF_OT_SEND_ACTIVE_SET \
OTLWF_CTL_CODE(186, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otOperationalDataset - aDataset
// uint8_t - aLength
// uint8_t[aLength] - aTlvTypes
#define IOCTL_OTLWF_OT_SEND_PENDING_GET \
OTLWF_CTL_CODE(187, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aLength
// uint8_t[aLength] - aTlvTypes
#define IOCTL_OTLWF_OT_SEND_PENDING_SET \
OTLWF_CTL_CODE(188, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otOperationalDataset - aDataset
// uint8_t - aLength
// uint8_t[aLength] - aTlvTypes
#define IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_GET \
OTLWF_CTL_CODE(189, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint8_t - aLength
// uint8_t[aLength] - aTlvs
#define IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_SET \
OTLWF_CTL_CODE(190, METHOD_BUFFERED, FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otOperationalDataset - aDataset
// uint8_t - aLength
// uint8_t[aLength] - aTlvs
#define IOCTL_OTLWF_OT_KEY_SWITCH_GUARDTIME \
OTLWF_CTL_CODE(191, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// uint32_t - aKeySwitchGuardTime
// OpenThread function IOCTL codes
#define MIN_OTLWF_IOCTL_FUNC_CODE 100
#define MAX_OTLWF_IOCTL_FUNC_CODE 191
#endif //__OTLWFIOCTL_H__
@@ -0,0 +1,78 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the context structure for NBLs send between otLwf and it's miniport.
*/
#ifndef __OT_NBL_CONTEXT_H__
#define __OT_NBL_CONTEXT_H__
#ifndef _NDIS_
#define NET_BUFFER_LIST_INFO(_NBL, _Id) ((_NBL)->NetBufferListInfo[(_Id)])
#endif
// Flag that indicates the ACK received had the Frame pending flag
#define OT_NBL_FLAG_ACK_FRAME_PENDING 0x01
// Represents the data necessary for the MAC layer to send out the NetBufferList
// Must be saved in: NET_BUFFER_LIST_INFO(NetBufferList, MediaSpecificInformationEx)
typedef struct _OT_NBL_CONTEXT
{
// Flags
UCHAR Flags;
// Channel used to transmit/receive the frame.
UCHAR Channel;
// Transmit/receive power in dBm.
CHAR Power;
// Link Quality Indicator for received frames.
UCHAR Lqi;
} OT_NBL_CONTEXT, *POT_NBL_CONTEXT;
// OT_NBL_CONTEXT must fit in the pointer used for MediaSpecificInformationEx in the NBL
C_ASSERT(sizeof(OT_NBL_CONTEXT) <= sizeof(PVOID));
// Helper to set the OT_NBL_CONTEXT attached to the NetBufferList
__forceinline VOID SetNBLContext(_In_ PNET_BUFFER_LIST NetBufferList, _In_ POT_NBL_CONTEXT Context)
{
*(POT_NBL_CONTEXT)(&NET_BUFFER_LIST_INFO(NetBufferList, MediaSpecificInformationEx)) = *Context;
}
// Helper to return the OT_NBL_CONTEXT attached to the NetBufferList
__forceinline POT_NBL_CONTEXT GetNBLContext(_In_ PNET_BUFFER_LIST NetBufferList)
{
return (POT_NBL_CONTEXT)(&NET_BUFFER_LIST_INFO(NetBufferList, MediaSpecificInformationEx));
}
#endif //__OT_NBL_CONTEXT_H__
+236
View File
@@ -0,0 +1,236 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the OID interface between otLwf and it's miniport.
*/
#ifndef __OTOID_H__
#define __OTOID_H__
#pragma once
//
// Macros for defining native OpenThread OIDs
//
#define OT_OPERATIONAL_OID (0x01U)
#define OT_STATISTICS_OID (0x02U)
#define OT_MANDATORY_OID (0x01U)
#define OT_OPTIONAL_OID (0x02U)
#define OT_DEFINE_OID(Seq,o,m) ((0xD0000000U) | ((o) << 16) | ((m) << 8) | (Seq))
//
// OpenThread Status Indication codes (and associated payload types)
//
#define NDIS_STATUS_OT_ENERGY_SCAN_RESULT ((NDIS_STATUS)0x40050000L)
typedef struct _OT_ENERGY_SCAN_RESULT
{
NDIS_STATUS Status;
CHAR MaxRssi;
} OT_ENERGY_SCAN_RESULT, * POT_ENERGY_SCAN_RESULT;
//
// General OID Definitions
//
// Used to query initial constants of the miniport
#define OID_OT_CAPABILITIES OT_DEFINE_OID(0, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef enum OT_MP_MODE
{
OT_MP_MODE_RADIO, // Supports the physical radio layer
OT_MP_MODE_THREAD // Supports the full Thread stack
} OT_MP_MODE;
typedef enum OT_RADIO_CAPABILITY
{
// Radio supports Ack timeouts internally
OT_RADIO_CAP_ACK_TIMEOUT = 1 << 0,
// Radio supports MAC retry logic and timers; as well as collision avoidance.
OT_RADIO_CAP_MAC_RETRY_AND_COLLISION_AVOIDANCE = 1 << 1,
// Radio supports sleeping. If the device supports sleeping, it is assumed to
// default to the sleep state on bring up.
OT_RADIO_CAP_SLEEP = 1 << 2,
} OT_RADIO_CAPABILITY;
typedef struct _OT_CAPABILITIES
{
#define OT_CAPABILITIES_REVISION_1 1
NDIS_OBJECT_HEADER Header;
OT_MP_MODE MiniportMode;
USHORT RadioCapabilities; // OT_RADIO_CAPABILITY flags
} OT_CAPABILITIES, * POT_CAPABILITIES;
#define SIZEOF_OT_CAPABILITIES_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_CAPABILITIES, RadioCapabilities)
//
// Radio Mode OIDs
//
// Used to query/set sleep mode; only used if RadioCapabilities
// indicates support for OT_RADIO_CAP_SLEEP.
#define OID_OT_SLEEP_MODE OT_DEFINE_OID(100, OT_OPERATIONAL_OID, OT_OPTIONAL_OID)
typedef struct _OT_SLEEP_MODE
{
#define OT_SLEEP_MODE_REVISION_1 1
NDIS_OBJECT_HEADER Header;
BOOLEAN InSleepMode;
} OT_SLEEP_MODE, * POT_SLEEP_MODE;
#define SIZEOF_OT_SLEEP_MODE_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_SLEEP_MODE, InSleepMode)
// Used to query/set promiscuous mode
#define OID_OT_PROMISCUOUS_MODE OT_DEFINE_OID(101, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_PROMISCUOUS_MODE
{
#define OT_PROMISCUOUS_MODE_REVISION_1 1
NDIS_OBJECT_HEADER Header;
BOOLEAN InPromiscuousMode;
} OT_PROMISCUOUS_MODE, * POT_PROMISCUOUS_MODE;
#define SIZEOF_OT_PROMISCUOUS_MODE_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_PROMISCUOUS_MODE, InPromiscuousMode)
// Used to query the factory Extended Address
#define OID_OT_FACTORY_EXTENDED_ADDRESS OT_DEFINE_OID(102, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_FACTORY_EXTENDED_ADDRESS
{
#define OT_FACTORY_EXTENDED_ADDRESS_REVISION_1 1
NDIS_OBJECT_HEADER Header;
ULONGLONG ExtendedAddress;
} OT_FACTORY_EXTENDED_ADDRESS, * POT_FACTORY_EXTENDED_ADDRESS;
#define SIZEOF_OT_FACTORY_EXTENDED_ADDRESS_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_FACTORY_EXTENDED_ADDRESS, ExtendedAddress)
// Used to query/set the Pan ID
#define OID_OT_PAND_ID OT_DEFINE_OID(103, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_PAND_ID
{
#define OT_PAND_ID_REVISION_1 1
NDIS_OBJECT_HEADER Header;
USHORT PanID;
} OT_PAND_ID, * POT_PAND_ID;
#define SIZEOF_OT_PAND_ID_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_PAND_ID, PanID)
// Used to query/set the Short Address
#define OID_OT_SHORT_ADDRESS OT_DEFINE_OID(104, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_SHORT_ADDRESS
{
#define OT_SHORT_ADDRESS_REVISION_1 1
NDIS_OBJECT_HEADER Header;
USHORT ShortAddress;
} OT_SHORT_ADDRESS, * POT_SHORT_ADDRESS;
#define SIZEOF_OT_SHORT_ADDRESS_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_SHORT_ADDRESS, ShortAddress)
// Used to query/set the Extended Address
#define OID_OT_EXTENDED_ADDRESS OT_DEFINE_OID(105, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_EXTENDED_ADDRESS
{
#define OT_EXTENDED_ADDRESS_REVISION_1 1
NDIS_OBJECT_HEADER Header;
ULONGLONG ExtendedAddress;
} OT_EXTENDED_ADDRESS, * POT_EXTENDED_ADDRESS;
#define SIZEOF_OT_EXTENDED_ADDRESS_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_EXTENDED_ADDRESS, ExtendedAddress)
// Used to query/set the current listening channel
#define OID_OT_CURRENT_CHANNEL OT_DEFINE_OID(106, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_CURRENT_CHANNEL
{
#define OT_CURRENT_CHANNEL_REVISION_1 1
NDIS_OBJECT_HEADER Header;
UCHAR Channel;
} OT_CURRENT_CHANNEL, * POT_CURRENT_CHANNEL;
#define SIZEOF_OT_CURRENT_CHANNEL_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_CURRENT_CHANNEL, Channel)
// Used to query the current RSSI for the current channel
#define OID_OT_RSSI OT_DEFINE_OID(107, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_RSSI
{
#define OT_RSSI_REVISION_1 1
NDIS_OBJECT_HEADER Header;
CHAR Rssi;
} OT_RSSI, * POT_RSSI;
#define SIZEOF_OT_RSSI_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_RSSI, Rssi)
// The maximum of each type (short or extended) of MAC address to pend
#define MAX_PENDING_MAC_SIZE 32
// Used to set the list of MAC addresses for SEDs we currently have packets pending
#define OID_OT_PENDING_MAC_OFFLOAD OT_DEFINE_OID(108, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_PENDING_MAC_OFFLOAD
{
#define OT_PENDING_MAC_OFFLOAD_REVISION_1 1
NDIS_OBJECT_HEADER Header;
UCHAR ShortAddressCount;
UCHAR ExtendedAddressCount;
// Dynamic array of USHORT ShortAddresses of count ShortAddressCount
// Dynamic array of ULONGLONG ExtendedAddresses of count ExtendedAddressCount
} OT_PENDING_MAC_OFFLOAD, * POT_PENDING_MAC_OFFLOAD;
#define SIZEOF_OT_PENDING_MAC_OFFLOAD_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_PENDING_MAC_OFFLOAD, ExtendedAddressCount)
#define COMPLETE_SIZEOF_OT_PENDING_MAC_OFFLOAD_REVISION_1(ShortAddressCount, ExtendedAddressCount) \
(SIZEOF_OT_PENDING_MAC_OFFLOAD_REVISION_1 + sizeof(USHORT) * ShortAddressCount + sizeof(ULONGLONG) * ExtendedAddressCount)
// Used to issue an energy scan request for the given channel
#define OID_OT_ENERGY_SCAN OT_DEFINE_OID(109, OT_OPERATIONAL_OID, OT_MANDATORY_OID)
typedef struct _OT_ENERGY_SCAN
{
#define OT_ENERGY_SCAN_REVISION_1 1
NDIS_OBJECT_HEADER Header;
UCHAR Channel;
USHORT DurationMs;
} OT_ENERGY_SCAN, * POT_ENERGY_SCAN;
#define SIZEOF_OT_ENERGY_SCAN_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(OT_ENERGY_SCAN, DurationMs)
//
// Thread Mode OIDs
//
// TODO ...
#endif //__OTOID_H__
@@ -0,0 +1,441 @@
/*
* 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.
*/
/**
* @file
* @brief
* This module contains routines and type definitions for managing reference
* counts.
*
* N.B. The functions defined here use the minimum fencing required for correct
* management of the reference count contract. No additional memory
* ordering should be assumed.
*/
#pragma once
//
// Architecture support macros.
// (Undefined at the bottom to avoid global namespace pollution)
//
#if defined(_WIN64)
#define RtlIncrementLongPtrNoFence InterlockedIncrementNoFence64
#define RtlDecrementLongPtrRelease InterlockedDecrementRelease64
#define RtlExchangeAddLongPtrNoFence InterlockedExchangeAddNoFence64
#define RtlExchangeAddLongPtrRelease InterlockedExchangeAddRelease64
#define RtlCompareExchangeLongPtrNoFence InterlockedCompareExchangeNoFence64
#define RtlCompareExchangeLongPtrRelease InterlockedCompareExchangeRelease64
#else
#define RtlIncrementLongPtrNoFence InterlockedIncrementNoFence
#define RtlDecrementLongPtrRelease InterlockedDecrementRelease
#define RtlExchangeAddLongPtrNoFence InterlockedExchangeAddNoFence
#define RtlExchangeAddLongPtrRelease InterlockedExchangeAddRelease
#define RtlCompareExchangeLongPtrNoFence InterlockedCompareExchangeNoFence
#define RtlCompareExchangeLongPtrRelease InterlockedCompareExchangeRelease
#endif
#if defined(_X86_) || defined(_AMD64_)
#define RtlBarrierAfterInterlock()
#elif defined(_ARM64_)
#define RtlBarrierAfterInterlock() __dmb(_ARM64_BARRIER_ISH)
#elif defined(_ARM_)
#define RtlBarrierAfterInterlock() __dmb(_ARM_BARRIER_ISH)
#else
#define Unsupported architecture.
#endif
#define RTL_REF_COUNT_INIT 1
FORCEINLINE
VOID
RtlInitializeReferenceCount (
_Out_ PRTL_REFERENCE_COUNT RefCount
)
/*++
Routine Description:
This function initializes a reference count to 1.
Arguments:
RefCount - Supplies a pointer to a reference count to initialize.
Return Value:
None.
--*/
{
*RefCount = RTL_REF_COUNT_INIT;
return;
}
FORCEINLINE
VOID
RtlInitializeReferenceCountEx (
_Out_ PRTL_REFERENCE_COUNT RefCount,
_In_ ULONG Bias
)
/*++
Routine Description:
This function initializes a reference count to a positive value.
Arguments:
RefCount - Supplies a pointer to a reference count to initialize.
Bias - Supplies an initial reference count (must be positive).
Return Value:
None.
--*/
{
*RefCount = Bias;
return;
}
FORCEINLINE
VOID
RtlIncrementReferenceCount (
_Inout_ PRTL_REFERENCE_COUNT RefCount
)
/*++
Routine Description:
This function increments the specified reference count, preventing object
deletion.
Arguments:
RefCount - Supplies a pointer to a reference count.
Return Value:
None.
--*/
{
if (RtlIncrementLongPtrNoFence(RefCount) > 1) {
return;
}
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
}
FORCEINLINE
VOID
RtlIncrementReferenceCountEx (
_Inout_ PRTL_REFERENCE_COUNT RefCount,
_In_ ULONG Bias
)
/*++
Routine Description:
This function increases the specified reference count by the specified bias,
preventing object deletion.
Arguments:
RefCount - Supplies a pointer to a reference count.
Bias - Supplies a reference bias amount.
Return Value:
None.
--*/
{
if (RtlExchangeAddLongPtrNoFence(RefCount, Bias) > 0) {
return;
}
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
}
FORCEINLINE
BOOLEAN
RtlIncrementReferenceCountNonZero (
_Inout_ volatile RTL_REFERENCE_COUNT *RefCount,
_In_ ULONG Bias
)
/*++
Routine Description:
This function increases the specified reference count by the specified bias,
unless the reference count was previously zero.
Arguments:
RefCount - Supplies a pointer to a reference count.
Bias - Supplies a reference bias amount.
Return Value:
TRUE if the reference count was incremented, FALSE otherwise.
--*/
{
RTL_REFERENCE_COUNT NewValue;
RTL_REFERENCE_COUNT OldValue;
PrefetchForWrite(RefCount);
OldValue = ReadLongPtrNoFence(RefCount);
for (;;) {
NewValue = OldValue + Bias;
if ((ULONG_PTR)NewValue > Bias) {
NewValue = RtlCompareExchangeLongPtrNoFence(RefCount,
NewValue,
OldValue);
if (NewValue == OldValue) {
return TRUE;
}
OldValue = NewValue;
} else if ((ULONG_PTR)NewValue == Bias) {
return FALSE;
} else {
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
}
}
}
FORCEINLINE
BOOLEAN
RtlDecrementReferenceCount (
_Inout_ PRTL_REFERENCE_COUNT RefCount
)
/*++
Routine Description:
This function reduces the specified reference count, potentially triggering
the destruction of the guarded object.
Arguments:
RefCount - Supplies a pointer to a reference count.
Return Value:
TRUE if the object should be destroyed, FALSE otherwise.
--*/
{
RTL_REFERENCE_COUNT NewValue;
//
// A release fence is required to ensure all guarded memory accesses are
// complete before any thread can begin destroying the object.
//
NewValue = RtlDecrementLongPtrRelease(RefCount);
if (NewValue > 0) {
return FALSE;
} else if (NewValue == 0) {
//
// An acquire fence is required before object destruction to ensure
// that the destructor cannot observe values changing on other threads.
//
RtlBarrierAfterInterlock();
return TRUE;
}
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
return FALSE;
}
FORCEINLINE
BOOLEAN
RtlDecrementReferenceCountEx (
_Inout_ PRTL_REFERENCE_COUNT RefCount,
_In_ ULONG Bias
)
/*++
Routine Description:
This function reduces the specified reference count by the specified amount,
potentially triggering the destruction of the guarded object.
Arguments:
RefCount - Supplies a pointer to a reference count.
Bias - Supplies a reference bias amount.
Return Value:
TRUE if the object should be destroyed, FALSE otherwise.
--*/
{
RTL_REFERENCE_COUNT NewValue;
//
// A release fence is required to ensure all guarded memory accesses are
// complete before any thread can begin destroying the object.
//
NewValue = RtlExchangeAddLongPtrRelease(RefCount, -(LONG)Bias) - Bias;
if (NewValue > 0) {
return FALSE;
} else if (NewValue == 0) {
//
// An acquire fence is required before object destruction to ensure
// that the destructor cannot observe values changing on other threads.
//
RtlBarrierAfterInterlock();
return TRUE;
}
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
return FALSE;
}
FORCEINLINE
BOOLEAN
RtlDecrementReferenceCountNonZero (
_Inout_ volatile RTL_REFERENCE_COUNT *RefCount,
_In_ ULONG Bias
)
/*++
Routine Description:
This function reduces the specified reference count by the specified amount,
unless doing so would result in a zero value.
Arguments:
RefCount - Supplies a pointer to a reference count.
Bias - Supplies a reference bias amount.
Return Value:
TRUE if the reference count would be zero, FALSE otherwise.
--*/
{
RTL_REFERENCE_COUNT NewValue;
RTL_REFERENCE_COUNT OldValue;
PrefetchForWrite(RefCount);
OldValue = ReadLongPtrNoFence(RefCount);
for (;;) {
NewValue = OldValue - Bias;
if (NewValue > 0) {
//
// A release fence is required to ensure all guarded memory
// accesses are complete before any thread can begin destroying
// the object.
//
NewValue = RtlCompareExchangeLongPtrRelease(RefCount,
NewValue,
OldValue);
if (NewValue == OldValue) {
return FALSE;
}
OldValue = NewValue;
} else if (NewValue == 0) {
return TRUE;
} else {
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
}
}
}
#undef RtlIncrementLongPtrNoFence
#undef RtlDecrementLongPtrRelease
#undef RtlExchangeAddLongPtrNoFence
#undef RtlExchangeAddLongPtrRelease
#undef RtlCompareExchangeLongPtrNoFence
#undef RtlCompareExchangeLongPtrRelease
#undef RtlBarrierAfterInterlock
+413
View File
@@ -0,0 +1,413 @@
/*
* 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 "precomp.h"
#include "address.tmh"
_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
otLwfOnAddressAdded(
_In_ PMS_FILTER pFilter,
_In_ const otNetifAddress* Addr,
_In_ BOOLEAN UpdateWindows
)
{
if (pFilter->otCachedAddrCount >= OT_MAX_ADDRESSES)
{
LogError(DRIVER_DEFAULT, "Failing to add new address as we have reached our max!");
return FALSE;
}
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! adding address: %!IPV6ADDR! (%u-bit prefix)",
&pFilter->InterfaceGuid,
(PIN6_ADDR)&Addr->mAddress,
Addr->mPrefixLength
);
// Update local cache
memcpy(pFilter->otCachedAddr + pFilter->otCachedAddrCount, Addr, sizeof(IN6_ADDR));
pFilter->otCachedAddrCount++;
// If this is link local, cache it as our link local address
if (IN6_IS_ADDR_LINKLOCAL((PIN6_ADDR)&Addr->mAddress))
{
memcpy(&pFilter->otLinkLocalAddr, Addr, sizeof(IN6_ADDR));
}
// Update Windows if necessary
if (UpdateWindows)
{
NTSTATUS status;
MIB_UNICASTIPADDRESS_ROW newRow;
MIB_IPFORWARD_ROW2 newRouteRow;
COMPARTMENT_ID OriginalCompartmentID;
InitializeUnicastIpAddressEntry(&newRow);
InitializeIpForwardEntry(&newRouteRow);
newRow.InterfaceIndex = pFilter->InterfaceIndex;
newRow.InterfaceLuid = pFilter->InterfaceLuid;
newRow.Address.si_family = AF_INET6;
newRow.Address.Ipv6.sin6_family = AF_INET6;
static_assert(sizeof(IN6_ADDR) == sizeof(otIp6Address), "Windows and OpenThread IPv6 Addr Structs must be same size");
memcpy(&newRow.Address.Ipv6.sin6_addr, &Addr->mAddress, sizeof(IN6_ADDR));
newRow.OnLinkPrefixLength = Addr->mPrefixLength;
newRow.PreferredLifetime = Addr->mPreferredLifetime;
newRow.ValidLifetime = Addr->mValidLifetime;
newRow.PrefixOrigin = IpPrefixOriginOther; // Derived from network XPANID
newRow.SkipAsSource = FALSE; // Allow automatic binding to this address (default)
if (IN6_IS_ADDR_LINKLOCAL(&newRow.Address.Ipv6.sin6_addr))
{
newRow.SuffixOrigin = IpSuffixOriginLinkLayerAddress; // Derived from Extended MAC address
}
else
{
newRow.SuffixOrigin = IpSuffixOriginRandom; // Was created randomly
}
// Make sure we are in the right compartment
(VOID)otLwfSetCompartment(pFilter, &OriginalCompartmentID);
status = CreateUnicastIpAddressEntry(&newRow);
//NT_ASSERT(NT_SUCCESS(status));
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "CreateUnicastIpAddressEntry failed %!STATUS!", status);
}
newRouteRow.InterfaceIndex = pFilter->InterfaceIndex;
newRouteRow.InterfaceLuid = pFilter->InterfaceLuid;
newRouteRow.DestinationPrefix.Prefix.si_family = AF_INET6;
newRouteRow.DestinationPrefix.PrefixLength = 0;
status = CreateIpForwardEntry2(&newRouteRow);
if (!NT_SUCCESS(status) && status != STATUS_DUPLICATE_OBJECTID)
{
LogVerbose(DRIVER_DEFAULT, "CreateIpForwardEntry2 failed %!STATUS!", status);
}
// Revert back to original compartment
otLwfRevertCompartment(OriginalCompartmentID);
}
return TRUE;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfOnAddressRemoved(
_In_ PMS_FILTER pFilter,
_In_ ULONG CachedIndex,
_In_ BOOLEAN UpdateWindows
)
{
// Cache address before we delete local cache
IN6_ADDR Addr = pFilter->otCachedAddr[CachedIndex];
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! removing address: %!IPV6ADDR!", &pFilter->InterfaceGuid, &Addr);
NT_ASSERT(pFilter->otCachedAddrCount != 0);
NT_ASSERT(CachedIndex < pFilter->otCachedAddrCount);
// Remove the cached entry
if (CachedIndex + 1 != pFilter->otCachedAddrCount)
memmove(pFilter->otCachedAddr + CachedIndex,
pFilter->otCachedAddr + CachedIndex + 1,
(pFilter->otCachedAddrCount - CachedIndex - 1) * sizeof(IN6_ADDR)
);
pFilter->otCachedAddrCount--;
// Update Windows if necessary
if (UpdateWindows)
{
MIB_UNICASTIPADDRESS_ROW deleteRow;
COMPARTMENT_ID OriginalCompartmentID;
InitializeUnicastIpAddressEntry(&deleteRow);
deleteRow.InterfaceIndex = pFilter->InterfaceIndex;
deleteRow.InterfaceLuid = pFilter->InterfaceLuid;
deleteRow.Address.si_family = AF_INET6;
deleteRow.Address.Ipv6.sin6_addr = Addr;
// Make sure we are in the right compartment
(VOID)otLwfSetCompartment(pFilter, &OriginalCompartmentID);
// Best effort remove address from TCPIP
(VOID)DeleteUnicastIpAddressEntry(&deleteRow);
// Revert back to original compartment
otLwfRevertCompartment(OriginalCompartmentID);
}
}
int
otLwfFindCachedAddrIndex(
_In_ PMS_FILTER pFilter,
_In_ PIN6_ADDR addr
)
{
for (ULONG i = 0; i < pFilter->otCachedAddrCount; i++)
if (memcmp(pFilter->otCachedAddr + i, addr, sizeof(IN6_ADDR)) == 0)
return (int)i;
return -1;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfInitializeAddresses(
_In_ PMS_FILTER pFilter
)
{
NTSTATUS status = STATUS_SUCCESS;
PMIB_UNICASTIPADDRESS_TABLE pMibUnicastAddressTable = NULL;
COMPARTMENT_ID OriginalCompartmentID;
LogFuncEntry(DRIVER_DEFAULT);
pFilter->otCachedAddrCount = 0;
// Make sure we are in the right compartment
(VOID)otLwfSetCompartment(pFilter, &OriginalCompartmentID);
// Query the table for the current compartment
status = GetUnicastIpAddressTable(AF_INET6, &pMibUnicastAddressTable);
// Revert the compartment, now that we have the table
otLwfRevertCompartment(OriginalCompartmentID);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "GetUnicastIpAddressTable failed, %!STATUS!", status);
goto error;
}
// Iterate through the addresses and delete (best effort) the ones for our interface
for (ULONG Index = 0; Index < pMibUnicastAddressTable->NumEntries; Index++)
{
MIB_UNICASTIPADDRESS_ROW* row = &pMibUnicastAddressTable->Table[Index];
if ((0 == memcmp(&row->InterfaceLuid, &pFilter->InterfaceLuid, sizeof(NET_LUID))))
{
LogInfo(DRIVER_DEFAULT, "Caching initial address: %!IPV6ADDR!", &row->Address.Ipv6.sin6_addr);
memcpy(pFilter->otCachedAddr + pFilter->otCachedAddrCount, &row->Address.Ipv6.sin6_addr, sizeof(IN6_ADDR));
pFilter->otCachedAddrCount++;
}
}
error:
if (NULL != pMibUnicastAddressTable)
{
FreeMibTable(pMibUnicastAddressTable);
}
LogFuncExitNT(DRIVER_DEFAULT, status);
return status;
}
// Callback from Windows TCPIP stack when an address change occurs
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
NETIOAPI_API_
otLwfAddressChangeCallback(
_In_ PVOID CallerContext,
_In_opt_ PMIB_UNICASTIPADDRESS_ROW Row,
_In_ MIB_NOTIFICATION_TYPE NotificationType
)
{
PMS_FILTER pFilter = (PMS_FILTER)CallerContext;
if (Row == NULL || pFilter == NULL) return;
// Ignore notifications that aren't for our interface
if (Row->InterfaceIndex != pFilter->InterfaceIndex) return;
LogFuncEntryMsg(DRIVER_DEFAULT, "%p (%u)", pFilter, NotificationType);
// Since we don't pass in the initial flag, we shouldn't get this type
NT_ASSERT(NotificationType != MibInitialNotification);
// Queue up the event for processing
otLwfEventProcessingIndicateAddressChange(
pFilter,
NotificationType,
&Row->Address.Ipv6.sin6_addr
);
LogFuncExit(DRIVER_DEFAULT);
}
// Callback on the OpenThread thread for processing an address change
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingAddressChanged(
_In_ PMS_FILTER pFilter,
_In_ MIB_NOTIFICATION_TYPE NotificationType,
_In_ PIN6_ADDR pAddr
)
{
LogFuncEntryMsg(DRIVER_DEFAULT, "%p (%u)", pFilter, NotificationType);
if (NotificationType == MibAddInstance ||
NotificationType == MibParameterNotification)
{
MIB_UNICASTIPADDRESS_ROW Row;
InitializeUnicastIpAddressEntry(&Row);
Row.Address.si_family = AF_INET6;
Row.Address.Ipv6.sin6_addr = *pAddr;
Row.InterfaceIndex = pFilter->InterfaceIndex;
Row.InterfaceLuid = pFilter->InterfaceLuid;
NTSTATUS status = GetUnicastIpAddressEntry(&Row);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "GetUnicastIpAddressEntry failed, %!STATUS!", status);
}
else
{
otNetifAddress otAddr = {0};
memcpy(&otAddr.mAddress, pAddr, sizeof(IN6_ADDR));
otAddr.mPreferredLifetime = Row.PreferredLifetime;
otAddr.mPrefixLength = Row.OnLinkPrefixLength;
otAddr.mValidLifetime = Row.ValidLifetime;
BOOLEAN ShouldDelete = FALSE;
BOOLEAN AddedToCache = FALSE;
BOOLEAN IsCached = otLwfFindCachedAddrIndex(pFilter, pAddr) != -1;
// Ignore link local addresses
if (IN6_IS_ADDR_LINKLOCAL(pAddr) && !IsCached)
{
ShouldDelete = TRUE;
goto add_complete;
}
// Add to the cache if this is a new address
if (NotificationType == MibAddInstance && !IsCached)
{
AddedToCache = otLwfOnAddressAdded(pFilter, &otAddr, FALSE);
if (AddedToCache == FALSE)
{
ShouldDelete = TRUE;
goto add_complete;
}
}
// Update OpenThread if we don't have this cached or it is being updated
if (!IsCached/* || NotificationType == MibParameterNotification*/)
{
LogInfo(DRIVER_DEFAULT, "Filter %p trying to add/update address: %!IPV6ADDR!", pFilter, pAddr);
// Add (or update) the address to OpenThread
ThreadError otError = otAddUnicastAddress(pFilter->otCtx, &otAddr);
if (otError != kThreadError_None)
{
LogError(DRIVER_DEFAULT, "otAddUnicastAddress failed, %!otError!", otError);
ShouldDelete = otError == kThreadError_NoBufs ? TRUE : FALSE;
}
}
add_complete:
// Remove it from TCPIP if necessary
if (ShouldDelete)
{
LogInfo(DRIVER_DEFAULT, "Filter %p deleting recently added address: %!IPV6ADDR!", pFilter, pAddr);
// Best effort remove address from TCPIP
(VOID)DeleteUnicastIpAddressEntry(&Row);
}
}
}
else if (NotificationType == MibDeleteInstance)
{
// Look for the address in our cache
int index = otLwfFindCachedAddrIndex(pFilter, pAddr);
// If it's not already deleted from our cache, then Windows
// is deleting the adddress and we need to update OpenThread.
if (index != -1)
{
// Update our cache
otLwfOnAddressRemoved(pFilter, (ULONG)index, FALSE);
LogInfo(DRIVER_DEFAULT, "Filter %p trying to remove address: %!IPV6ADDR!", pFilter, pAddr);
// Find the correct address from OpenThread to remove (best effort)
(void)otRemoveUnicastAddress(pFilter->otCtx, (otIp6Address*)pAddr);
}
}
LogFuncExit(DRIVER_DEFAULT);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfAddressesUpdated(
_In_ PMS_FILTER pFilter
)
{
LogFuncEntry(DRIVER_DEFAULT);
ULONG FoundInOpenThread = 0; // Bit field
ULONG OriginalCacheLength = pFilter->otCachedAddrCount;
const otNetifAddress* addr = otGetUnicastAddresses(pFilter->otCtx);
// Process the addresses
while (addr)
{
int index = otLwfFindCachedAddrIndex(pFilter, (PIN6_ADDR)&addr->mAddress);
if (index == -1)
{
otLwfOnAddressAdded(pFilter, addr, TRUE);
}
else
{
NT_ASSERT(index < 8 * sizeof(FoundInOpenThread));
FoundInOpenThread |= 1 << index;
}
addr = addr->mNext;
}
// Look for missing addresses and mark them as removed
for (int i = OriginalCacheLength - 1; i >= 0; i--)
{
if ((FoundInOpenThread & (1 << i)) == 0)
{
otLwfOnAddressRemoved(pFilter, (ULONG)i, TRUE);
}
}
LogFuncExit(DRIVER_DEFAULT);
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file implements the alarm functions required for the OpenThread library.
*/
#include "precomp.h"
#include "alarm.tmh"
uint32_t
otPlatAlarmGetNow()
{
// Return number of 'ticks'
LARGE_INTEGER PerformanceCounter = KeQueryPerformanceCounter(NULL);
// Multiply by 1000 ms/sec and divide by 'ticks'/sec to get ms
return (uint32_t)(PerformanceCounter.QuadPart * 1000 / FilterPerformanceFrequency.QuadPart);
}
void
otPlatAlarmStop(
_In_ otInstance *otCtx
)
{
LogVerbose(DRIVER_DEFAULT, "otPlatAlarmStop");
otLwfEventProcessingIndicateNewWaitTime(otCtxToFilter(otCtx), (ULONG)(-1));
}
void
otPlatAlarmStartAt(
_In_ otInstance *otCtx,
uint32_t now,
uint32_t waitTime
)
{
UNREFERENCED_PARAMETER(now);
LogVerbose(DRIVER_DEFAULT, "otPlatAlarmStartAt %u ms", waitTime);
otLwfEventProcessingIndicateNewWaitTime(otCtxToFilter(otCtx), waitTime);
}
+586
View File
@@ -0,0 +1,586 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file implements the functions required for handling NetBufferLists in
* the data path.
*/
#include "precomp.h"
#include "datapath.tmh"
#ifdef LOG_BUFFERS
__forceinline CHAR ToHex(CHAR n)
{
if (n > 9) return 'A' + (n - 10);
else return '0' + n;
}
#define otLogLineLength 32
// Helper to log a buffer
void
otLogBuffer(
_In_reads_bytes_(BufferLength) PUCHAR Buffer,
_In_ ULONG BufferLength
)
{
ULONG index = 0;
while (index < BufferLength)
{
CHAR szBuffer[otLogLineLength * 4] = " ";
PCHAR buf = szBuffer + 2;
for (ULONG i = 0; i < otLogLineLength && i + index < BufferLength; i++)
{
buf[0] = ToHex(Buffer[i + index] >> 4);
buf[1] = ToHex(Buffer[i + index] & 0x0F);
buf[2] = ' ';
buf += 3;
}
buf[0] = 0;
LogVerbose(DRIVER_DATA_PATH, "%s", szBuffer);
index += otLogLineLength;
}
}
#endif
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEnableDataPath(
_In_ PMS_FILTER pFilter
)
/*++
Routine Description:
Enables the datapath to allow NLBs to go through to OpenThread.
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! enabling data path.", &pFilter->InterfaceGuid);
// Re-enabling data path
ExReInitializeRundownProtection(&pFilter->DataPathRundown);
LogFuncExit(DRIVER_DEFAULT);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfDisableDataPath(
_In_ PMS_FILTER pFilter
)
/*++
Routine Description:
Disables the datapath and waits for any outstanding calls
into OpenThread to complete.
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! disabling data path.", &pFilter->InterfaceGuid);
ExWaitForRundownProtectionRelease(&pFilter->DataPathRundown);
LogFuncExit(DRIVER_DEFAULT);
}
_Use_decl_annotations_
VOID
FilterSendNetBufferListsComplete(
NDIS_HANDLE FilterModuleContext,
PNET_BUFFER_LIST NetBufferLists,
ULONG SendCompleteFlags
)
/*++
Routine Description:
Send complete handler
This routine is invoked whenever the lower layer is finished processing
sent NET_BUFFER_LISTs. If the filter does not need to be involved in the
send path, you should remove this routine and the FilterSendNetBufferLists
routine. NDIS will pass along send packets on behalf of your filter more
efficiently than the filter can.
Arguments:
FilterModuleContext - our filter context
NetBufferLists - a chain of NBLs that are being returned to you
SendCompleteFlags - flags (see documentation)
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
UNREFERENCED_PARAMETER(SendCompleteFlags);
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p, NBL: %p", FilterModuleContext, NetBufferLists);
NT_ASSERT(NetBufferLists == pFilter->SendNetBufferList);
NT_ASSERT(kStateTransmit == pFilter->otPhyState);
KeSetEvent(&pFilter->SendNetBufferListComplete, 0, FALSE);
LogFuncExit(DRIVER_DATA_PATH);
}
_Use_decl_annotations_
VOID
FilterSendNetBufferLists(
NDIS_HANDLE FilterModuleContext,
PNET_BUFFER_LIST NetBufferLists,
NDIS_PORT_NUMBER PortNumber,
ULONG SendFlags
)
/*++
Routine Description:
Send Net Buffer List handler
This function is an optional function for filter drivers. If provided, NDIS
will call this function to transmit a linked list of NetBuffers, described by a
NetBufferList, over the network. If this handler is NULL, NDIS will skip calling
this filter when sending a NetBufferList and will call the next lower
driver in the stack. A filter that doesn't provide a FilerSendNetBufferList
handler can not originate a send on its own.
Arguments:
FilterModuleContext - our filter context area
NetBufferLists - a List of NetBufferLists to send
PortNumber - Port Number to which this send is targeted
SendFlags - specifies if the call is at DISPATCH_LEVEL
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
BOOLEAN DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p, NBL: %p", FilterModuleContext, NetBufferLists);
// Try to grab a ref on the data path first, to make sure we are allowed
if (!ExAcquireRundownProtection(&pFilter->DataPathRundown))
{
LogVerbose(DRIVER_DEFAULT, "Failing SendNetBufferLists because data path isn't active.");
// Ignore any NBLs we get if we aren't active (can't get a ref)
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
while (CurrNbl)
{
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
NdisFSendNetBufferListsComplete(
pFilter->FilterHandle,
NetBufferLists,
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0
);
}
else
{
// Indicate a new NBL to process on our worker thread
otLwfEventProcessingIndicateNewNetBufferLists(
pFilter,
DispatchLevel,
FALSE,
PortNumber,
NetBufferLists
);
// Release the data path ref now
ExReleaseRundownProtection(&pFilter->DataPathRundown);
}
LogFuncExit(DRIVER_DATA_PATH);
}
_Use_decl_annotations_
VOID
FilterReturnNetBufferLists(
NDIS_HANDLE FilterModuleContext,
PNET_BUFFER_LIST NetBufferLists,
ULONG ReturnFlags
)
/*++
Routine Description:
FilterReturnNetBufferLists handler.
FilterReturnNetBufferLists is an optional function. If provided, NDIS calls
FilterReturnNetBufferLists to return the ownership of one or more NetBufferLists
and their embedded NetBuffers to the filter driver. If this handler is NULL, NDIS
will skip calling this filter when returning NetBufferLists to the underlying
miniport and will call the next lower driver in the stack. A filter that doesn't
provide a FilterReturnNetBufferLists handler cannot originate a receive indication
on its own.
Arguments:
FilterInstanceContext - our filter context area
NetBufferLists - a linked list of NetBufferLists that this
filter driver indicated in a previous call to
NdisFIndicateReceiveNetBufferLists
ReturnFlags - flags specifying if the caller is at DISPATCH_LEVEL
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
UNREFERENCED_PARAMETER(ReturnFlags);
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p, NBL: %p", pFilter, NetBufferLists);
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
while (CurrNbl)
{
if (!NT_SUCCESS(CurrNbl->Status))
{
LogVerbose(DRIVER_DATA_PATH, "NBL failed on return: %!STATUS!", CurrNbl->Status);
}
PNET_BUFFER_LIST NblToFree = CurrNbl;
PNET_BUFFER NbToFree = NET_BUFFER_LIST_FIRST_NB(NblToFree);
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
NET_BUFFER_LIST_NEXT_NBL(NblToFree) = NULL;
NdisAdvanceNetBufferDataStart(NbToFree, NET_BUFFER_DATA_LENGTH(NbToFree), TRUE, NULL);
NdisFreeNetBufferList(NblToFree);
}
LogFuncExit(DRIVER_DATA_PATH);
}
_Use_decl_annotations_
VOID
FilterReceiveNetBufferLists(
NDIS_HANDLE FilterModuleContext,
PNET_BUFFER_LIST NetBufferLists,
NDIS_PORT_NUMBER PortNumber,
ULONG NumberOfNetBufferLists,
ULONG ReceiveFlags
)
/*++
Routine Description:
FilerReceiveNetBufferLists is an optional function for filter drivers.
If provided, this function processes receive indications made by underlying
NIC or lower level filter drivers. This function can also be called as a
result of loopback. If this handler is NULL, NDIS will skip calling this
filter when processing a receive indication and will call the next higher
driver in the stack. A filter that doesn't provide a
FilterReceiveNetBufferLists handler cannot provide a
FilterReturnNetBufferLists handler and cannot a initiate an original receive
indication on its own.
Arguments:
FilterModuleContext - our filter context area.
NetBufferLists - a linked list of NetBufferLists
PortNumber - Port on which the receive is indicated
ReceiveFlags -
N.B.: It is important to check the ReceiveFlags in NDIS_TEST_RECEIVE_CANNOT_PEND.
This controls whether the receive indication is an synchronous or
asynchronous function call.
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
BOOLEAN DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p, NBL: %p", FilterModuleContext, NetBufferLists);
ASSERT(NumberOfNetBufferLists >= 1);
UNREFERENCED_PARAMETER(NumberOfNetBufferLists);
// We don't support non-pending NBLs
NT_ASSERT(NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags));
if (NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags))
{
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
while (CurrNbl)
{
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_NOT_SUPPORTED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
}
// Try to grab a ref on the data path first, to make sure we are allowed
else if(pFilter->otPhyState == kStateDisabled || !ExAcquireRundownProtection(&pFilter->DataPathRundown))
{
LogVerbose(DRIVER_DATA_PATH, "Failing ReceiveNetBufferLists because data path isn't active.");
// Ignore any NBLs we get if we aren't active (can't get a ref)
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
while (CurrNbl)
{
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
NdisFReturnNetBufferLists(
pFilter->FilterHandle,
NetBufferLists,
DispatchLevel ? NDIS_RETURN_FLAGS_DISPATCH_LEVEL : 0
);
}
else
{
#if DBG
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
while (CurrNbl)
{
POT_NBL_CONTEXT NblContext = GetNBLContext(CurrNbl);
NT_ASSERT(NblContext->Channel >= 11 && NblContext->Channel <= 26);
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
#endif
// Indicate a new NBL to process on our worker thread
otLwfEventProcessingIndicateNewNetBufferLists(
pFilter,
DispatchLevel,
TRUE,
PortNumber,
NetBufferLists
);
// Release the data path ref now
ExReleaseRundownProtection(&pFilter->DataPathRundown);
}
LogFuncExit(DRIVER_DATA_PATH);
}
_Use_decl_annotations_
VOID
FilterCancelSendNetBufferLists(
NDIS_HANDLE FilterModuleContext,
PVOID CancelId
)
/*++
Routine Description:
This function cancels any NET_BUFFER_LISTs pended in the filter and then
calls the NdisFCancelSendNetBufferLists to propagate the cancel operation.
If your driver does not queue any send NBLs, you may omit this routine.
NDIS will propagate the cancelation on your behalf more efficiently.
Arguments:
FilterModuleContext - our filter context area.
CancelId - an identifier for all NBLs that should be dequeued
*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p, CancelId: %p", FilterModuleContext, CancelId);
otLwfEventProcessingIndicateNetBufferListsCancelled(pFilter, CancelId);
LogFuncExit(DRIVER_DATA_PATH);
}
#pragma pack(push)
#pragma pack(1)
typedef struct UDPHeader
{
USHORT SourcePort;
USHORT DestinationPort;
USHORT TotalLength;
USHORT Checksum;
} UDPHeader;
#pragma pack(pop)
// Callback received from OpenThread when it has an IPv6 packet ready for
// delivery to TCPIP.
void
otLwfReceiveIp6DatagramCallback(
_In_ otMessage aMessage,
_In_ void *aContext
)
{
PMS_FILTER pFilter = (PMS_FILTER)aContext;
uint16_t messageLength = otGetMessageLength(aMessage);
PNET_BUFFER_LIST NetBufferList = NULL;
PNET_BUFFER NetBuffer = NULL;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PUCHAR DataBuffer = NULL;
int BytesRead = 0;
IPV6_HEADER* v6Header;
#ifdef FORCE_SYNCHRONOUS_RECEIVE
KIRQL irql;
#endif
// Create the NetBufferList
NetBufferList =
NdisAllocateNetBufferAndNetBufferList(
pFilter->NetBufferListPool, // PoolHandle
0, // ContextSize
0, // ContextBackFill
NULL, // MdlChain
0, // DataOffset
0 // DataLength
);
if (NetBufferList == NULL)
{
LogWarning(DRIVER_DEFAULT, "Failed to create Recv NetBufferList");
goto error;
}
// Set the flag to indicate its a IPv6 packet
NdisSetNblFlag(NetBufferList, NDIS_NBL_FLAGS_IS_IPV6);
NET_BUFFER_LIST_INFO(NetBufferList, NetBufferListFrameType) =
UlongToPtr(RtlUshortByteSwap(ETHERNET_TYPE_IPV6));
// Initialize NetBuffer fields
NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
NET_BUFFER_CURRENT_MDL(NetBuffer) = NULL;
NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer) = 0;
NET_BUFFER_DATA_LENGTH(NetBuffer) = 0;
NET_BUFFER_DATA_OFFSET(NetBuffer) = 0;
NET_BUFFER_FIRST_MDL(NetBuffer) = NULL;
// Allocate the NetBuffer for SendNetBufferList
Status = NdisRetreatNetBufferDataStart(NetBuffer, messageLength, 0, NULL);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeNetBufferList(NetBufferList);
LogError(DRIVER_DEFAULT, "Failed to allocate NB for Recv NetBufferList, %!NDIS_STATUS!", Status);
goto error;
}
// Get the data buffer to write to
DataBuffer = NdisGetDataBuffer(NetBuffer, messageLength, NULL, 1, 0);
NT_ASSERT(DataBuffer);
if (DataBuffer == NULL)
{
NdisAdvanceNetBufferDataStart(NetBuffer, messageLength, TRUE, NULL);
NdisFreeNetBufferList(NetBufferList);
LogError(DRIVER_DEFAULT, "Failed to get contiguous data buffer for Recv NetBufferList");
goto error;
}
// Read the bytes to the buffer
BytesRead = otReadMessage(aMessage, 0, DataBuffer, messageLength);
NT_ASSERT(BytesRead == (int)messageLength);
if (BytesRead != (int)messageLength)
{
NdisAdvanceNetBufferDataStart(NetBuffer, messageLength, TRUE, NULL);
NdisFreeNetBufferList(NetBufferList);
LogError(DRIVER_DEFAULT, "Failed to read message buffer for Recv NetBufferList");
goto error;
}
v6Header = (IPV6_HEADER*)DataBuffer;
// Filter messages to addresses we expose
if (!IN6_IS_ADDR_MULTICAST(&v6Header->DestinationAddress) &&
otLwfFindCachedAddrIndex(pFilter, &v6Header->DestinationAddress) == -1)
{
NdisAdvanceNetBufferDataStart(NetBuffer, messageLength, TRUE, NULL);
NdisFreeNetBufferList(NetBufferList);
LogVerbose(DRIVER_DATA_PATH, "Filter: %p dropping internal address message.", pFilter);
goto error;
}
// Filter internal Thread messages
if (v6Header->NextHeader == IPPROTO_UDP &&
messageLength >= sizeof(IPV6_HEADER) + sizeof(UDPHeader) &&
memcmp(&pFilter->otLinkLocalAddr, &v6Header->DestinationAddress, sizeof(IN6_ADDR)) == 0)
{
// Check for MLE message
UDPHeader* UdpHeader = (UDPHeader*)(v6Header + 1);
if (UdpHeader->DestinationPort == UdpHeader->SourcePort &&
UdpHeader->DestinationPort == RtlUshortByteSwap(19788)) // MLE Port
{
NdisAdvanceNetBufferDataStart(NetBuffer, messageLength, TRUE, NULL);
NdisFreeNetBufferList(NetBufferList);
LogVerbose(DRIVER_DATA_PATH, "Filter: %p dropping MLE message.", pFilter);
goto error;
}
}
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, IP6_RECV: %p : %!IPV6ADDR! => %!IPV6ADDR! (%u bytes)",
pFilter, NetBufferList, &v6Header->SourceAddress, &v6Header->DestinationAddress,
messageLength);
#ifdef LOG_BUFFERS
otLogBuffer(DataBuffer, messageLength);
#endif
#ifdef FORCE_SYNCHRONOUS_RECEIVE
irql = KfRaiseIrql(DISPATCH_LEVEL);
if (messageLength == 248) // Magic length used for TAEF test packets
{
DbgBreakPoint();
}
#endif
// Indicate the NBL up
NdisFIndicateReceiveNetBufferLists(
pFilter->FilterHandle,
NetBufferList,
NDIS_DEFAULT_PORT_NUMBER,
1,
#ifdef FORCE_SYNCHRONOUS_RECEIVE
NDIS_RECEIVE_FLAGS_RESOURCES | NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL
#else
0
#endif
);
#ifdef FORCE_SYNCHRONOUS_RECEIVE
KeLowerIrql(irql);
FilterReturnNetBufferLists(pFilter, NetBufferList, 0);
#endif
error:
otFreeMessage(aMessage);
}
+696
View File
@@ -0,0 +1,696 @@
/*
* 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 "precomp.h"
#include "device.tmh"
// IoControl Device Object from IoCreateDeviceSecure
PDEVICE_OBJECT IoDeviceObject = NULL;
// Global context for device control callbacks
POTLWF_DEVICE_EXTENSION FilterDeviceExtension = NULL;
/*
Powershell script to generate security desciptors:
$sddl = "D:P(A;;GA;;;SY)(A;;GA;;;NS)(A;;GA;;;BA)(A;;GA;;;WD)(A;;GA;;;S-1-15-3-3)"
$blob = ([wmiclass]"Win32_SecurityDescriptorHelper").SDDLToBinarySD($sddl).BinarySD
$string = [BitConverter]::ToString($blob)
$string = $string -replace '-', ''
$string = $string -replace '(..)(..)(..)(..)', '0x$4$3$2$1, '
$string -replace '(.{10}, .{10}, .{10}, .{10},) ', "$&`n"
*/
const unsigned long c_sdThreadLwf[] =
{
0x90040001, 0x00000000, 0x00000000, 0x00000000,
0x00000014, 0x00740002, 0x00000005, 0x00140000,
0x10000000, 0x00000101, 0x05000000, 0x00000012,
0x00140000, 0x10000000, 0x00000101, 0x05000000,
0x00000014, 0x00180000, 0x10000000, 0x00000201,
0x05000000, 0x00000020, 0x00000220, 0x00140000,
0x10000000, 0x00000101, 0x01000000, 0x00000000,
0x00180000, 0x10000000, 0x00000201, 0x0F000000,
0x00000003, 0x00000003
};
_No_competing_thread_
INITCODE
NDIS_STATUS
otLwfRegisterDevice(
VOID
)
{
NTSTATUS Status = NDIS_STATUS_SUCCESS;
UNICODE_STRING DeviceName;
UNICODE_STRING DeviceLinkUnicodeString;
PDEVICE_OBJECT DeviceObject;
LogFuncEntry(DRIVER_DEFAULT);
NT_ASSERT(FilterDeviceExtension == NULL);
NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);
Status = IoCreateDeviceSecure(FilterDriverObject, // DriverObject
sizeof(OTLWF_DEVICE_EXTENSION), // DeviceExtension
&DeviceName, // DeviceName
FILE_DEVICE_NETWORK, // DeviceType
FILE_DEVICE_SECURE_OPEN, // DeviceCharacteristics
FALSE, // Exclusive
&SDDL_DEVOBJ_KERNEL_ONLY, // security attributes
NULL, // security override device class
&DeviceObject); // DeviceObject
if (NT_SUCCESS(Status))
{
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
Status = IoCreateSymbolicLink(&DeviceLinkUnicodeString, &DeviceName);
if (!NT_SUCCESS(Status))
{
LogError(DRIVER_DEFAULT, "IoCreateSymbolicLink failed, %!STATUS!", Status);
IoDeleteDevice(DeviceObject);
}
else
{
FilterDeviceExtension = (POTLWF_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
RtlZeroMemory(FilterDeviceExtension, sizeof(OTLWF_DEVICE_EXTENSION));
FilterDeviceExtension->Signature = 'FTDR';
FilterDeviceExtension->Handle = FilterDriverHandle;
NdisAllocateSpinLock(&FilterDeviceExtension->Lock);
InitializeListHead(&FilterDeviceExtension->ClientList);
#pragma push
#pragma warning(disable:28168) // The function 'otLwfDispatch' does not have a _Dispatch_type_ annotation matching dispatch table position *
FilterDriverObject->MajorFunction[IRP_MJ_CREATE] = otLwfDispatch;
FilterDriverObject->MajorFunction[IRP_MJ_CLEANUP] = otLwfDispatch;
FilterDriverObject->MajorFunction[IRP_MJ_CLOSE] = otLwfDispatch;
FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = otLwfDeviceIoControl;
#pragma pop
HANDLE fileHandle;
Status = ObOpenObjectByPointer(DeviceObject,
OBJ_KERNEL_HANDLE,
NULL,
WRITE_DAC,
0,
KernelMode,
&fileHandle);
if (NT_SUCCESS(Status))
{
Status = ZwSetSecurityObject(fileHandle,
DACL_SECURITY_INFORMATION,
(PSECURITY_DESCRIPTOR)c_sdThreadLwf);
if (!NT_SUCCESS(Status))
{
LogError(DRIVER_DEFAULT, "ZwSetSecurityObject failed, %!STATUS!", Status);
}
ZwClose(fileHandle);
}
else
{
LogError(DRIVER_DEFAULT, "ObOpenObjectByPointer failed, %!STATUS!", Status);
}
IoDeviceObject = DeviceObject;
}
}
else
{
LogError(DRIVER_DEFAULT, "IoCreateDeviceSecure failed, %!STATUS!", Status);
}
LogFuncExitNT(DRIVER_DEFAULT, Status);
return (NDIS_STATUS)Status;
}
PIRP
otLwfDeviceClientCleanup(
POTLWF_DEVICE_CLIENT DeviceClient
)
{
PIRP IrpToCancel = NULL;
// Clean the FileObject context
DeviceClient->FileObject->FsContext2 = NULL;
// Release pending IRP
if (DeviceClient->PendingNotificationIRP)
{
IrpToCancel = DeviceClient->PendingNotificationIRP;
DeviceClient->PendingNotificationIRP = NULL;
}
// Free all pending notifications
for (UCHAR i = 0; i < DeviceClient->NotificationSize; i++)
{
UCHAR index = (DeviceClient->NotificationOffset + i) % OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT;
otLwfReleaseNotification(DeviceClient->PendingNotifications[index]);
}
return IrpToCancel;
}
_No_competing_thread_
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfDeregisterDevice(
VOID
)
{
LogFuncEntry(DRIVER_DEFAULT);
if (IoDeviceObject != NULL)
{
NT_ASSERT(FilterDeviceExtension);
NdisFreeSpinLock(&FilterDeviceExtension->Lock);
// Clean up all pending clients
PLIST_ENTRY Link = FilterDeviceExtension->ClientList.Flink;
while (Link != &FilterDeviceExtension->ClientList)
{
POTLWF_DEVICE_CLIENT DeviceClient = CONTAINING_RECORD(Link, OTLWF_DEVICE_CLIENT, Link);
PIRP IrpToCancel = NULL;
// Set next link
Link = Link->Flink;
// Make sure to clean up any left overs from the device client
IrpToCancel = otLwfDeviceClientCleanup(DeviceClient);
// Complete the pending IRP since we are shutting down
if (IrpToCancel)
{
// Before we are allowed to complete the pending IRP, we must remove the cancel routine
KIRQL irql;
IoAcquireCancelSpinLock(&irql);
IoSetCancelRoutine(IrpToCancel, NULL);
IoReleaseCancelSpinLock(irql);
IrpToCancel->IoStatus.Status = STATUS_CANCELLED;
IrpToCancel->IoStatus.Information = 0;
IoCompleteRequest(IrpToCancel, IO_NO_INCREMENT);
}
// Remove the device client from the list
RemoveEntryList(&DeviceClient->Link);
// Delete the device client
NdisFreeMemory(DeviceClient, 0, 0);
}
IoDeleteDevice(IoDeviceObject);
}
IoDeviceObject = NULL;
LogFuncExit(DRIVER_DEFAULT);
}
_Use_decl_annotations_
NTSTATUS
otLwfDispatch(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
{
PIO_STACK_LOCATION IrpStack;
NTSTATUS Status = STATUS_SUCCESS;
PIRP IrpToCancel = NULL;
POTLWF_DEVICE_CLIENT DeviceClient = NULL;
UNREFERENCED_PARAMETER(DeviceObject);
LogFuncEntry(DRIVER_IOCTL);
IrpStack = IoGetCurrentIrpStackLocation(Irp);
NdisAcquireSpinLock(&FilterDeviceExtension->Lock);
switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:
LogInfo(DRIVER_IOCTL, "Client %p attached.", IrpStack->FileObject);
if (FilterDeviceExtension->ClientListSize >= OTLWF_MAX_CLIENTS)
{
LogError(DRIVER_IOCTL, "Already have max clients!");
Status = STATUS_TOO_MANY_SESSIONS;
break;
}
DeviceClient = FILTER_ALLOC_DEVICE_CLIENT();
if (DeviceClient)
{
RtlZeroMemory(DeviceClient, sizeof(OTLWF_DEVICE_CLIENT));
DeviceClient->FileObject = IrpStack->FileObject;
NT_ASSERT(IrpStack->FileObject->FsContext2 == NULL);
IrpStack->FileObject->FsContext2 = DeviceClient;
// Insert into the client list
InsertTailList(&FilterDeviceExtension->ClientList, &DeviceClient->Link);
FilterDeviceExtension->ClientListSize++;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
break;
case IRP_MJ_CLEANUP:
LogInfo(DRIVER_IOCTL, "Client %p cleaning up.", IrpStack->FileObject);
DeviceClient = (POTLWF_DEVICE_CLIENT)IrpStack->FileObject->FsContext2;
// Make sure to clean up any left overs from the device client
IrpToCancel = otLwfDeviceClientCleanup(DeviceClient);
// Remove the device client from the list
RemoveEntryList(&DeviceClient->Link);
FilterDeviceExtension->ClientListSize--;
// Delete the device client
NdisFreeMemory(DeviceClient, 0, 0);
break;
case IRP_MJ_CLOSE:
LogInfo(DRIVER_IOCTL, "Client %p detatched.", IrpStack->FileObject);
break;
default:
break;
}
NdisReleaseSpinLock(&FilterDeviceExtension->Lock);
// Cancel the pending notification IRP if set
if (IrpToCancel)
{
// Complete the pending IRP
IrpToCancel->IoStatus.Status = STATUS_CANCELLED;
IrpToCancel->IoStatus.Information = 0;
IoCompleteRequest(IrpToCancel, IO_NO_INCREMENT);
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
LogFuncExitNT(DRIVER_IOCTL, Status);
return Status;
}
_Use_decl_annotations_
NTSTATUS
otLwfDeviceIoControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN CompleteIRP = TRUE;
PVOID IoBuffer = Irp->AssociatedIrp.SystemBuffer;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
ULONG InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
ULONG IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
ULONG FuncCode = (IoControlCode >> 2) & 0xFFF;
LogFuncEntryMsg(DRIVER_IOCTL, "%p", IrpSp->FileObject);
#if DBG
ASSERT(((POTLWF_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Signature == 'FTDR');
#else
UNREFERENCED_PARAMETER(DeviceObject);
#endif
// We only allow PASSIVE_LEVEL calls
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
{
LogWarning(DRIVER_IOCTL, "FilterDeviceIoControl called higher than PASSIVE.");
status = STATUS_NOT_SUPPORTED;
RtlZeroMemory(IoBuffer, OutputBufferLength);
OutputBufferLength = 0;
goto error;
}
if (FuncCode >= MIN_OTLWF_IOCTL_FUNC_CODE && FuncCode <= MAX_OTLWF_IOCTL_FUNC_CODE)
{
CompleteIRP = FALSE;
status = otLwfIoCtlOpenThreadControl(Irp);
goto error;
}
// Check the IoControlCode to determine which IOCTL we are processing
switch (IoControlCode)
{
case IOCTL_OTLWF_QUERY_NOTIFICATION:
CompleteIRP = FALSE;
status = otLwfQueryNextNotification(Irp);
break;
case IOCTL_OTLWF_ENUMERATE_DEVICES:
status =
otLwfIoCtlEnumerateInterfaces(
IoBuffer, InputBufferLength,
IoBuffer, &OutputBufferLength
);
break;
case IOCTL_OTLWF_QUERY_DEVICE:
status =
otLwfIoCtlQueryInterface(
IoBuffer, InputBufferLength,
IoBuffer, &OutputBufferLength
);
break;
default:
status = STATUS_NOT_IMPLEMENTED;
RtlZeroMemory(IoBuffer, OutputBufferLength);
OutputBufferLength = 0;
break;
}
error:
if (CompleteIRP)
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = OutputBufferLength;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
LogFuncExitNT(DRIVER_IOCTL, status);
return status;
}
_Use_decl_annotations_
PMS_FILTER
otLwfFindAndRefInterface(
_In_ PGUID InterfaceGuid
)
{
PMS_FILTER pOutput = NULL;
NdisAcquireSpinLock(&FilterListLock);
for (PLIST_ENTRY Link = FilterModuleList.Flink; Link != &FilterModuleList; Link = Link->Flink)
{
PMS_FILTER pFilter = CONTAINING_RECORD(Link, MS_FILTER, FilterModuleLink);
if (pFilter->State == FilterRunning &&
memcmp(InterfaceGuid, &pFilter->InterfaceGuid, sizeof(GUID)) == 0)
{
// Increment ref count on interface
RtlIncrementReferenceCount(&pFilter->IoControlReferences);
pOutput = pFilter;
break;
}
}
NdisReleaseSpinLock(&FilterListLock);
return pOutput;
}
_Use_decl_annotations_
VOID
otLwfReleaseInterface(
_In_ PMS_FILTER pFilter
)
{
// Decrement ref count, and set shutdown event if it goes to 0
if (RtlDecrementReferenceCount(&pFilter->IoControlReferences))
{
NdisSetEvent(&pFilter->IoControlShutdownComplete);
}
}
//
// Notification Functions
//
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfReleaseNotification(
_In_ PFILTER_NOTIFICATION_ENTRY NotifEntry
)
{
if (RtlDecrementReferenceCount(&NotifEntry->RefCount))
{
NdisFreeMemory(NotifEntry, 0, 0);
}
}
// Indicates a new notification
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfIndicateNotification(
_In_ PFILTER_NOTIFICATION_ENTRY NotifEntry
)
{
PIRP IrpsToComplete[OTLWF_MAX_CLIENTS] = {0};
UCHAR IrpOffset = 0;
LogFuncEntry(DRIVER_IOCTL);
// Initialize with a local ref
NotifEntry->RefCount = 1;
if (FilterDeviceExtension == NULL) goto error;
NdisAcquireSpinLock(&FilterDeviceExtension->Lock);
// Pend the notification for each client
PLIST_ENTRY Link = FilterDeviceExtension->ClientList.Flink;
while (Link != &FilterDeviceExtension->ClientList)
{
POTLWF_DEVICE_CLIENT DeviceClient = CONTAINING_RECORD(Link, OTLWF_DEVICE_CLIENT, Link);
// Set next link
Link = Link->Flink;
KIRQL irql;
IoAcquireCancelSpinLock(&irql);
// If there are other pending notifications or we don't have a pending IRP saved
// then just go ahead and add the notification to the list
if (DeviceClient->NotificationSize != 0 ||
DeviceClient->PendingNotificationIRP == NULL
)
{
// Calculate the next index
UCHAR Index = (DeviceClient->NotificationOffset + DeviceClient->NotificationSize) % OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT;
// Add additional ref to the notif
RtlIncrementReferenceCount(&NotifEntry->RefCount);
// If we are at the max already, release the oldest
if (DeviceClient->NotificationSize == OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT)
{
LogWarning(DRIVER_IOCTL, "Dropping old notification!");
otLwfReleaseNotification(DeviceClient->PendingNotifications[DeviceClient->NotificationOffset]);
}
// Copy the notification to the next space
DeviceClient->PendingNotifications[Index] = NotifEntry;
DeviceClient->NotificationSize++;
}
else
{
// Before we are allowed to complete the pending IRP, we must remove the cancel routine
IoSetCancelRoutine(DeviceClient->PendingNotificationIRP, NULL);
IrpsToComplete[IrpOffset] = DeviceClient->PendingNotificationIRP;
IrpOffset++;
DeviceClient->PendingNotificationIRP = NULL;
}
// Release the cancel spin lock
IoReleaseCancelSpinLock(irql);
}
NdisReleaseSpinLock(&FilterDeviceExtension->Lock);
// Complete any IRPs now, outside the lock
for (UCHAR i = 0; i < IrpOffset; i++)
{
PIRP IrpToComplete = IrpsToComplete[i];
// Copy the notification payload
PVOID IoBuffer = IrpToComplete->AssociatedIrp.SystemBuffer;
memcpy(IoBuffer, &NotifEntry->Notif, sizeof(OTLWF_NOTIFICATION));
IrpToComplete->IoStatus.Information = sizeof(OTLWF_NOTIFICATION);
// Complete the IRP
IrpToComplete->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(IrpToComplete, IO_NO_INCREMENT);
}
error:
// Release local ref on the notification
otLwfReleaseNotification(NotifEntry);
LogFuncExit(DRIVER_IOCTL);
}
DRIVER_CANCEL otLwfQueryNotificationCancelled;
_Use_decl_annotations_
VOID
otLwfQueryNotificationCancelled(
_Inout_ PDEVICE_OBJECT DeviceObject,
_Inout_ _IRQL_uses_cancel_ struct _IRP *Irp
)
{
UNREFERENCED_PARAMETER(DeviceObject);
LogFuncEntry(DRIVER_IOCTL);
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
POTLWF_DEVICE_CLIENT DeviceClient = (POTLWF_DEVICE_CLIENT)IrpSp->FileObject->FsContext2;
if (DeviceClient)
{
DeviceClient->PendingNotificationIRP = NULL;
}
IoReleaseCancelSpinLock(Irp->CancelIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
LogFuncExit(DRIVER_IOCTL);
}
// Queries the next notification
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
otLwfQueryNextNotification(
_In_ PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
POTLWF_DEVICE_CLIENT DeviceClient = NULL;
PFILTER_NOTIFICATION_ENTRY NotifEntry = NULL;
LogFuncEntry(DRIVER_IOCTL);
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
// Validate we have a big enough buffer
if (OutputBufferLength < sizeof(OTLWF_NOTIFICATION))
{
RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, OutputBufferLength);
status = STATUS_INSUFFICIENT_RESOURCES;
goto error;
}
DeviceClient = (POTLWF_DEVICE_CLIENT)IrpSp->FileObject->FsContext2;
if (DeviceClient == NULL)
{
status = STATUS_DEVICE_NOT_READY;
goto error;
}
NdisAcquireSpinLock(&FilterDeviceExtension->Lock);
// Check to see if there are any notifications available
if (DeviceClient->NotificationSize == 0)
{
// Set the cancel routine
IoSetCancelRoutine(Irp, otLwfQueryNotificationCancelled);
// Mark the Irp as pending
IoMarkIrpPending(Irp);
// Save the IRP to complete later, when we have a notification
DeviceClient->PendingNotificationIRP = Irp;
}
else
{
// Get the notification
NotifEntry = DeviceClient->PendingNotifications[DeviceClient->NotificationOffset];
DeviceClient->PendingNotifications[DeviceClient->NotificationOffset] = NULL;
// Increment the offset and decrement the size
DeviceClient->NotificationOffset = (DeviceClient->NotificationOffset + 1) % OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT;
DeviceClient->NotificationSize--;
}
NdisReleaseSpinLock(&FilterDeviceExtension->Lock);
// If we found a notification, complete the IRP with it
if (NotifEntry)
{
// Copy the notification payload
PVOID IoBuffer = Irp->AssociatedIrp.SystemBuffer;
memcpy(IoBuffer, &NotifEntry->Notif, sizeof(OTLWF_NOTIFICATION));
Irp->IoStatus.Information = sizeof(OTLWF_NOTIFICATION);
// Free the notification
otLwfReleaseNotification(NotifEntry);
}
else
{
// Otherwise, set status to indicate we are pending the IRP
status = STATUS_PENDING;
}
error:
// Complete the IRP if we aren't pending
if (status != STATUS_PENDING)
{
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
LogFuncExitNT(DRIVER_IOCTL, status);
return status;
}
+168
View File
@@ -0,0 +1,168 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the functions for managing the device IOCTL interface.
*/
#ifndef _DEVICE_H
#define _DEVICE_H
//
// The filter needs to handle IOCTRLs
//
#define LINKNAME_STRING L"\\DosDevices\\otLwf"
#define NTDEVICE_STRING L"\\Device\\otLwf"
// The maximum number of simultaneous clients supported
#define OTLWF_MAX_CLIENTS 10
// The maximum number of notifications allowed to be pended, per client
#define OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT 100
// Context for IO Device Control callbacks
typedef struct _OTLWF_DEVICE_EXTENSION
{
ULONG Signature;
NDIS_HANDLE Handle;
NDIS_SPIN_LOCK Lock;
_Guarded_by_(Lock)
LIST_ENTRY ClientList;
ULONG ClientListSize;
} OTLWF_DEVICE_EXTENSION, *POTLWF_DEVICE_EXTENSION;
// Notification structure
typedef struct _FILTER_NOTIFICATION_ENTRY
{
RTL_REFERENCE_COUNT RefCount;
OTLWF_NOTIFICATION Notif;
} FILTER_NOTIFICATION_ENTRY, *PFILTER_NOTIFICATION_ENTRY;
// Tag for allocating notification structures 'TNtf
#define FILTER_NOTIF_ALLOC_TAG 'ftNT'
// Helper to allocate a new notification entry
#define FILTER_ALLOC_NOTIF(_pFilter) \
(PFILTER_NOTIFICATION_ENTRY)NdisAllocateMemoryWithTagPriority(_pFilter->FilterHandle, sizeof(FILTER_NOTIFICATION_ENTRY), FILTER_NOTIF_ALLOC_TAG, NormalPoolPriority)
// Context for IO Device Control clients
typedef struct _OTLWF_DEVICE_CLIENT
{
LIST_ENTRY Link;
PFILE_OBJECT FileObject;
PIRP PendingNotificationIRP;
PFILTER_NOTIFICATION_ENTRY PendingNotifications[OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT];
UCHAR NotificationOffset;
UCHAR NotificationSize;
} OTLWF_DEVICE_CLIENT, *POTLWF_DEVICE_CLIENT;
// Helper to allocate a new Device Control client
#define FILTER_ALLOC_DEVICE_CLIENT() \
(POTLWF_DEVICE_CLIENT)NdisAllocateMemoryWithTagPriority(FilterDeviceExtension->Handle, sizeof(OTLWF_DEVICE_CLIENT), FILTER_NOTIF_ALLOC_TAG, NormalPoolPriority)
static_assert(
(1 << (sizeof(UCHAR) * 8)) > OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT,
"Type of NotificationOffset must be big enough for OTLWF_MAX_PENDING_NOTIFICATIONS_PER_CLIENT"
);
// Global context for device control callbacks
extern POTLWF_DEVICE_EXTENSION FilterDeviceExtension;
//
// Function prototypes
//
// Registers for Io Control callbacks
_No_competing_thread_
INITCODE
NDIS_STATUS
otLwfRegisterDevice(
VOID
);
// Unregisters for Io Control Callbacks
_No_competing_thread_
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfDeregisterDevice(
VOID
);
// Callback for general control IRPs
DRIVER_DISPATCH otLwfDispatch;
// Callback for IOCTLs
DRIVER_DISPATCH otLwfDeviceIoControl;
// Attempts to find and add a reference to the Thread interface
_IRQL_requires_max_(PASSIVE_LEVEL)
PMS_FILTER
otLwfFindAndRefInterface(
_In_ PGUID InterfaceGuid
);
// Releases a successfully referenced Thread interface from a previous
// call to otLwfFindAndRefInterface.
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfReleaseInterface(
_In_ PMS_FILTER pFilter
);
//
// Notification Type and Functions
//
// Indicates a new notification
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfIndicateNotification(
_In_ PFILTER_NOTIFICATION_ENTRY NotifEntry
);
// Queries the next notification
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
otLwfQueryNextNotification(
_In_ PIRP Irp
);
// Release a ref on the notification
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfReleaseNotification(
_In_ PFILTER_NOTIFICATION_ENTRY NotifEntry
);
#endif // _DEVICE_H
+241
View File
@@ -0,0 +1,241 @@
/*
* 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 "precomp.h"
#include "driver.tmh"
//
// Global variables
//
// Global Driver Object from DriverEntry
PDRIVER_OBJECT FilterDriverObject = NULL;
// NDIS Filter handle from NdisFRegisterFilterDriver
NDIS_HANDLE FilterDriverHandle = NULL;
// Global list of THREAD_FILTER instances
NDIS_SPIN_LOCK FilterListLock;
LIST_ENTRY FilterModuleList;
// Cached performance frequency of the system
LARGE_INTEGER FilterPerformanceFrequency;
INITCODE
_Use_decl_annotations_
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
First entry point to be called, when this driver is loaded.
Register with NDIS as a filter driver and create a device
for communication with user-mode.
Arguments:
DriverObject - pointer to the system's driver object structure
for this driver
RegistryPath - system's registry path for this driver
Return Value:
STATUS_SUCCESS if all initialization is successful, STATUS_XXX
error code if not.
--*/
{
NDIS_STATUS Status;
NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
NDIS_STRING ServiceName = RTL_CONSTANT_STRING(FILTER_SERVICE_NAME);
NDIS_STRING UniqueName = RTL_CONSTANT_STRING(FILTER_UNIQUE_NAME);
NDIS_STRING FriendlyName = RTL_CONSTANT_STRING(FILTER_FRIENDLY_NAME);
BOOLEAN bFalse = FALSE;
//
// Initialize WPP logging
//
WPP_INIT_TRACING(DriverObject, RegistryPath);
//
// Save global DriverObject
//
FilterDriverObject = DriverObject;
// Cache perf freq
(VOID)KeQueryPerformanceCounter(&FilterPerformanceFrequency);
LogFuncEntry(DRIVER_DEFAULT);
do
{
NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));
FChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
#if NDIS_SUPPORT_NDIS61
FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
#else
FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
#endif
FChars.MajorNdisVersion = NDIS_FILTER_MAJOR_VERSION;
FChars.MinorNdisVersion = NDIS_FILTER_MINOR_VERSION;
FChars.MajorDriverVersion = 1;
FChars.MinorDriverVersion = 0;
FChars.Flags = 0;
FChars.FriendlyName = FriendlyName;
FChars.UniqueName = UniqueName;
FChars.ServiceName = ServiceName;
DriverObject->DriverUnload = DriverUnload;
FChars.AttachHandler = FilterAttach;
FChars.DetachHandler = FilterDetach;
FChars.RestartHandler = FilterRestart;
FChars.PauseHandler = FilterPause;
FChars.StatusHandler = FilterStatus;
FChars.OidRequestHandler = FilterOidRequest;
FChars.OidRequestCompleteHandler = FilterOidRequestComplete;
FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;
FChars.NetPnPEventHandler = FilterNetPnPEvent;
FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;
FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;
FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;
FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;
FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;
//
// Initialize global variables
//
NdisAllocateSpinLock(&FilterListLock);
InitializeListHead(&FilterModuleList);
//
// Register the filter with NDIS
//
FilterDriverHandle = NULL;
Status =
NdisFRegisterFilterDriver(
DriverObject,
(NDIS_HANDLE)FilterDriverObject,
&FChars,
&FilterDriverHandle
);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeSpinLock(&FilterListLock);
LogError(DRIVER_DEFAULT, "Register filter driver failed, %!NDIS_STATUS!", Status);
break;
}
//
// Register the device IOCTL interface
//
Status = otLwfRegisterDevice();
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFDeregisterFilterDriver(FilterDriverHandle);
NdisFreeSpinLock(&FilterListLock);
LogError(DRIVER_DEFAULT, "Register device for the filter driver failed, %!NDIS_STATUS!", Status);
break;
}
} while (bFalse);
LogFuncExitNDIS(DRIVER_DEFAULT, Status);
if (Status != NDIS_STATUS_SUCCESS)
{
WPP_CLEANUP(DriverObject);
}
return Status;
}
PAGEDX
_Use_decl_annotations_
VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Filter driver's unload routine.
Deregister the driver from NDIS.
Arguments:
DriverObject - pointer to the system's driver object structure
for this driver
Return Value:
NONE
--*/
{
PAGED_CODE();
LogFuncEntry(DRIVER_DEFAULT);
//
// Clean up the device IOCTL interface
//
otLwfDeregisterDevice();
//
// Deregister the NDIS filter
//
NdisFDeregisterFilterDriver(FilterDriverHandle);
// Validate we have no outstanding filter instances
NT_ASSERT(IsListEmpty(&FilterModuleList));
//
// Clean up global variables
//
NdisFreeSpinLock(&FilterListLock);
LogFuncExit(DRIVER_DEFAULT);
//
// Clean up WPP logging
//
WPP_CLEANUP(DriverObject);
}
+85
View File
@@ -0,0 +1,85 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the top-level functions and variables for driver initialization
* and clean up.
*/
#ifndef _DRIVER_H
#define _DRIVER_H
// Legal values include:
// 6.0 Available starting with Windows Vista RTM
// 6.1 Available starting with Windows Vista SP1 / Windows Server 2008
// 6.20 Available starting with Windows 7 / Windows Server 2008 R2
// 6.30 Available starting with Windows 8 / Windows Server "8"
#define FILTER_MAJOR_NDIS_VERSION 6
#if defined(NDIS60)
#define FILTER_MINOR_NDIS_VERSION 0
#elif defined(NDIS620)
#define FILTER_MINOR_NDIS_VERSION 20
#elif defined(NDIS630)
#define FILTER_MINOR_NDIS_VERSION 30
#endif
//
// Global variables
//
// Global Driver Object from DriverEntry
extern PDRIVER_OBJECT FilterDriverObject;
// NDIS Filter handle from NdisFRegisterFilterDriver
extern NDIS_HANDLE FilterDriverHandle;
// IoControl Device Object from IoCreateDeviceSecure
extern PDEVICE_OBJECT IoDeviceObject;
// Global list of THREAD_FILTER instances
extern NDIS_SPIN_LOCK FilterListLock;
extern LIST_ENTRY FilterModuleList;
// Cached performance frequency of the system
extern LARGE_INTEGER FilterPerformanceFrequency;
#define FILTER_FRIENDLY_NAME L"OpenThread NDIS LightWeight Filter"
#define FILTER_UNIQUE_NAME L"{B3A3845A-164E-4727-B12E-32B8DCE1F6CD}" //unique name, quid name
#define FILTER_SERVICE_NAME L"OTLWF"
//
// Function prototypes
//
INITCODE DRIVER_INITIALIZE DriverEntry;
PAGEDX DRIVER_UNLOAD DriverUnload;
#endif // _DRIVER_H
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+429
View File
@@ -0,0 +1,429 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the structures and functions for the otLwf Filter instance.
*/
#ifndef _FILT_H
#define _FILT_H
// The maximum allowed addresses an OpenThread interface
#define OT_MAX_ADDRESSES 10
#define OT_MAX_AUTO_ADDRESSES (OT_MAX_ADDRESSES - 4)
#define OTLWF_ALLOC_TAG 'mFto' // otFm
#define FILTER_ALLOC_MEM(_NdisHandle, _Size) \
NdisAllocateMemoryWithTagPriority(_NdisHandle, _Size, OTLWF_ALLOC_TAG, LowPoolPriority)
#define FILTER_FREE_MEM(_pMem) NdisFreeMemory(_pMem, 0, 0)
#define FILTER_INIT_LOCK(_pLock) NdisAllocateSpinLock(_pLock)
#define FILTER_FREE_LOCK(_pLock) NdisFreeSpinLock(_pLock)
// Helper for locking an NDIS lock
#define FILTER_ACQUIRE_LOCK(_pLock, DispatchLevel) \
{ \
if (DispatchLevel) { NdisDprAcquireSpinLock(_pLock); } \
else { NdisAcquireSpinLock(_pLock); } \
}
// Helper for releasing an NDIS lock
#define FILTER_RELEASE_LOCK(_pLock, DispatchLevel) \
{ \
if (DispatchLevel) { NdisDprReleaseSpinLock(_pLock); } \
else { NdisReleaseSpinLock(_pLock); } \
}
//
// Enum of filter's states
// Filter can only be in one state at one time
//
typedef enum _FILTER_STATE
{
FilterStateUnspecified,
FilterPausing,
FilterPaused,
FilterRunning,
} FILTER_STATE;
#define OT_EVENT_TIMER_NOT_RUNNING 0
#define OT_EVENT_TIMER_RUNNING 1
#define OT_EVENT_TIMER_FIRED 2
//
// Define the filter struct
//
typedef struct _MS_FILTER
{
// Entry in the global list of Filter instances
LIST_ENTRY FilterModuleLink;
// NDIS Handle for the Filter instance
NDIS_HANDLE FilterHandle;
// Current state (Running or not) of the Filter instance
FILTER_STATE State;
NDIS_EVENT FilterPauseComplete;
// Handle for unicast IP address notifications
HANDLE AddressChangeHandle;
//
// Interface / Adapter variables
//
GUID InterfaceGuid;
NET_IFINDEX InterfaceIndex;
NET_LUID InterfaceLuid;
COMPARTMENT_ID InterfaceCompartmentID;
NDIS_STRING MiniportFriendlyName;
volatile LONG PendingDisconnectTasks;
//
// Miniport Capabilities
//
OT_CAPABILITIES MiniportCapabilities;
NDIS_LINK_STATE MiniportLinkState;
//
// Pending OID Handling
//
NDIS_SPIN_LOCK PendingOidRequestLock;
PNDIS_OID_REQUEST PendingOidRequest;
//
// Io Control Path Synchronization
//
RTL_REFERENCE_COUNT IoControlReferences;
NDIS_EVENT IoControlShutdownComplete;
//
// Event processing
//
PVOID EventWorkerThread;
KEVENT EventWorkerThreadStopEvent;
KEVENT EventWorkerThreadProcessAddressChanges;
KEVENT EventWorkerThreadProcessNBLs;
NDIS_SPIN_LOCK EventsLock;
LIST_ENTRY AddressChangesHead;
LIST_ENTRY NBLsHead;
ULONG CountPendingRecvNBLs;
LARGE_INTEGER NextAlarmTickCount;
KEVENT EventWorkerThreadWaitTimeUpdated;
KEVENT EventWorkerThreadProcessTasklets;
PEX_TIMER EventHighPrecisionTimer;
UCHAR EventTimerState;
LIST_ENTRY EventIrpListHead;
KEVENT EventWorkerThreadProcessIrp;
KEVENT EventWorkerThreadEnergyScanComplete;
//
// Data Path Synchronization
//
EX_RUNDOWN_REF DataPathRundown;
NDIS_HANDLE NetBufferListPool;
BOOLEAN SendPending;
PNET_BUFFER_LIST SendNetBufferList;
KEVENT SendNetBufferListComplete;
//
// OpenThread state management
//
otDeviceRole otCachedRole;
//
// OpenThread addresses
//
IN6_ADDR otCachedAddr[OT_MAX_ADDRESSES];
ULONG otCachedAddrCount;
IN6_ADDR otLinkLocalAddr;
otNetifAddress otAutoAddresses[OT_MAX_AUTO_ADDRESSES];
//
// OpenThread radio variables
//
otRadioCaps otRadioCapabilities;
PhyState otPhyState;
uint8_t otCurrentListenChannel;
uint8_t otReceiveMessage[kMaxPHYPacketSize];
uint8_t otTransmitMessage[kMaxPHYPacketSize];
RadioPacket otReceiveFrame;
RadioPacket otTransmitFrame;
CHAR otLastEnergyScanMaxRssi;
BOOLEAN otPromiscuous;
uint16_t otPanID;
uint64_t otFactoryAddress;
uint64_t otExtendedAddress;
uint16_t otShortAddress;
BOOLEAN otPendingMacOffloadEnabled;
uint8_t otPendingShortAddressCount;
uint16_t otPendingShortAddresses[MAX_PENDING_MAC_SIZE];
uint8_t otPendingExtendedAddressCount;
uint64_t otPendingExtendedAddresses[MAX_PENDING_MAC_SIZE];
#if DBG
// Used for tracking memory allocations
HANDLE otThreadId;
volatile LONG otOutstandingAllocationCount;
volatile LONG otOutstandingMemoryAllocated;
LIST_ENTRY otOutStandingAllocations;
ULONG otAllocationID;
#endif
//
// OpenThread context buffer
//
otInstance* otCtx;
PUCHAR otInstanceBuffer;
} MS_FILTER, * PMS_FILTER;
// Helper function that converts an otInstance pointer to a MS_FILTER pointer
__inline PMS_FILTER otCtxToFilter(_In_ otInstance* otCtx)
{
return *(PMS_FILTER*)((PUCHAR)otCtx - sizeof(PMS_FILTER));
}
// Helper function to indicate if a role means it is attached or not
_inline BOOLEAN IsAttached(_In_ otDeviceRole role)
{
return role > kDeviceRoleDetached;
}
//
// function prototypes
//
FILTER_ATTACH FilterAttach;
FILTER_DETACH FilterDetach;
FILTER_RESTART FilterRestart;
FILTER_PAUSE FilterPause;
FILTER_STATUS FilterStatus;
FILTER_DEVICE_PNP_EVENT_NOTIFY FilterDevicePnPEventNotify;
FILTER_NET_PNP_EVENT FilterNetPnPEvent;
FILTER_SEND_NET_BUFFER_LISTS FilterSendNetBufferLists;
FILTER_RETURN_NET_BUFFER_LISTS FilterReturnNetBufferLists;
FILTER_SEND_NET_BUFFER_LISTS_COMPLETE FilterSendNetBufferListsComplete;
FILTER_RECEIVE_NET_BUFFER_LISTS FilterReceiveNetBufferLists;
FILTER_CANCEL_SEND_NET_BUFFER_LISTS FilterCancelSendNetBufferLists;
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfIndicateLinkState(
_In_ PMS_FILTER pFilter,
_In_ NDIS_MEDIA_CONNECT_STATE MediaState
);
//
// Compartment Functions
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfSetCompartment(
_In_ PMS_FILTER pFilter,
_Out_ COMPARTMENT_ID* pOriginalCompartment
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfRevertCompartment(
_In_ COMPARTMENT_ID OriginalCompartment
);
//
// Event Processing Functions
//
EXT_CALLBACK otLwfEventProcessingTimer;
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfEventProcessingStart(
_In_ PMS_FILTER pFilter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingStop(
_In_ PMS_FILTER pFilter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingIndicateNewWaitTime(
_In_ PMS_FILTER pFilter,
_In_ ULONG waitTime
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingIndicateNewTasklet(
_In_ PMS_FILTER pFilter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingIndicateAddressChange(
_In_ PMS_FILTER pFilter,
_In_ MIB_NOTIFICATION_TYPE NotificationType,
_In_ PIN6_ADDR pAddr
);
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfEventProcessingIndicateNewNetBufferLists(
_In_ PMS_FILTER pFilter,
_In_ BOOLEAN DispatchLevel,
_In_ BOOLEAN Received,
_In_ NDIS_PORT_NUMBER PortNumber,
_In_ PNET_BUFFER_LIST NetBufferLists
);
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfEventProcessingIndicateNetBufferListsCancelled(
_In_ PMS_FILTER pFilter,
_In_ PVOID CancelId
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingIndicateIrp(
_In_ PMS_FILTER pFilter,
_In_ PIRP Irp
);
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfEventProcessingIndicateEnergyScanResult(
_In_ PMS_FILTER pFilter,
_In_ CHAR MaxRssi
);
//
// Data Path functions
//
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEnableDataPath(
_In_ PMS_FILTER pFilter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfDisableDataPath(
_In_ PMS_FILTER pFilter
);
//
// OpenThread callbacks
//
void otLwfStateChangedCallback(uint32_t aFlags, _In_ void *aContext);
void otLwfReceiveIp6DatagramCallback(_In_ otMessage aMessage, _In_ void *aContext);
void otLwfActiveScanCallback(_In_ otActiveScanResult *aResult, _In_ void *aContext);
void otLwfEnergyScanCallback(_In_ otEnergyScanResult *aResult, _In_ void *aContext);
void otLwfDiscoverCallback(_In_ otActiveScanResult *aResult, _In_ void *aContext);
void otLwfCommissionerEnergyReportCallback(uint32_t aChannelMask, const uint8_t *aEnergyList, uint8_t aEnergyListLength, void *aContext);
void otLwfCommissionerPanIdConflictCallback(uint16_t aPanId, uint32_t aChannelMask, _In_ void *aContext);
//
// Address Functions
//
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
NETIOAPI_API_
otLwfAddressChangeCallback(
_In_ PVOID CallerContext,
_In_opt_ PMIB_UNICASTIPADDRESS_ROW Row,
_In_ MIB_NOTIFICATION_TYPE NotificationType
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfEventProcessingAddressChanged(
_In_ PMS_FILTER pFilter,
_In_ MIB_NOTIFICATION_TYPE NotificationType,
_In_ PIN6_ADDR pAddr
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfInitializeAddresses(
_In_ PMS_FILTER pFilter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfAddressesUpdated(
_In_ PMS_FILTER pFilter
);
int
otLwfFindCachedAddrIndex(
_In_ PMS_FILTER pFilter,
_In_ PIN6_ADDR addr
);
//
// Logging Helper
//
#ifdef LOG_BUFFERS
void
otLogBuffer(
_In_reads_bytes_(BufferLength) PUCHAR Buffer,
_In_ ULONG BufferLength
);
#endif
//
// Debug Helpers
//
#if DBG
typedef struct _OT_ALLOC
{
LIST_ENTRY Link;
LONG Length;
ULONG ID;
} OT_ALLOC;
PMS_FILTER
otLwfFindFromCurrentThread();
#endif
#endif //_FILT_H
+40
View File
@@ -0,0 +1,40 @@
#include <windows.h>
#include <ntverp.h>
/*-----------------------------------------------*/
/* the following lines are specific to this file */
/*-----------------------------------------------*/
/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR
* and VER_INTERNALNAME_STR must be defined before including COMMON.VER
* The strings don't need a '\0', since common.ver has them.
*/
#define VER_FILETYPE VFT_DRV
/* possible values: VFT_UNKNOWN
VFT_APP
VFT_DLL
VFT_DRV
VFT_FONT
VFT_VXD
VFT_STATIC_LIB
*/
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
/* possible values VFT2_UNKNOWN
VFT2_DRV_PRINTER
VFT2_DRV_KEYBOARD
VFT2_DRV_LANGUAGE
VFT2_DRV_DISPLAY
VFT2_DRV_MOUSE
VFT2_DRV_NETWORK
VFT2_DRV_SYSTEM
VFT2_DRV_INSTALLABLE
VFT2_DRV_SOUND
VFT2_DRV_COMM
*/
#define VER_FILEDESCRIPTION_STR "otLwf NDIS 6.0 Filter Driver"
#define VER_INTERNALNAME_STR "otLwf.sys"
#define VER_ORIGINALFILENAME_STR "otLwf.sys"
#define VER_LANGNEUTRAL
#include "common.ver"
File diff suppressed because it is too large Load Diff
+180
View File
@@ -0,0 +1,180 @@
/*
* 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.
*/
#ifndef _IOCONTROL_H
#define _IOCONTROL_H
//
// Function prototype for general Io Control functions
//
typedef
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
OTLWF_IOCTL_FUNC(
_In_reads_bytes_(InBufferLength)
PVOID InBuffer,
_In_ ULONG InBufferLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
);
//
// General Io Control Functions
//
// Handles queries for the current list of Thread interfaces
OTLWF_IOCTL_FUNC otLwfIoCtlEnumerateInterfaces;
// Handles queries for the details of a specific Thread interface
OTLWF_IOCTL_FUNC otLwfIoCtlQueryInterface;
// Handles IOTCLs for OpenThread control
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfIoCtlOpenThreadControl(
_In_ PIRP Irp
);
// Handles Irp for IOTCLs for OpenThread control on the OpenThread thread
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
otLwfCompleteOpenThreadIrp(
_In_ PMS_FILTER pFilter,
_In_ PIRP Irp
);
//
// Function prototype for OpenThread Io Control functions
//
typedef
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
OTLWF_OT_IOCTL_FUNC(
_In_ PMS_FILTER pFilter,
_In_reads_bytes_(InBufferLength)
PUCHAR InBuffer,
_In_ ULONG InBufferLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
);
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otInterface;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otThread;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otActiveScan;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otDiscover;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otChannel;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otChildTimeout;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otExtendedAddress;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otExtendedPanId;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLeaderRloc;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLinkMode;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMasterKey;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMeshLocalEid;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMeshLocalPrefix;
//OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otNetworkDataLeader
//OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otNetworkDataLocal
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otNetworkName;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otPanId;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRouterRollEnabled;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otShortAddress;
//OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otUnicastAddresses
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otActiveDataset;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otPendingDataset;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLocalLeaderWeight;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otAddBorderRouter;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRemoveBorderRouter;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otAddExternalRoute;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRemoveExternalRoute;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendServerData;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otContextIdReuseDelay;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otKeySequenceCounter;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otNetworkIdTimeout;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRouterUpgradeThreshold;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otReleaseRouterId;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMacWhitelistEnabled;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otAddMacWhitelist;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRemoveMacWhitelist;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMacWhitelistEntry;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otClearMacWhitelist;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otDeviceRole;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otChildInfoById;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otChildInfoByIndex;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otEidCacheEntry;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLeaderData;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLeaderRouterId;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLeaderWeight;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otNetworkDataVersion;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otPartitionId;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRloc16;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRouterIdSequence;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRouterInfo;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otStableNetworkDataVersion;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMacBlacklistEnabled;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otAddMacBlacklist;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRemoveMacBlacklist;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMacBlacklistEntry;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otClearMacBlacklist;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMaxTransmitPower;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otNextOnMeshPrefix;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otPollPeriod;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otLocalLeaderPartitionId;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otAssignLinkQuality;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otPlatformReset;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otParentInfo;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSingleton;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMacCounters;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otMaxChildren;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerStart;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerStop;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otJoinerStart;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otJoinerStop;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otFactoryAssignedIeeeEui64;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otHashMacAddress;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRouterDowngradeThreshold;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerPanIdQuery;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerEnergyScan;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otRouterSelectionJitter;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otJoinerUdpPort;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendDiagnosticGet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendDiagnosticReset;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerAddJoiner;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerRemoveJoiner;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerProvisioningUrl;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otCommissionerAnnounceBegin;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otEnergyScan;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendActiveGet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendActiveSet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendPendingGet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendPendingSet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendMgmtCommissionerGet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otSendMgmtCommissionerSet;
OTLWF_OT_IOCTL_FUNC otLwfIoCtl_otKeySwitchGuardtime;
#endif // _IOCONTROL_H
+149
View File
@@ -0,0 +1,149 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the various types and function required to use NSI to
* query an interface's compartment ID.
*/
#ifndef _NSI_HELPER_H
#define _NSI_HELPER_H
#define NSISTATUS NTSTATUS
typedef enum _NSI_STORE {
NsiPersistent,
// Persists as long as module exists.
NsiActive,
NsiBoth,
NsiCurrent,
NsiBootFirmwareTable
} NSI_STORE;
typedef enum _NSI_STRUCT_TYPE {
NsiStructRw,
NsiStructRoDynamic,
NsiStructRoStatic,
NsiMaximumStructType
} NSI_STRUCT_TYPE;
NSISTATUS
NsiGetParameter(
__in NSI_STORE Store,
__in PNPI_MODULEID ModuleId,
__in ULONG ObjectIndex,
__in_bcount_opt(KeyStructLength) PVOID KeyStruct,
__in ULONG KeyStructLength,
__in NSI_STRUCT_TYPE StructType,
__out_bcount(ParameterLen) PVOID Parameter,
__in ULONG ParameterLen,
__in ULONG ParameterOffset
);
extern CONST NPI_MODULEID NPI_MS_NDIS_MODULEID;
typedef enum _NDIS_NSI_OBJECT_INDEX
{
NdisNsiObjectInterfaceInformation,
NdisNsiObjectInterfaceEnum,
NdisNsiObjectInterfaceLookUp,
NdisNsiObjectIfRcvAddress,
NdisNsiObjectStackIfEntry,
NdisNsiObjectInvertedIfStackEntry,
NdisNsiObjectNetwork,
NdisNsiObjectCompartment,
NdisNsiObjectThread,
NdisNsiObjectSession,
NdisNsiObjectInterfacePersist,
NdisNsiObjectCompartmentLookup,
NdisNsiObjectInterfaceInformationRaw,
NdisNsiObjectInterfaceEnumRaw,
NdisNsiObjectStackIfEnum,
NdisNsiObjectInterfaceIsolationInfo,
NdisNsiObjectJob,
NdisNsiObjectMaximum
} NDIS_NSI_OBJECT_INDEX, *PNDIS_NSI_OBJECT_INDEX;
typedef struct _NDIS_NSI_INTERFACE_INFORMATION_RW
{
// rw fields
GUID NetworkGuid;
NET_IF_ADMIN_STATUS ifAdminStatus;
NDIS_IF_COUNTED_STRING ifAlias;
NDIS_IF_PHYSICAL_ADDRESS ifPhysAddress;
NDIS_IF_COUNTED_STRING ifL2NetworkInfo;
}NDIS_NSI_INTERFACE_INFORMATION_RW, *PNDIS_NSI_INTERFACE_INFORMATION_RW;
#define NDIS_SIZEOF_NSI_INTERFACE_INFORMATION_RW_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(NDIS_NSI_INTERFACE_INFORMATION_RW, ifPhysAddress)
typedef NDIS_INTERFACE_INFORMATION NDIS_NSI_INTERFACE_INFORMATION_ROD, *PNDIS_NSI_INTERFACE_INFORMATION_ROD;
//
// Copied from ndiscomp.h
//
_IRQL_requires_max_(DISPATCH_LEVEL)
EXPORT
COMPARTMENT_ID
NdisGetThreadObjectCompartmentId(
_In_ PETHREAD ThreadObject
);
_IRQL_requires_(PASSIVE_LEVEL)
EXPORT
NTSTATUS
NdisSetThreadObjectCompartmentId(
_In_ PETHREAD ThreadObject,
_In_ NET_IF_COMPARTMENT_ID CompartmentId
);
_IRQL_requires_max_(DISPATCH_LEVEL)
__inline
COMPARTMENT_ID
NdisGetCurrentThreadCompartmentId(
VOID
)
{
return NdisGetThreadObjectCompartmentId(PsGetCurrentThread());
}
_IRQL_requires_(PASSIVE_LEVEL)
__inline
NTSTATUS
NdisSetCurrentThreadCompartmentId(
_In_ COMPARTMENT_ID CompartmentId
)
{
return
NdisSetThreadObjectCompartmentId(PsGetCurrentThread(), CompartmentId);
}
#endif // _NSI_HELPER_H
+581
View File
@@ -0,0 +1,581 @@
/*
* 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 "precomp.h"
#include "oid.tmh"
_Use_decl_annotations_
NDIS_STATUS
FilterOidRequest(
NDIS_HANDLE FilterModuleContext,
PNDIS_OID_REQUEST Request
)
/*++
Routine Description:
Request handler
Handle requests from upper layers
Arguments:
FilterModuleContext - our filter
Request - the request passed down
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_PENDING
NDIS_STATUS_XXX
NOTE: Called at <= DISPATCH_LEVEL (unlike a miniport's MiniportOidRequest)
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status;
PNDIS_OID_REQUEST ClonedRequest=NULL;
BOOLEAN bSubmitted = FALSE;
POTLWF_REQUEST_CONTEXT Context;
BOOLEAN bFalse = FALSE;
LogFuncEntryMsg(DRIVER_OID, "Request %p", Request);
//
// Most of the time, a filter will clone the OID request and pass down
// the clone. When the clone completes, the filter completes the original
// OID request.
//
// If your filter needs to modify a specific request, it can modify the
// request before or after sending down the cloned request. Or, it can
// complete the original request on its own without sending down any
// clone at all.
//
// If your filter driver does not need to modify any OID requests, then
// you may simply omit this routine entirely; NDIS will pass OID requests
// down on your behalf. This is more efficient than implementing a
// routine that does nothing but clone all requests, as in the sample here.
//
do
{
Status = NdisAllocateCloneOidRequest(pFilter->FilterHandle,
Request,
OTLWF_CLONED_OID_TAG,
&ClonedRequest);
if (Status != NDIS_STATUS_SUCCESS)
{
LogWarning(DRIVER_OID, "Failed to Clone Request, %!NDIS_STATUS!", Status);
break;
}
Context = (POTLWF_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);
*Context = Request;
bSubmitted = TRUE;
//
// Use same request ID
//
ClonedRequest->RequestId = Request->RequestId;
pFilter->PendingOidRequest = ClonedRequest;
LogVerbose(DRIVER_OID, "Sending (cloned) Oid Request %p", ClonedRequest);
Status = NdisFOidRequest(pFilter->FilterHandle, ClonedRequest);
if (Status != NDIS_STATUS_PENDING)
{
FilterOidRequestComplete(pFilter, ClonedRequest, Status);
Status = NDIS_STATUS_PENDING;
}
} while(bFalse);
if (bSubmitted == FALSE)
{
switch(Request->RequestType)
{
case NdisRequestMethod:
Request->DATA.METHOD_INFORMATION.BytesRead = 0;
Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;
Request->DATA.METHOD_INFORMATION.BytesWritten = 0;
break;
case NdisRequestSetInformation:
Request->DATA.SET_INFORMATION.BytesRead = 0;
Request->DATA.SET_INFORMATION.BytesNeeded = 0;
break;
case NdisRequestQueryInformation:
case NdisRequestQueryStatistics:
default:
Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
break;
}
}
LogFuncExitNDIS(DRIVER_OID, Status);
return Status;
}
_Use_decl_annotations_
VOID
FilterCancelOidRequest(
NDIS_HANDLE FilterModuleContext,
PVOID RequestId
)
/*++
Routine Description:
Cancels an OID request
If your filter driver does not intercept and hold onto any OID requests,
then you do not need to implement this routine. You may simply omit it.
Furthermore, if the filter only holds onto OID requests so it can pass
down a clone (the most common case) the filter does not need to implement
this routine; NDIS will then automatically request that the lower-level
filter/miniport cancel your cloned OID.
Most filters do not need to implement this routine.
Arguments:
FilterModuleContext - our filter
RequestId - identifies the request(s) to cancel
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
PNDIS_OID_REQUEST Request = NULL;
POTLWF_REQUEST_CONTEXT Context;
PNDIS_OID_REQUEST OriginalRequest = NULL;
BOOLEAN bFalse = FALSE;
LogFuncEntryMsg(DRIVER_OID, "Filter: %p, RequestId: %p", FilterModuleContext, RequestId);
FILTER_ACQUIRE_LOCK(&pFilter->PendingOidRequestLock, bFalse);
Request = pFilter->PendingOidRequest;
if (Request != NULL)
{
Context = (POTLWF_REQUEST_CONTEXT)(&Request->SourceReserved[0]);
OriginalRequest = (*Context);
}
if ((OriginalRequest != NULL) && (OriginalRequest->RequestId == RequestId))
{
FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse);
NdisFCancelOidRequest(pFilter->FilterHandle, RequestId);
}
else
{
FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse);
}
LogFuncExit(DRIVER_OID);
}
_Use_decl_annotations_
VOID
FilterOidRequestComplete(
NDIS_HANDLE FilterModuleContext,
PNDIS_OID_REQUEST Request,
NDIS_STATUS Status
)
/*++
Routine Description:
Notification that an OID request has been completed
If this filter sends a request down to a lower layer, and the request is
pended, the FilterOidRequestComplete routine is invoked when the request
is complete. Most requests we've sent are simply clones of requests
received from a higher layer; all we need to do is complete the original
higher request.
However, if this filter driver sends original requests down, it must not
attempt to complete a pending request to the higher layer.
Arguments:
FilterModuleContext - our filter context area
NdisRequest - the completed request
Status - completion status
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
PNDIS_OID_REQUEST OriginalRequest;
POTLWF_REQUEST_CONTEXT Context;
BOOLEAN bFalse = FALSE;
LogFuncEntryMsg(DRIVER_OID, "Filter: %p, Request %p", FilterModuleContext, Request);
Context = (POTLWF_REQUEST_CONTEXT)(&Request->SourceReserved[0]);
OriginalRequest = (*Context);
//
// This is an internal request
//
if (OriginalRequest == NULL)
{
otLwfInternalRequestComplete(pFilter, Request, Status);
LogFuncExit(DRIVER_OID);
return;
}
FILTER_ACQUIRE_LOCK(&pFilter->PendingOidRequestLock, bFalse);
ASSERT(pFilter->PendingOidRequest == Request);
pFilter->PendingOidRequest = NULL;
FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse);
//
// Copy the information from the returned request to the original request
//
switch(Request->RequestType)
{
case NdisRequestMethod:
OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = Request->DATA.METHOD_INFORMATION.OutputBufferLength;
OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead;
OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded;
OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten;
break;
case NdisRequestSetInformation:
OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead;
OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded;
break;
case NdisRequestQueryInformation:
case NdisRequestQueryStatistics:
default:
OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten;
OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded;
break;
}
(*Context) = NULL;
LogVerbose(DRIVER_OID, "Freeing (cloned) Oid Request %p", Request);
NdisFreeCloneOidRequest(pFilter->FilterHandle, Request);
LogVerbose(DRIVER_OID, "Completing (external) Oid Request %p", OriginalRequest);
NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status);
LogFuncExit(DRIVER_OID);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NDIS_STATUS
otLwfSendInternalRequest(
_In_ PMS_FILTER FilterModuleContext,
_In_ NDIS_REQUEST_TYPE RequestType,
_In_ NDIS_OID Oid,
_Inout_updates_bytes_to_(InformationBufferLength, *pBytesProcessed)
PVOID InformationBuffer,
_In_ ULONG InformationBufferLength,
_Out_ PULONG pBytesProcessed
)
/*++
Routine Description:
Utility routine that forms and sends an NDIS_OID_REQUEST to the
miniport, waits for it to complete, and returns status
to the caller.
NOTE: this assumes that the calling routine ensures validity
of the filter handle until this returns.
Arguments:
FilterModuleContext - pointer to our filter module context
RequestType - NdisRequest[Set|Query]Information
Oid - the object being set/queried
InformationBuffer - data for the request
InformationBufferLength - length of the above
OutputBufferLength - valid only for method request
MethodId - valid only for method request
pBytesProcessed - place to return bytes read/written
Return Value:
Status of the set/query request
--*/
{
LogFuncEntryMsg(DRIVER_OID, "Filter: %p, OID = 0x%u", FilterModuleContext, Oid);
// Build the request structure
OTLWF_REQUEST FilterRequest = { 0 };
FilterRequest.Signature = OTLWF_REQUEST_TAG;
FilterRequest.Request.Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
FilterRequest.Request.Header.Revision = NDIS_OID_REQUEST_REVISION_1;
FilterRequest.Request.Header.Size = sizeof(NDIS_OID_REQUEST);
FilterRequest.Request.RequestType = RequestType;
FilterRequest.Request.RequestId = (PVOID)OTLWF_REQUEST_ID;
FilterRequest.FreeOnCompletion = FALSE;
FilterRequest.Callback = otLwfInternalSyncRequestComplete;
NdisInitializeEvent(&FilterRequest.ReqEvent);
*pBytesProcessed = 0;
switch (RequestType)
{
case NdisRequestQueryInformation:
FilterRequest.Request.DATA.QUERY_INFORMATION.Oid = Oid;
FilterRequest.Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
FilterRequest.Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
break;
case NdisRequestSetInformation:
FilterRequest.Request.DATA.SET_INFORMATION.Oid = Oid;
FilterRequest.Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
FilterRequest.Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
break;
default:
NT_ASSERT(FALSE);
break;
}
LogVerbose(DRIVER_OID, "Sending (internal, sync) Oid Request %p", &FilterRequest.Request);
// Send off the OID request
NT_ASSERT(FilterRequest.Signature == OTLWF_REQUEST_TAG);
NDIS_STATUS Status = NdisFOidRequest(FilterModuleContext->FilterHandle, &FilterRequest.Request);
// If pending, wait for completion
if (Status == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&FilterRequest.ReqEvent, 0);
Status = FilterRequest.Status;
}
if (Status == NDIS_STATUS_SUCCESS)
{
if (RequestType == NdisRequestSetInformation)
{
*pBytesProcessed = FilterRequest.Request.DATA.SET_INFORMATION.BytesRead;
}
if (RequestType == NdisRequestQueryInformation)
{
*pBytesProcessed = FilterRequest.Request.DATA.QUERY_INFORMATION.BytesWritten;
}
}
LogFuncExitNDIS(DRIVER_OID, Status);
return Status;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
NDIS_STATUS
otLwfSendInternalRequestAsync(
_In_ PMS_FILTER FilterModuleContext,
_In_ NDIS_REQUEST_TYPE RequestType,
_In_ NDIS_OID Oid,
_Inout_updates_(InformationBufferLength)
PVOID InformationBuffer,
_In_ ULONG InformationBufferLength,
_In_opt_ otLwfInternalRequestCallback Callback
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
LogFuncEntryMsg(DRIVER_OID, "OID = 0x%u", Oid);
// Build the request structure
POTLWF_REQUEST_ASYNC FilterRequest = FILTER_ALLOC_MEM(FilterModuleContext->FilterHandle, sizeof(OTLWF_REQUEST_ASYNC));
if (FilterRequest == NULL)
{
Status = NDIS_STATUS_RESOURCES;
LogWarning(DRIVER_OID, "Failed to allocate async internal request structure");
goto error;
}
RtlZeroMemory(FilterRequest, sizeof(OTLWF_REQUEST_ASYNC));
FilterRequest->Signature = OTLWF_ASYNC_REQUEST_TAG;
FilterRequest->Request.Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
FilterRequest->Request.Header.Revision = NDIS_OID_REQUEST_REVISION_1;
FilterRequest->Request.Header.Size = sizeof(NDIS_OID_REQUEST);
FilterRequest->Request.RequestType = RequestType;
FilterRequest->Request.RequestId = (PVOID)OTLWF_REQUEST_ID;
FilterRequest->FreeOnCompletion = TRUE;
FilterRequest->Callback = Callback;
switch (RequestType)
{
case NdisRequestQueryInformation:
FilterRequest->Request.DATA.QUERY_INFORMATION.Oid = Oid;
FilterRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
FilterRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
break;
case NdisRequestSetInformation:
FilterRequest->Request.DATA.SET_INFORMATION.Oid = Oid;
FilterRequest->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
FilterRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
break;
default:
NT_ASSERT(FALSE);
break;
}
LogVerbose(DRIVER_OID, "Sending (internal, async) Oid Request %p", &FilterRequest->Request);
// Send the OID request off
NT_ASSERT(FilterRequest->Signature == OTLWF_ASYNC_REQUEST_TAG);
Status = NdisFOidRequest(FilterModuleContext->FilterHandle, &FilterRequest->Request);
// Treat pending as success
if (Status == NDIS_STATUS_PENDING)
{
Status = NDIS_STATUS_SUCCESS;
}
error:
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeMemory(FilterRequest, 0, 0);
}
LogFuncExitNDIS(DRIVER_OID, Status);
return Status;
}
// Callback for synchronous OID requests
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfInternalSyncRequestComplete(
_In_ PMS_FILTER FilterModuleContext,
_In_ PNDIS_OID_REQUEST NdisRequest,
_In_ NDIS_STATUS Status
)
{
// Get at the request context.
POTLWF_REQUEST FilterRequest = CONTAINING_RECORD(NdisRequest, OTLWF_REQUEST, Request);
UNREFERENCED_PARAMETER(FilterModuleContext);
// Save away the completion status.
FilterRequest->Status = Status;
LogVerbose(DRIVER_OID, "Setting completion event for (internal, sync) Oid Request %p", NdisRequest);
// Wake up the thread blocked for this request to complete.
NdisSetEvent(&FilterRequest->ReqEvent);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfInternalRequestComplete(
_In_ NDIS_HANDLE FilterModuleContext,
_In_ PNDIS_OID_REQUEST NdisRequest,
_In_ NDIS_STATUS Status
)
/*++
Routine Description:
NDIS entry point indicating completion of a pended NDIS_OID_REQUEST.
Arguments:
FilterModuleContext - pointer to filter module context
NdisRequest - pointer to NDIS request
Status - status of request completion
Return Value:
None
--*/
{
// Get at the request context.
POTLWF_REQUEST_ASYNC FilterRequest = CONTAINING_RECORD(NdisRequest, OTLWF_REQUEST_ASYNC, Request);
NT_ASSERT(FilterRequest->Signature == OTLWF_REQUEST_TAG || FilterRequest->Signature == OTLWF_ASYNC_REQUEST_TAG);
if (FilterRequest->Signature != OTLWF_REQUEST_TAG && FilterRequest->Signature != OTLWF_ASYNC_REQUEST_TAG) return;
FilterRequest->Signature = (ULONG)(-1); // Prevent further calls into here
BOOLEAN FreeOnCompletion = FilterRequest->FreeOnCompletion;
// Invoke the callback or free the payload if there is no callback
if (FilterRequest->Callback)
{
LogVerbose(DRIVER_OID, "Invoking callback for (internal) Oid Request %p", NdisRequest);
FilterRequest->Callback((PMS_FILTER)FilterModuleContext, NdisRequest, Status);
}
else
{
switch (NdisRequest->RequestType)
{
case NdisRequestQueryInformation:
NdisFreeMemory(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer, 0, 0);
break;
case NdisRequestSetInformation:
NdisFreeMemory(NdisRequest->DATA.SET_INFORMATION.InformationBuffer, 0, 0);
break;
default:
NT_ASSERT(FALSE);
break;
}
}
// Free the request if necessary
if (FreeOnCompletion)
{
LogVerbose(DRIVER_OID, "Freeing (internal) Oid Request %p", NdisRequest);
NdisFreeMemory(FilterRequest, 0, 0);
}
}
+130
View File
@@ -0,0 +1,130 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the structures and functions for sending and processing
* NDIS OIDs.
*/
#ifndef _OID_H
#define _OID_H
// Allocation tag for OID requests sent from the filter, 'TOID'
#define OTLWF_REQUEST_ID 'DIOT'
// Allocation tag for cloned OIDs, 'TCOD'
#define OTLWF_CLONED_OID_TAG 'DOCT'
// The context inside a cloned request
typedef struct _NDIS_OID_REQUEST *OTLWF_REQUEST_CONTEXT, **POTLWF_REQUEST_CONTEXT;
// Callback to set a new list of Keys to the MAC layer
_IRQL_requires_max_(DISPATCH_LEVEL)
typedef VOID
(*otLwfInternalRequestCallback)(
_In_ PMS_FILTER FilterModuleContext,
_In_ PNDIS_OID_REQUEST Request,
_In_ NDIS_STATUS Status
);
#define OTLWF_ASYNC_REQUEST_TAG 'aRIT'
#define OTLWF_REQUEST_TAG 'sRIT'
// Used for sending internal OID requests
typedef struct _OTLWF_REQUEST_ASYNC
{
ULONG Signature; // equals OTLWF_ASYNC_REQUEST_TAG or OTLWF_REQUEST_TAG
NDIS_OID_REQUEST Request;
BOOLEAN FreeOnCompletion;
otLwfInternalRequestCallback Callback;
} OTLWF_REQUEST_ASYNC, *POTLWF_REQUEST_ASYNC;
// Used for sending internal OID requests
typedef struct _OTLWF_REQUEST
{
OTLWF_REQUEST_ASYNC;
NDIS_EVENT ReqEvent;
NDIS_STATUS Status;
} OTLWF_REQUEST, *POTLWF_REQUEST;
FILTER_OID_REQUEST FilterOidRequest;
FILTER_CANCEL_OID_REQUEST FilterCancelOidRequest;
FILTER_OID_REQUEST_COMPLETE FilterOidRequestComplete;
// Sends an internal OID request down and waits
_IRQL_requires_max_(PASSIVE_LEVEL)
NDIS_STATUS
otLwfSendInternalRequest(
_In_ PMS_FILTER FilterModuleContext,
_In_ NDIS_REQUEST_TYPE RequestType,
_In_ NDIS_OID Oid,
_Inout_updates_bytes_to_(InformationBufferLength, *pBytesProcessed)
PVOID InformationBuffer,
_In_ ULONG InformationBufferLength,
_Out_ PULONG pBytesProcessed
);
// Sends an internal OID request down. When complete it fires the callback,
// or if the callback isn't set, frees the InformationBuffer.
_IRQL_requires_max_(DISPATCH_LEVEL)
NDIS_STATUS
otLwfSendInternalRequestAsync(
_In_ PMS_FILTER FilterModuleContext,
_In_ NDIS_REQUEST_TYPE RequestType,
_In_ NDIS_OID Oid,
_Inout_updates_(InformationBufferLength)
PVOID InformationBuffer,
_In_ ULONG InformationBufferLength,
_In_opt_ otLwfInternalRequestCallback Callback
);
// Callback for synchronous OID requests
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfInternalSyncRequestComplete(
_In_ PMS_FILTER FilterModuleContext,
_In_ PNDIS_OID_REQUEST NdisRequest,
_In_ NDIS_STATUS Status
);
// Callback when the internal OID request completes
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfInternalRequestComplete(
_In_ NDIS_HANDLE FilterModuleContext,
_In_ PNDIS_OID_REQUEST NdisRequest,
_In_ NDIS_STATUS Status
);
#endif //_OID_H
+98
View File
@@ -0,0 +1,98 @@
;-------------------------------------------------------------------------
; otLwf.INF -- NDIS LightWeight Filter Driver
; Copyright (c) 2016, Microsoft Corporation. All rights reserved.
;-------------------------------------------------------------------------
[version]
; Do not change these values
Signature = "$Windows NT$"
Class = NetService
ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318}
Provider = %openthread%
DriverVer =
CatalogFile = otLwf.cat
[Manufacturer]
%openthread%=MSFT,NTx86,NTia64,NTamd64,NTarm,NTarm64
; MS_otLwf can be used with netcfg.exe to install/uninstall the driver.
[MSFT.NTx86]
%otLwf_Desc%=Install, otLwf
[MSFT.NTia64]
%otLwf_Desc%=Install, otLwf
[MSFT.NTamd64]
%otLwf_Desc%=Install, otLwf
[MSFT.NTarm]
%otLwf_Desc%=Install, otLwf
[MSFT.NTarm64]
%otLwf_Desc%=Install, otLwf
;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[Install]
AddReg=Inst_Ndi
Characteristics=0x40000
NetCfgInstanceId="{B3A3845A-164E-4727-B12E-32B8DCE1F6CD}"
Copyfiles = otLwf.copyfiles.sys
[SourceDisksNames]
1=%otLwf_Desc%,"",,
[SourceDisksFiles]
; TODO: Include any related files that should be installed with your driver.
otLwf.sys=1
[DestinationDirs]
DefaultDestDir=12
otLwf.copyfiles.sys=12
[otLwf.copyfiles.sys]
otLwf.sys,,,2
;-------------------------------------------------------------------------
; Ndi installation support
;-------------------------------------------------------------------------
[Inst_Ndi]
HKR, Ndi,Service,,"otLwf"
HKR, Ndi,CoServices,0x00010000,"otLwf"
HKR, Ndi,HelpText,,%otLwf_HelpText%
HKR, Ndi,FilterClass,, ms_medium_converter_top
HKR, Ndi,FilterType,0x00010001,0x00000002
HKR, Ndi,FilterRunType, 0x00010001, 0x00000002 ;OPTIONAL filter
HKR, Ndi\Interfaces,UpperRange,,"noupper"
HKR, Ndi\Interfaces,LowerRange,,"nolower"
HKR, Ndi\Interfaces, FilterMediaTypes,,"802.15.4"
;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[Install.Services]
AddService=otLwf,,otLwf_Service_Inst
[otLwf_Service_Inst]
DisplayName = %otLwf_Desc%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
; Typically you will want your filter driver to start with SERVICE_SYSTEM_START.
; If it is an Optional filter, you may also use 3;SERVICE_DEMAND_START.
StartType = 1 ;SERVICE_SYSTEM_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\otLwf.sys
LoadOrderGroup = NDIS
Description = %otLwf_Desc%
[Install.Remove.Services]
; The SPSVCINST_STOPSERVICE flag instructs SCM to stop the NT service
; before uninstalling the driver.
DelService=otLwf,0x200 ; SPSVCINST_STOPSERVICE
[Strings]
openthread = "OpenThread"
otLwf_Desc = "OpenThread NDIS LightWeight Filter"
otLwf_HelpText = "OpenThread NDIS LightWeight Filter"
+1
View File
@@ -0,0 +1 @@
#include "precomp.h"
+99
View File
@@ -0,0 +1,99 @@
/*
* 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.
*/
/**
* @file
* @brief
* Precompiled header for otLwf project.
*/
#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable:4204) // nonstandard extension used : non-constant aggregate initializer
#pragma warning(disable:28175) // The 'MajorFunction' member of _DRIVER_OBJECT should not be accessed by a driver:
// Access to this member may be permitted for certain classes of drivers.
#pragma warning(disable:28301) // No annotations for first declaration of *
#include <ntifs.h>
#include <ndis.h>
#include <wdmsec.h>
#include <rtlrefcount.h>
#include <netiodef.h>
#include <nsihelper.h>
#include <netioapi.h>
#include <bcrypt.h>
VOID
RtlCopyBufferToMdl(
_In_reads_bytes_(BytesToCopy) CONST VOID *Buffer,
_Inout_ PMDL MdlChain,
_In_ SIZE_T MdlOffset,
_In_ SIZE_T BytesToCopy,
_Out_ SIZE_T* BytesCopied
);
#include <stdio.h>
#include <stdarg.h>
#include <openthread-core-config.h>
#include <openthread.h>
#include <commissioning/commissioner.h>
#include <commissioning/joiner.h>
#include <common/code_utils.hpp>
#include <platform/logging.h>
#include <platform/logging-windows.h>
#include <platform/radio.h>
#include <platform/misc.h>
#include <platform/alarm.h>
#include <platform/settings.h>
#include <otLwfIoctl.h>
#include <otOID.h>
#include <otNBLContext.h>
#ifdef _KERNEL_MODE
#define CODE_SEG(segment) __declspec(code_seg(segment))
#else
#define CODE_SEG(segment)
#endif
#define PAGED CODE_SEG("PAGE") _IRQL_always_function_max_(PASSIVE_LEVEL)
#define PAGEDX CODE_SEG("PAGE")
#define INITCODE CODE_SEG("INIT")
typedef struct _MS_FILTER MS_FILTER, *PMS_FILTER;
//#define DEBUG_TIMING
//#define LOG_BUFFERS
//#define FORCE_SYNCHRONOUS_RECEIVE
#include "driver.h"
#include "device.h"
#include "iocontrol.h"
#include "oid.h"
#include "radio.h"
#include "filter.h"
+943
View File
@@ -0,0 +1,943 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file implements the logging function required for the OpenThread library.
*/
#include "precomp.h"
#include "radio.tmh"
void
LogMac(
_In_ PCSTR szDir,
_In_ PMS_FILTER pFilter,
_In_ PNET_BUFFER_LIST NetBufferList,
ULONG frameLength,
_In_reads_bytes_(frameLength) PUCHAR frame
);
const char MacSend[] = "MAC_SEND";
const char MacRecv[] = "MAC_RECV";
#define LogMacSend(pFilter, NBL, frameLength, frame) LogMac(MacSend, pFilter, NBL, frameLength, frame)
#define LogMacRecv(pFilter, NBL, frameLength, frame) LogMac(MacRecv, pFilter, NBL, frameLength, frame)
void
otPlatReset(
_In_ otInstance *otCtx
)
{
NT_ASSERT(otCtx);
// This function does nothing currently.
UNREFERENCED_PARAMETER(otCtx);
}
otPlatResetReason
otPlatGetResetReason(
_In_ otInstance *otCtx
)
{
NT_ASSERT(otCtx);
UNREFERENCED_PARAMETER(otCtx);
return kPlatResetReason_PowerOn;
}
VOID
otLwfRadioSendPacket(
_In_ PMS_FILTER pFilter,
_In_ RadioPacket* Packet
);
VOID
otLwfRadioGetFactoryAddress(
_In_ PMS_FILTER pFilter
)
{
NDIS_STATUS status;
ULONG bytesProcessed;
OT_FACTORY_EXTENDED_ADDRESS OidBuffer = { {0} };
RtlZeroMemory(&pFilter->otFactoryAddress, sizeof(pFilter->otFactoryAddress));
// Query the MP for the address
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestQueryInformation,
OID_OT_FACTORY_EXTENDED_ADDRESS,
&OidBuffer,
sizeof(OT_FACTORY_EXTENDED_ADDRESS),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Query for OID_FACTORY_EXTENDED_ADDRESS failed, %!NDIS_STATUS!", status);
return;
}
// Validate the return header
if (bytesProcessed != SIZEOF_OT_FACTORY_EXTENDED_ADDRESS_REVISION_1 ||
OidBuffer.Header.Type != NDIS_OBJECT_TYPE_DEFAULT ||
OidBuffer.Header.Revision != OT_FACTORY_EXTENDED_ADDRESS_REVISION_1 ||
OidBuffer.Header.Size != SIZEOF_OT_FACTORY_EXTENDED_ADDRESS_REVISION_1)
{
LogError(DRIVER_DEFAULT, "Query for OID_OT_FACTORY_EXTENDED_ADDRESS returned invalid data");
return;
}
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! cached factory Extended Mac Address: %llX", &pFilter->InterfaceGuid, OidBuffer.ExtendedAddress);
pFilter->otFactoryAddress = OidBuffer.ExtendedAddress;
}
VOID
otLwfRadioInit(
_In_ PMS_FILTER pFilter
)
{
LogFuncEntry(DRIVER_DEFAULT);
NT_ASSERT(pFilter->MiniportCapabilities.MiniportMode == OT_MP_MODE_RADIO);
// Initialize the OpenThread radio capability flags
pFilter->otRadioCapabilities = kRadioCapsEnergyScan;
if ((pFilter->MiniportCapabilities.RadioCapabilities & OT_RADIO_CAP_ACK_TIMEOUT) != 0)
pFilter->otRadioCapabilities |= kRadioCapsAckTimeout;
pFilter->otPhyState = kStateDisabled;
pFilter->otCurrentListenChannel = 0xFF;
pFilter->otPromiscuous = false;
pFilter->otReceiveFrame.mPsdu = pFilter->otReceiveMessage;
pFilter->otTransmitFrame.mPsdu = pFilter->otTransmitMessage;
pFilter->otPendingMacOffloadEnabled = FALSE;
pFilter->otPendingShortAddressCount = 0;
pFilter->otPendingExtendedAddressCount = 0;
// Cache the factory address
otLwfRadioGetFactoryAddress(pFilter);
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateDisabled.", pFilter);
LogFuncExit(DRIVER_DEFAULT);
}
void otPlatRadioGetIeeeEui64(otInstance *otCtx, uint8_t *aIeeeEui64)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
memcpy(aIeeeEui64, &pFilter->otFactoryAddress, sizeof(ULONGLONG));
}
void otPlatRadioSetPanId(_In_ otInstance *otCtx, uint16_t panid)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NDIS_STATUS status;
ULONG bytesProcessed;
OT_PAND_ID OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_PAND_ID_REVISION_1, SIZEOF_OT_PAND_ID_REVISION_1}, panid };
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! set PanID: %X", &pFilter->InterfaceGuid, panid);
pFilter->otPanID = panid;
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_PAND_ID,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_PAND_ID failed, %!NDIS_STATUS!", status);
}
}
void otPlatRadioSetExtendedAddress(_In_ otInstance *otCtx, uint8_t *address)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NDIS_STATUS status;
ULONG bytesProcessed;
OT_EXTENDED_ADDRESS OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_EXTENDED_ADDRESS_REVISION_1, SIZEOF_OT_EXTENDED_ADDRESS_REVISION_1} };
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! set Extended Mac Address: %llX", &pFilter->InterfaceGuid, *(ULONGLONG*)address);
pFilter->otExtendedAddress = *(ULONGLONG*)address;
OidBuffer.ExtendedAddress = *(ULONGLONG*)address;
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_EXTENDED_ADDRESS,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_EXTENDED_ADDRESS failed, %!NDIS_STATUS!", status);
}
}
void otPlatRadioSetShortAddress(_In_ otInstance *otCtx, uint16_t address)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NDIS_STATUS status;
ULONG bytesProcessed;
OT_SHORT_ADDRESS OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_SHORT_ADDRESS_REVISION_1, SIZEOF_OT_SHORT_ADDRESS_REVISION_1}, address };
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! set Short Mac Address: %X", &pFilter->InterfaceGuid, address);
pFilter->otShortAddress = address;
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_SHORT_ADDRESS,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_SHORT_ADDRESS failed, %!NDIS_STATUS!", status);
}
}
void otPlatRadioSetPromiscuous(_In_ otInstance *otCtx, int aEnable)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NDIS_STATUS status;
ULONG bytesProcessed;
OT_PROMISCUOUS_MODE OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_PROMISCUOUS_MODE_REVISION_1, SIZEOF_OT_PROMISCUOUS_MODE_REVISION_1}, (BOOLEAN)aEnable };
pFilter->otPromiscuous = (BOOLEAN)aEnable;
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_PROMISCUOUS_MODE,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_PROMISCUOUS_MODE failed, %!NDIS_STATUS!", status);
}
}
ThreadError otPlatRadioEnable(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NT_ASSERT(pFilter->otPhyState <= kStateSleep);
if (pFilter->otPhyState > kStateSleep) return kThreadError_Busy;
pFilter->otPhyState = kStateSleep;
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateSleep.", pFilter);
return kThreadError_None;
}
ThreadError otPlatRadioDisable(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NT_ASSERT(pFilter->otPhyState <= kStateSleep);
if (pFilter->otPhyState > kStateSleep) return kThreadError_Busy;
pFilter->otPhyState = kStateDisabled;
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateDisabled.", pFilter);
return kThreadError_None;
}
ThreadError otPlatRadioSleep(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NT_ASSERT(pFilter->otPhyState != kStateDisabled);
//NT_ASSERT(pFilter->otPhyState == kStateSleep || pFilter->otPhyState == kStateReceive);
if (pFilter->otPhyState != kStateSleep && pFilter->otPhyState != kStateReceive)
return kThreadError_Busy;
if (pFilter->otPhyState != kStateSleep)
{
pFilter->otPhyState = kStateSleep;
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateSleep.", pFilter);
if ((pFilter->MiniportCapabilities.RadioCapabilities & OT_RADIO_CAP_SLEEP) != 0)
{
NDIS_STATUS status;
ULONG bytesProcessed;
OT_SLEEP_MODE OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_SLEEP_MODE_REVISION_1, SIZEOF_OT_SLEEP_MODE_REVISION_1}, TRUE };
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_SLEEP_MODE,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_SLEEP_MODE failed, %!NDIS_STATUS!", status);
}
}
}
return kThreadError_None;
}
ThreadError otPlatRadioReceive(_In_ otInstance *otCtx, uint8_t aChannel)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NT_ASSERT(pFilter->otPhyState != kStateDisabled);
if (pFilter->otPhyState == kStateDisabled) return kThreadError_Busy;
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p", pFilter);
// If we are currently in the sleep state and the minport supports sleep
// mode, come out of sleep mode now.
if (pFilter->otPhyState == kStateSleep)
{
if ((pFilter->MiniportCapabilities.RadioCapabilities & OT_RADIO_CAP_SLEEP) != 0)
{
NDIS_STATUS status;
ULONG bytesProcessed;
OT_SLEEP_MODE OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_SLEEP_MODE_REVISION_1, SIZEOF_OT_SLEEP_MODE_REVISION_1}, FALSE };
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_SLEEP_MODE,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_SLEEP_MODE failed, %!NDIS_STATUS!", status);
}
}
}
// Update current channel if different
if (pFilter->otCurrentListenChannel != aChannel)
{
NDIS_STATUS status;
ULONG bytesProcessed;
OT_CURRENT_CHANNEL OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_CURRENT_CHANNEL_REVISION_1, SIZEOF_OT_CURRENT_CHANNEL_REVISION_1}, aChannel };
NT_ASSERT(aChannel >= 11 && aChannel <= 26);
LogInfo(DRIVER_DEFAULT, "Filter %p new Listen Channel = %u.", pFilter, aChannel);
pFilter->otCurrentListenChannel = aChannel;
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_CURRENT_CHANNEL,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_CURRENT_CHANNEL failed, %!NDIS_STATUS!", status);
}
}
// Only transition to the receive state if we were sleeping; otherwise we
// are already in receive or transmit state.
if (pFilter->otPhyState == kStateSleep)
{
pFilter->otPhyState = kStateReceive;
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateReceive.", pFilter);
// Set the event to indicate we can process NBLs
KeSetEvent(&pFilter->EventWorkerThreadProcessNBLs, 0, FALSE);
}
LogFuncExit(DRIVER_DATA_PATH);
return kThreadError_None;
}
RadioPacket *otPlatRadioGetTransmitBuffer(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
return &pFilter->otTransmitFrame;
}
int8_t otPlatRadioGetRssi(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
return 0;
}
otRadioCaps otPlatRadioGetCaps(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
return otCtxToFilter(otCtx)->otRadioCapabilities;
}
int otPlatRadioGetPromiscuous(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
return pFilter->otPromiscuous;
}
VOID
otLwfRadioReceiveFrame(
_In_ PMS_FILTER pFilter,
_In_ PNET_BUFFER_LIST NetBufferList
)
{
NT_ASSERT(pFilter->otReceiveFrame.mChannel >= 11 && pFilter->otReceiveFrame.mChannel <= 26);
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p", pFilter);
LogMacRecv(pFilter, NetBufferList, pFilter->otReceiveFrame.mLength, pFilter->otReceiveFrame.mPsdu);
NT_ASSERT(pFilter->otPhyState > kStateDisabled);
if (pFilter->otPhyState > kStateDisabled)
{
otPlatRadioReceiveDone(pFilter->otCtx, &pFilter->otReceiveFrame, kThreadError_None);
}
else
{
LogVerbose(DRIVER_DATA_PATH, "Mac frame dropped.");
}
LogFuncExit(DRIVER_DATA_PATH);
}
ThreadError otPlatRadioTransmit(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
ThreadError error = kThreadError_Busy;
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p", pFilter);
NT_ASSERT(pFilter->otPhyState == kStateReceive);
if (pFilter->otPhyState == kStateReceive)
{
error = kThreadError_None;
pFilter->otPhyState = kStateTransmit;
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateTransmit.", pFilter);
}
LogFuncExitMsg(DRIVER_DATA_PATH, "%u", error);
return error;
}
VOID otLwfRadioTransmitFrame(_In_ PMS_FILTER pFilter)
{
NT_ASSERT(pFilter->otPhyState == kStateTransmit);
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p", pFilter);
otLwfRadioSendPacket(pFilter, &pFilter->otTransmitFrame);
LogFuncExit(DRIVER_DATA_PATH);
}
VOID
otLwfRadioSendPacket(
_In_ PMS_FILTER pFilter,
_In_ RadioPacket* Packet
)
{
SIZE_T BytesCopied = 0;
PNET_BUFFER SendNetBuffer = NET_BUFFER_LIST_FIRST_NB(pFilter->SendNetBufferList);
OT_NBL_CONTEXT NblContext = { 0 /* Flags */, Packet->mChannel, Packet->mPower, 0 /* Lqi */ };
NT_ASSERT(NblContext.Channel >= 11 && NblContext.Channel <= 26);
NT_ASSERT(!pFilter->SendPending);
NT_ASSERT(Packet->mLength <= kMaxPHYPacketSize);
LogMacSend(pFilter, pFilter->SendNetBufferList, Packet->mLength, Packet->mPsdu);
// Copy to the NetBufferList
RtlCopyBufferToMdl(
Packet->mPsdu,
SendNetBuffer->CurrentMdl,
SendNetBuffer->CurrentMdlOffset,
Packet->mLength,
&BytesCopied
);
NT_ASSERT(BytesCopied == Packet->mLength);
// Set the length field
NET_BUFFER_DATA_LENGTH(SendNetBuffer) = Packet->mLength;
// Set the context
SetNBLContext(pFilter->SendNetBufferList, &NblContext);
// Reset the completion event
KeResetEvent(&pFilter->SendNetBufferListComplete);
pFilter->SendPending = TRUE;
// Send the NetBufferList
NdisFSendNetBufferLists(
pFilter->FilterHandle,
pFilter->SendNetBufferList,
NDIS_DEFAULT_PORT_NUMBER,
0
);
}
VOID
otLwfRadioTransmitFrameDone(
_In_ PMS_FILTER pFilter
)
{
LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p", pFilter);
pFilter->SendPending = FALSE;
NT_ASSERT(pFilter->otPhyState == kStateTransmit);
// Now that we are completing a send, fall back to receive state and set the event
pFilter->otPhyState = kStateReceive;
LogInfo(DRIVER_DEFAULT, "Filter %p PhyState = kStateReceive.", pFilter);
KeSetEvent(&pFilter->EventWorkerThreadProcessNBLs, 0, FALSE);
if (STATUS_SUCCESS == pFilter->SendNetBufferList->Status)
{
POT_NBL_CONTEXT SendNblContext = GetNBLContext(pFilter->SendNetBufferList);
BOOLEAN FramePending = (SendNblContext->Flags & OT_NBL_FLAG_ACK_FRAME_PENDING) != 0 || pFilter->CountPendingRecvNBLs != 0;
otPlatRadioTransmitDone(pFilter->otCtx, FramePending, kThreadError_None);
}
else if (STATUS_DEVICE_BUSY == pFilter->SendNetBufferList->Status)
{
otPlatRadioTransmitDone(pFilter->otCtx, false, kThreadError_ChannelAccessFailure);
}
else if (STATUS_TIMEOUT == pFilter->SendNetBufferList->Status)
{
otPlatRadioTransmitDone(pFilter->otCtx, false, kThreadError_NoAck);
}
else
{
otPlatRadioTransmitDone(pFilter->otCtx, false, kThreadError_Abort);
}
LogFuncExit(DRIVER_DATA_PATH);
}
NDIS_STATUS
otPlatRadioSendPendingMacOffload(
_In_ PMS_FILTER pFilter
)
{
NDIS_STATUS status;
ULONG bytesProcessed;
UCHAR ShortAddressCount = pFilter->otPendingMacOffloadEnabled == TRUE ? pFilter->otPendingShortAddressCount : 0;
UCHAR ExtendedAddressCount = pFilter->otPendingMacOffloadEnabled == TRUE ? pFilter->otPendingExtendedAddressCount : 0;
USHORT OidBufferSize = COMPLETE_SIZEOF_OT_PENDING_MAC_OFFLOAD_REVISION_1(ShortAddressCount, ExtendedAddressCount);
POT_PENDING_MAC_OFFLOAD OidBuffer = (POT_PENDING_MAC_OFFLOAD)FILTER_ALLOC_MEM(pFilter->FilterHandle, OidBufferSize);
PUCHAR Offset = (PUCHAR)(OidBuffer + 1);
ULONG BufferSizeLeft = OidBufferSize - sizeof(OT_PENDING_MAC_OFFLOAD);
OidBuffer->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
OidBuffer->Header.Revision = OT_PENDING_MAC_OFFLOAD_REVISION_1;
OidBuffer->Header.Size = OidBufferSize;
OidBuffer->ShortAddressCount = ShortAddressCount;
OidBuffer->ExtendedAddressCount = ExtendedAddressCount;
if (ShortAddressCount != 0)
{
memcpy_s(Offset, BufferSizeLeft, pFilter->otPendingShortAddresses, sizeof(USHORT) * ShortAddressCount);
Offset += sizeof(USHORT) * ShortAddressCount;
BufferSizeLeft -= sizeof(USHORT) * ShortAddressCount;
}
if (ExtendedAddressCount != 0)
{
memcpy_s(Offset, BufferSizeLeft, pFilter->otPendingExtendedAddresses, sizeof(ULONGLONG) * ExtendedAddressCount);
}
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! indicating updated Pending Mac Offload", &pFilter->InterfaceGuid);
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_PENDING_MAC_OFFLOAD,
OidBuffer,
OidBufferSize,
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_PENDING_MAC_OFFLOAD failed, %!NDIS_STATUS!", status);
}
FILTER_FREE_MEM(OidBuffer);
return status;
}
void otPlatRadioEnableSrcMatch(_In_ otInstance *otCtx, bool aEnable)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Ignore if we are already in the correct state
if (aEnable == pFilter->otPendingMacOffloadEnabled) return;
// Set the new value and update the miniport
pFilter->otPendingMacOffloadEnabled = aEnable ? TRUE : FALSE;
otPlatRadioSendPendingMacOffload(pFilter);
}
ThreadError otPlatRadioAddSrcMatchShortEntry(_In_ otInstance *otCtx, const uint16_t aShortAddress)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Make sure we are enabled
NT_ASSERT(pFilter->otPendingMacOffloadEnabled);
if (pFilter->otPendingMacOffloadEnabled == FALSE)
return kThreadError_InvalidState;
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingShortAddressCount; i++)
{
if (aShortAddress == pFilter->otPendingShortAddresses[i])
{
Found = TRUE;
break;
}
}
// Already in the list, return success
if (Found) return kThreadError_None;
// Make sure we have room
if (pFilter->otPendingShortAddressCount == MAX_PENDING_MAC_SIZE) return kThreadError_NoBufs;
// Copy to the list
pFilter->otPendingShortAddresses[pFilter->otPendingShortAddressCount] = aShortAddress;
pFilter->otPendingShortAddressCount++;
// Update the miniport
otPlatRadioSendPendingMacOffload(pFilter);
return kThreadError_None;
}
ThreadError otPlatRadioAddSrcMatchExtEntry(_In_ otInstance *otCtx, const uint8_t *aExtAddress)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Make sure we are enabled
NT_ASSERT(pFilter->otPendingMacOffloadEnabled);
if (pFilter->otPendingMacOffloadEnabled == FALSE)
return kThreadError_InvalidState;
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingExtendedAddressCount; i++)
{
if (memcmp(aExtAddress, &pFilter->otPendingExtendedAddresses[i], sizeof(ULONGLONG)) == 0)
{
Found = TRUE;
break;
}
}
// Already in the list, return success
if (Found) return kThreadError_None;
// Make sure we have room
if (pFilter->otPendingExtendedAddressCount == MAX_PENDING_MAC_SIZE) return kThreadError_NoBufs;
// Copy to the list
memcpy(&pFilter->otPendingExtendedAddresses[pFilter->otPendingExtendedAddressCount], aExtAddress, sizeof(ULONGLONG));
pFilter->otPendingExtendedAddressCount++;
// Update the miniport
otPlatRadioSendPendingMacOffload(pFilter);
return kThreadError_None;
}
ThreadError otPlatRadioClearSrcMatchShortEntry(_In_ otInstance *otCtx, const uint16_t aShortAddress)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Make sure we are enabled
NT_ASSERT(pFilter->otPendingMacOffloadEnabled);
if (pFilter->otPendingMacOffloadEnabled == FALSE)
return kThreadError_InvalidState;
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingShortAddressCount; i++)
{
if (aShortAddress == pFilter->otPendingShortAddresses[i])
{
// Remove it from the list
if (i + 1 != pFilter->otPendingShortAddressCount)
pFilter->otPendingShortAddresses[i] = pFilter->otPendingShortAddresses[pFilter->otPendingShortAddressCount - 1];
pFilter->otPendingShortAddressCount--;
Found = TRUE;
break;
}
}
// Wasn't in the list, return failure
if (Found == FALSE) return kThreadError_NotFound;
// Update the miniport
otPlatRadioSendPendingMacOffload(pFilter);
return kThreadError_None;
}
ThreadError otPlatRadioClearSrcMatchExtEntry(_In_ otInstance *otCtx, const uint8_t *aExtAddress)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Make sure we are enabled
NT_ASSERT(pFilter->otPendingMacOffloadEnabled);
if (pFilter->otPendingMacOffloadEnabled == FALSE)
return kThreadError_InvalidState;
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingExtendedAddressCount; i++)
{
if (memcmp(aExtAddress, &pFilter->otPendingExtendedAddresses[i], sizeof(ULONGLONG)) == 0)
{
// Remove it from the list
if (i + 1 != pFilter->otPendingExtendedAddressCount)
pFilter->otPendingExtendedAddresses[i] = pFilter->otPendingExtendedAddresses[pFilter->otPendingExtendedAddressCount - 1];
pFilter->otPendingExtendedAddressCount--;
Found = TRUE;
break;
}
}
// Wasn't in the list, return failure
if (Found == FALSE) return kThreadError_NotFound;
// Update the miniport
otPlatRadioSendPendingMacOffload(pFilter);
return kThreadError_None;
}
void otPlatRadioClearSrcMatchShortEntries(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Ignore if we are already in the correct state
if (pFilter->otPendingShortAddressCount == 0) return;
// Set the new value and update the miniport
pFilter->otPendingShortAddressCount = 0;
otPlatRadioSendPendingMacOffload(pFilter);
}
void otPlatRadioClearSrcMatchExtEntries(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Ignore if we are already in the correct state
if (pFilter->otPendingExtendedAddressCount == 0) return;
// Set the new value and update the miniport
pFilter->otPendingExtendedAddressCount = 0;
otPlatRadioSendPendingMacOffload(pFilter);
}
ThreadError otPlatRadioEnergyScan(_In_ otInstance *otCtx, uint8_t aScanChannel, uint16_t aScanDuration)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NDIS_STATUS status;
ULONG bytesProcessed;
OT_ENERGY_SCAN OidBuffer = { {NDIS_OBJECT_TYPE_DEFAULT, OT_ENERGY_SCAN_REVISION_1, SIZEOF_OT_ENERGY_SCAN_REVISION_1}, aScanChannel, aScanDuration };
LogInfo(DRIVER_DEFAULT, "Filter %p starting energy scan on channel %d (%d ms).", pFilter, aScanChannel, aScanDuration);
// Cache the listening channel
pFilter->otCurrentListenChannel = aScanChannel;
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_ENERGY_SCAN,
&OidBuffer,
sizeof(OidBuffer),
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_ENERGY_SCAN failed, %!NDIS_STATUS!", status);
}
return NT_SUCCESS(status) ? kThreadError_None : kThreadError_Failed;
}
inline USHORT getDstShortAddress(const UCHAR *frame)
{
return (((USHORT)frame[IEEE802154_DSTADDR_OFFSET + 1]) << 8) | frame[IEEE802154_DSTADDR_OFFSET];
}
inline USHORT getSrcShortAddress(ULONG frameLength, _In_reads_bytes_(frameLength) PUCHAR frame, ULONG offset)
{
return (offset + 1 < frameLength) ? ((((USHORT)frame[offset + 1]) << 8) | frame[offset]) : 0;
}
inline ULONGLONG getDstExtAddress(const UCHAR *frame)
{
return *(ULONGLONG*)(frame + IEEE802154_DSTADDR_OFFSET);
}
inline ULONGLONG getSrcExtAddress(ULONG frameLength, _In_reads_bytes_(frameLength) PUCHAR frame, ULONG offset)
{
return (offset + 7 < frameLength) ? (*(ULONGLONG*)(frame + offset)) : 0;
}
void
LogMac(
_In_ PCSTR szDir,
_In_ PMS_FILTER pFilter,
_In_ PNET_BUFFER_LIST NetBufferList,
ULONG frameLength,
_In_reads_bytes_(frameLength) PUCHAR frame
)
{
if (frameLength < 6) return;
NT_ASSERT(frame);
UCHAR AckRequested = (frame[0] & IEEE802154_ACK_REQUEST) != 0 ? 1 : 0;
UCHAR FramePending = (frame[0] & IEEE802154_FRAME_PENDING) != 0 ? 1 : 0;
switch (frame[1] & (IEEE802154_DST_ADDR_MASK | IEEE802154_SRC_ADDR_MASK))
{
case IEEE802154_DST_ADDR_NONE | IEEE802154_SRC_ADDR_NONE:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : null => null (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_NONE | IEEE802154_SRC_ADDR_SHORT:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : %X => null (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getSrcShortAddress(frameLength, frame, IEEE802154_DSTADDR_OFFSET), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_NONE | IEEE802154_SRC_ADDR_EXT:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : %llX => null (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getSrcExtAddress(frameLength, frame, IEEE802154_DSTADDR_OFFSET), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_SHORT | IEEE802154_SRC_ADDR_NONE:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : null => %X (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getDstShortAddress(frame), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_SHORT | IEEE802154_SRC_ADDR_SHORT:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : %X => %X (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getSrcShortAddress(frameLength, frame, IEEE802154_DSTADDR_OFFSET+2), getDstShortAddress(frame), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_SHORT | IEEE802154_SRC_ADDR_EXT:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : %llX => %X (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getSrcExtAddress(frameLength, frame, IEEE802154_DSTADDR_OFFSET+2), getDstShortAddress(frame), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_EXT | IEEE802154_SRC_ADDR_NONE:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : null => %llX (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getDstExtAddress(frame), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_EXT | IEEE802154_SRC_ADDR_SHORT:
LogVerbose(DRIVER_DATA_PATH, "Filt: %p, %s: %p : %X => %llX (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getSrcShortAddress(frameLength, frame, IEEE802154_DSTADDR_OFFSET+8), getDstExtAddress(frame), frameLength, AckRequested, FramePending);
break;
case IEEE802154_DST_ADDR_EXT | IEEE802154_SRC_ADDR_EXT:
LogVerbose(DRIVER_DATA_PATH, "Filter: %p, %s: %p : %llX => %llX (%u bytes, AckReq=%u, FramePending=%u)",
pFilter, szDir, NetBufferList, getSrcExtAddress(frameLength, frame, IEEE802154_DSTADDR_OFFSET+8), getDstExtAddress(frame), frameLength, AckRequested, FramePending);
break;
}
#ifdef LOG_BUFFERS
otLogBuffer(frame, frameLength);
#endif
}
+92
View File
@@ -0,0 +1,92 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file defines the structures and functions for the OpenThread radio interface.
*/
#ifndef _OTLWF_RADIO_H
#define _OTLWF_RADIO_H
enum
{
IEEE802154_MIN_LENGTH = 5,
IEEE802154_MAX_LENGTH = 127,
IEEE802154_ACK_LENGTH = 5,
IEEE802154_BROADCAST = 0xffff,
IEEE802154_FRAME_TYPE_ACK = 2 << 0,
IEEE802154_FRAME_TYPE_MACCMD = 3 << 0,
IEEE802154_FRAME_TYPE_MASK = 7 << 0,
IEEE802154_SECURITY_ENABLED = 1 << 3,
IEEE802154_FRAME_PENDING = 1 << 4,
IEEE802154_ACK_REQUEST = 1 << 5,
IEEE802154_PANID_COMPRESSION = 1 << 6,
IEEE802154_DST_ADDR_NONE = 0 << 2,
IEEE802154_DST_ADDR_SHORT = 2 << 2,
IEEE802154_DST_ADDR_EXT = 3 << 2,
IEEE802154_DST_ADDR_MASK = 3 << 2,
IEEE802154_SRC_ADDR_NONE = 0 << 6,
IEEE802154_SRC_ADDR_SHORT = 2 << 6,
IEEE802154_SRC_ADDR_EXT = 3 << 6,
IEEE802154_SRC_ADDR_MASK = 3 << 6,
IEEE802154_DSN_OFFSET = 2,
IEEE802154_DSTPAN_OFFSET = 3,
IEEE802154_DSTADDR_OFFSET = 5,
IEEE802154_SEC_LEVEL_MASK = 7 << 0,
IEEE802154_KEY_ID_MODE_0 = 0 << 3,
IEEE802154_KEY_ID_MODE_1 = 1 << 3,
IEEE802154_KEY_ID_MODE_2 = 2 << 3,
IEEE802154_KEY_ID_MODE_3 = 3 << 3,
IEEE802154_KEY_ID_MODE_MASK = 3 << 3,
IEEE802154_MACCMD_DATA_REQ = 4,
};
// Initializes the radio layer
VOID otLwfRadioInit(_In_ PMS_FILTER pFilter);
// Indicates a received frame from the radio layer
VOID otLwfRadioReceiveFrame(_In_ PMS_FILTER pFilter, _In_ PNET_BUFFER_LIST NetBufferList);
// Indicates the transmit frame is ready to send to the radio layer
VOID otLwfRadioTransmitFrame(_In_ PMS_FILTER pFilter);
// Indicates the transmit frame finished sending
VOID otLwfRadioTransmitFrameDone(_In_ PMS_FILTER pFilter);
#endif //_OTLWF_RADIO_H
+118
View File
@@ -0,0 +1,118 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file implements the settings functions required for the OpenThread library.
*/
#include "precomp.h"
#include "settings.tmh"
void otPlatSettingsInit(otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
}
ThreadError otPlatSettingsBeginChange(otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
return kThreadError_NotImplemented;
}
ThreadError otPlatSettingsCommitChange(otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
return kThreadError_NotImplemented;
}
ThreadError otPlatSettingsAbandonChange(otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
return kThreadError_NotImplemented;
}
ThreadError otPlatSettingsGet(otInstance *otCtx, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
UNREFERENCED_PARAMETER(aKey);
UNREFERENCED_PARAMETER(aIndex);
UNREFERENCED_PARAMETER(aValue);
UNREFERENCED_PARAMETER(aValueLength);
return kThreadError_NotImplemented;
}
ThreadError otPlatSettingsSet(otInstance *otCtx, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
UNREFERENCED_PARAMETER(aKey);
UNREFERENCED_PARAMETER(aValue);
UNREFERENCED_PARAMETER(aValueLength);
return kThreadError_NotImplemented;
}
ThreadError otPlatSettingsAdd(otInstance *otCtx, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
UNREFERENCED_PARAMETER(aKey);
UNREFERENCED_PARAMETER(aValue);
UNREFERENCED_PARAMETER(aValueLength);
return kThreadError_NotImplemented;
}
ThreadError otPlatSettingsDelete(otInstance *otCtx, uint16_t aKey, int aIndex)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
UNREFERENCED_PARAMETER(aKey);
UNREFERENCED_PARAMETER(aIndex);
return kThreadError_NotImplemented;
}
void otPlatSettingsWipe(otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
UNREFERENCED_PARAMETER(pFilter);
}
+1 -1
View File
@@ -45,7 +45,7 @@ extern "C" {
#endif
#ifdef _WIN32
#ifdef WINDOWS_KERNEL
#ifdef _KERNEL_MODE
#include <ntdef.h>
#else
#include <windows.h>
+1 -2
View File
@@ -35,8 +35,7 @@
#ifndef OT_PLATFORM_SETTINGS_H
#define OT_PLATFORM_SETTINGS_H 1
#include <stdint.h>
#include <openthread-instance.h>
#include <openthread-types.h>
#ifdef __cplusplus
extern "C" {
+6
View File
@@ -72,6 +72,12 @@ static const otExtAddress sMode2ExtAddress =
static const uint8_t sExtendedPanidInit[] = {0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0xca, 0xfe};
static const char sNetworkNameInit[] = "OpenThread";
#ifdef _WIN32
const uint32_t kMinBackoffSum = kMinBackoff + (kUnitBackoffPeriod *kPhyUsPerSymbol * (1 << kMinBE)) / 1000;
const uint32_t kMaxBackoffSum = kMinBackoff + (kUnitBackoffPeriod *kPhyUsPerSymbol * (1 << kMaxBE)) / 1000;
static_assert(kMinBackoffSum > 0, "The min backoff value should be greater than zero!");
#endif
void Mac::StartCsmaBackoff(void)
{
uint32_t backoffExponent = kMinBE + mTransmitAttempts + mCsmaAttempts;
+2 -6
View File
@@ -34,14 +34,10 @@
#ifndef OPENTHREAD_CORE_CONFIG_H_
#define OPENTHREAD_CORE_CONFIG_H_
#ifndef OPENTHREAD_CORE_HAVE_PROJECT_SPECIFIC_CONFIG
#define OPENTHREAD_CORE_HAVE_PROJECT_SPECIFIC_CONFIG 0
#endif
#define OPENTHREAD_CORE_CONFIG_H_IN
#if OPENTHREAD_CORE_HAVE_PROJECT_SPECIFIC_CONFIG
#include <openthread-core-project-config.h>
#ifdef OPENTHREAD_PROJECT_CORE_CONFIG_FILE
#include OPENTHREAD_PROJECT_CORE_CONFIG_FILE
#endif
#include <openthread-core-default-config.h>
+6 -5
View File
@@ -56,7 +56,8 @@ void Dataset::Clear(bool isLocal)
if (isLocal)
{
otPlatSettingsDelete(mInstance, mType == Tlv::kActiveTimestamp ? kKeyActiveDataset : kKeyPendingDataset, -1);
otPlatSettingsDelete(mInstance, static_cast<uint16_t>(mType == Tlv::kActiveTimestamp ? kKeyActiveDataset :
kKeyPendingDataset), -1);
}
}
@@ -440,14 +441,14 @@ int Dataset::Compare(const Dataset &aCompare) const
ThreadError Dataset::Restore(void)
{
return otPlatSettingsGet(mInstance, mType == Tlv::kActiveTimestamp ? kKeyActiveDataset : kKeyPendingDataset, 0, mTlvs,
&mLength);
return otPlatSettingsGet(mInstance, static_cast<uint16_t>(mType == Tlv::kActiveTimestamp ? kKeyActiveDataset :
kKeyPendingDataset), 0, mTlvs, &mLength);
}
ThreadError Dataset::Store(void)
{
return otPlatSettingsSet(mInstance, mType == Tlv::kActiveTimestamp ? kKeyActiveDataset : kKeyPendingDataset, mTlvs,
mLength);
return otPlatSettingsSet(mInstance, static_cast<uint16_t>(mType == Tlv::kActiveTimestamp ? kKeyActiveDataset :
kKeyPendingDataset), mTlvs, mLength);
}
ThreadError Dataset::Set(const Tlv &aTlv)