mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
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:
+48
-6
@@ -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.
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -0,0 +1 @@
|
||||
#include "precomp.h"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -45,7 +45,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef WINDOWS_KERNEL
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <ntdef.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user