mirror of
https://github.com/tsukumijima/px4_drv.git
synced 2025-07-23 04:03:01 +02:00
winusb: 本体を追加
This commit is contained in:
5
winusb/.gitignore
vendored
Normal file
5
winusb/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.vs/
|
||||
build/
|
||||
|
||||
*.aps
|
||||
*.user
|
39
winusb/include/IBonDriver.h
Normal file
39
winusb/include/IBonDriver.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// IBonDriver.h: IBonDriver <20>N<EFBFBD><4E><EFBFBD>X<EFBFBD>̃C<CC83><43><EFBFBD>^<5E>[<5B>t<EFBFBD>F<EFBFBD>C<EFBFBD>X
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(_IBONDRIVER_H_)
|
||||
#define _IBONDRIVER_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
|
||||
// <20>}<7D>h<EFBFBD><68><EFBFBD>C<EFBFBD>o<EFBFBD>C<EFBFBD><43><EFBFBD>^<5E>t<EFBFBD>F<EFBFBD>[<5B>X
|
||||
class IBonDriver
|
||||
{
|
||||
public:
|
||||
virtual const BOOL OpenTuner(void) = 0;
|
||||
virtual void CloseTuner(void) = 0;
|
||||
|
||||
virtual const BOOL SetChannel(const BYTE bCh) = 0;
|
||||
virtual const float GetSignalLevel(void) = 0;
|
||||
|
||||
virtual const DWORD WaitTsStream(const DWORD dwTimeOut = 0) = 0;
|
||||
virtual const DWORD GetReadyCount(void) = 0;
|
||||
|
||||
virtual const BOOL GetTsStream(BYTE *pDst, DWORD *pdwSize, DWORD *pdwRemain) = 0;
|
||||
virtual const BOOL GetTsStream(BYTE **ppDst, DWORD *pdwSize, DWORD *pdwRemain) = 0;
|
||||
|
||||
virtual void PurgeTsStream(void) = 0;
|
||||
|
||||
virtual void Release(void) = 0;
|
||||
};
|
||||
|
||||
|
||||
// <20>C<EFBFBD><43><EFBFBD>X<EFBFBD>^<5E><><EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<5C>b<EFBFBD>h
|
||||
extern "C" __declspec(dllimport) IBonDriver * CreateBonDriver();
|
||||
|
||||
|
||||
#endif // !defined(_IBONDRIVER_H_)
|
36
winusb/include/IBonDriver2.h
Normal file
36
winusb/include/IBonDriver2.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// IBonDriver2.h: IBonDriver2 <20>N<EFBFBD><4E><EFBFBD>X<EFBFBD>̃C<CC83><43><EFBFBD>^<5E>[<5B>t<EFBFBD>F<EFBFBD>C<EFBFBD>X
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(_IBONDRIVER2_H_)
|
||||
#define _IBONDRIVER2_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
|
||||
#include "IBonDriver.h"
|
||||
|
||||
|
||||
// <20>}<7D>h<EFBFBD><68><EFBFBD>C<EFBFBD>o<EFBFBD>C<EFBFBD><43><EFBFBD>^<5E>t<EFBFBD>F<EFBFBD>[<5B>X2
|
||||
class IBonDriver2 : public IBonDriver
|
||||
{
|
||||
public:
|
||||
virtual LPCTSTR GetTunerName(void) = 0;
|
||||
|
||||
virtual const BOOL IsTunerOpening(void) = 0;
|
||||
|
||||
virtual LPCTSTR EnumTuningSpace(const DWORD dwSpace) = 0;
|
||||
virtual LPCTSTR EnumChannelName(const DWORD dwSpace, const DWORD dwChannel) = 0;
|
||||
|
||||
virtual const BOOL SetChannel(const DWORD dwSpace, const DWORD dwChannel) = 0;
|
||||
|
||||
virtual const DWORD GetCurSpace(void) = 0;
|
||||
virtual const DWORD GetCurChannel(void) = 0;
|
||||
|
||||
// IBonDriver
|
||||
virtual void Release(void) = 0;
|
||||
};
|
||||
|
||||
#endif // !defined(_IBONDRIVER2_H_)
|
65
winusb/px4_winusb.sln
Normal file
65
winusb/px4_winusb.sln
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29613.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BonDriver_PX4", "src\BonDriver_PX4\BonDriver_PX4.vcxproj", "{E57919FC-F7EA-4551-B021-A1ACD2E324B1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DriverHost_PX4", "src\DriverHost_PX4\DriverHost_PX4.vcxproj", "{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fwtool", "src\fwtool\fwtool.vcxproj", "{BDBD265F-5914-426F-89F7-16478BE1AFCC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
Release-static|x64 = Release-static|x64
|
||||
Release-static|x86 = Release-static|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Debug|x64.Build.0 = Debug|x64
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release|x64.ActiveCfg = Release|x64
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release|x64.Build.0 = Release|x64
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release|x86.Build.0 = Release|Win32
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release-static|x64.ActiveCfg = Release-static|x64
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release-static|x64.Build.0 = Release-static|x64
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release-static|x86.ActiveCfg = Release-static|Win32
|
||||
{E57919FC-F7EA-4551-B021-A1ACD2E324B1}.Release-static|x86.Build.0 = Release-static|Win32
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Debug|x64.Build.0 = Debug|x64
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release|x64.ActiveCfg = Release|x64
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release|x64.Build.0 = Release|x64
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release|x86.Build.0 = Release|Win32
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release-static|x64.ActiveCfg = Release-static|x64
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release-static|x64.Build.0 = Release-static|x64
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release-static|x86.ActiveCfg = Release-static|Win32
|
||||
{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}.Release-static|x86.Build.0 = Release-static|Win32
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Debug|x64.Build.0 = Debug|x64
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release|x64.ActiveCfg = Release|x64
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release|x64.Build.0 = Release|x64
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release|x86.Build.0 = Release|Win32
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release-static|x64.ActiveCfg = Release-static|x64
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release-static|x64.Build.0 = Release-static|x64
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release-static|x86.ActiveCfg = Release-static|Win32
|
||||
{BDBD265F-5914-426F-89F7-16478BE1AFCC}.Release-static|x86.Build.0 = Release-static|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {91D321FC-F13A-44DF-88BB-2B76CDE50DE2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
296
winusb/src/BonDriver_PX4/BonDriver_PX4.vcxproj
Normal file
296
winusb/src/BonDriver_PX4/BonDriver_PX4.vcxproj
Normal file
@@ -0,0 +1,296 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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="Release-static|Win32">
|
||||
<Configuration>Release-static</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>
|
||||
<ProjectConfiguration Include="Release-static|x64">
|
||||
<Configuration>Release-static</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{E57919FC-F7EA-4551-B021-A1ACD2E324B1}</ProjectGuid>
|
||||
<RootNamespace>BonDriverPX4</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<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'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)include;$(SolutionDir)src\common;$(ProjectDir);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)include;$(SolutionDir)src\common;$(ProjectDir);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)include;$(SolutionDir)src\common;$(ProjectDir);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)include;$(SolutionDir)src\common;$(ProjectDir);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)include;$(SolutionDir)src\common;$(ProjectDir);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)include;$(SolutionDir)src\common;$(ProjectDir);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\config.cpp" />
|
||||
<ClCompile Include="..\common\msg.c" />
|
||||
<ClCompile Include="..\common\pipe.cpp" />
|
||||
<ClCompile Include="..\common\util.cpp" />
|
||||
<ClCompile Include="bon_driver.cpp" />
|
||||
<ClCompile Include="chset.cpp" />
|
||||
<ClCompile Include="cmd_client.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="io_queue.cpp" />
|
||||
<ClCompile Include="pipe_client.cpp" />
|
||||
<ClCompile Include="receiver_info_set.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\IBonDriver.h" />
|
||||
<ClInclude Include="..\..\include\IBonDriver2.h" />
|
||||
<ClInclude Include="..\common\command.hpp" />
|
||||
<ClInclude Include="..\common\config.hpp" />
|
||||
<ClInclude Include="..\common\msg.h" />
|
||||
<ClInclude Include="..\common\pipe.hpp" />
|
||||
<ClInclude Include="..\common\type.hpp" />
|
||||
<ClInclude Include="..\common\util.hpp" />
|
||||
<ClInclude Include="bon_driver.hpp" />
|
||||
<ClInclude Include="chset.hpp" />
|
||||
<ClInclude Include="cmd_client.hpp" />
|
||||
<ClInclude Include="io_queue.hpp" />
|
||||
<ClInclude Include="pipe_client.hpp" />
|
||||
<ClInclude Include="receiver_info_set.hpp" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\pkg\BonDriver_PX4\BonDriver_PX-MLT.ini" />
|
||||
<None Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-S.ini" />
|
||||
<None Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-T.ini" />
|
||||
<None Include="dll.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-S.ChSet.txt" />
|
||||
<Text Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-T.ChSet.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="BonDriver_PX4.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
129
winusb/src/BonDriver_PX4/BonDriver_PX4.vcxproj.filters
Normal file
129
winusb/src/BonDriver_PX4/BonDriver_PX4.vcxproj.filters
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="ソース ファイル">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="ヘッダー ファイル">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="リソース ファイル">
|
||||
<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="パッケージ">
|
||||
<UniqueIdentifier>{0d60a9d3-c999-47a3-a4fd-27e57fc16b6a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\config.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\msg.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\pipe.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\util.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="bon_driver.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="chset.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cmd_client.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="io_queue.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pipe_client.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="receiver_info_set.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\IBonDriver.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IBonDriver2.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\command.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\config.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\msg.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\pipe.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\type.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\util.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="bon_driver.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="chset.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cmd_client.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="io_queue.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pipe_client.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="receiver_info_set.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\pkg\BonDriver_PX4\BonDriver_PX-MLT.ini">
|
||||
<Filter>パッケージ</Filter>
|
||||
</None>
|
||||
<None Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-S.ini">
|
||||
<Filter>パッケージ</Filter>
|
||||
</None>
|
||||
<None Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-T.ini">
|
||||
<Filter>パッケージ</Filter>
|
||||
</None>
|
||||
<None Include="dll.def">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-S.ChSet.txt">
|
||||
<Filter>パッケージ</Filter>
|
||||
</Text>
|
||||
<Text Include="..\..\pkg\BonDriver_PX4\BonDriver_PX4-T.ChSet.txt">
|
||||
<Filter>パッケージ</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="BonDriver_PX4.rc">
|
||||
<Filter>リソース ファイル</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
556
winusb/src/BonDriver_PX4/bon_driver.cpp
Normal file
556
winusb/src/BonDriver_PX4/bon_driver.cpp
Normal file
@@ -0,0 +1,556 @@
|
||||
// bon_driver.cpp
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
#include <aclapi.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include "bon_driver.hpp"
|
||||
#include "config.hpp"
|
||||
#include "chset.hpp"
|
||||
#include "pipe_client.hpp"
|
||||
#include "command.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
BonDriver::BonDriver() noexcept
|
||||
: mtx_(),
|
||||
driver_host_path_(),
|
||||
configs_(),
|
||||
name_(),
|
||||
systems_(px4::SystemType::UNSPECIFIED),
|
||||
chset_(),
|
||||
receivers_(),
|
||||
ctrl_client_(nullptr),
|
||||
data_pipe_(nullptr),
|
||||
open_(FALSE),
|
||||
space_(0),
|
||||
ch_(0),
|
||||
stream_mtx_(),
|
||||
ioq_(nullptr),
|
||||
iorp_(*this),
|
||||
current_ofs_(0),
|
||||
quit_event_(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BonDriver::~BonDriver()
|
||||
{
|
||||
CloseTuner();
|
||||
Term();
|
||||
}
|
||||
|
||||
bool BonDriver::Init()
|
||||
{
|
||||
try {
|
||||
const std::wstring &dir_path = px4::util::path::GetDir();
|
||||
|
||||
if (!configs_.Load(px4::util::path::GetFileBase() + L".ini"))
|
||||
return false;
|
||||
|
||||
if (configs_.Exists(L"BonDriver")) {
|
||||
const px4::Config &bon_config = configs_.Get(L"BonDriver");
|
||||
const std::wstring &mode = bon_config.Get(L"System", L"ISDB-T");
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
if (!px4::util::ParseSystemStr(mode, systems_))
|
||||
return false;
|
||||
|
||||
driver_host_path_ = bon_config.Get(L"DriverHostPath", dir_path + L"DriverHost_PX4.exe");
|
||||
if (PathIsRelativeW(driver_host_path_.c_str()) && PathCanonicalizeW(path, (dir_path + driver_host_path_).c_str()))
|
||||
driver_host_path_ = path;
|
||||
|
||||
name_ = bon_config.Get(L"Name", L"PX4");
|
||||
} else {
|
||||
systems_ = px4::SystemType::ISDB_T;
|
||||
driver_host_path_ = dir_path + L"DriverHost_PX4.exe";
|
||||
name_ = L"PX4";
|
||||
}
|
||||
|
||||
if ((systems_ & px4::SystemType::ISDB_T) == px4::SystemType::ISDB_T) {
|
||||
px4::ChannelSet chset_t;
|
||||
bool result;
|
||||
|
||||
try {
|
||||
result = chset_t.Load(configs_.Get(L"BonDriver.ISDB-T").Get(L"ChSetPath"), px4::SystemType::ISDB_T);
|
||||
} catch (const std::out_of_range&) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
chset_t.Clear();
|
||||
result = chset_t.Load(L".\\BonDriver_PX4-T.ChSet.txt", px4::SystemType::ISDB_T);
|
||||
}
|
||||
|
||||
if (result)
|
||||
chset_.Merge(chset_t);
|
||||
}
|
||||
|
||||
if ((systems_ & px4::SystemType::ISDB_S) == px4::SystemType::ISDB_S) {
|
||||
px4::ChannelSet chset_s;
|
||||
bool result;
|
||||
|
||||
try {
|
||||
result = chset_s.Load(configs_.Get(L"BonDriver.ISDB-S").Get(L"ChSetPath"), px4::SystemType::ISDB_S);
|
||||
} catch (const std::out_of_range&) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
chset_s.Clear();
|
||||
result = chset_s.Load(L".\\BonDriver_PX4-S.ChSet.txt", px4::SystemType::ISDB_S);
|
||||
}
|
||||
|
||||
if (result)
|
||||
chset_.Merge(chset_s);
|
||||
}
|
||||
|
||||
receivers_.Load(configs_);
|
||||
|
||||
quit_event_ = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!quit_event_)
|
||||
return false;
|
||||
|
||||
ioq_.reset(new px4::IoQueue(px4::IoQueue::IoOperation::READ, iorp_, 188 * 2048, 32, 2));
|
||||
} catch (const std::runtime_error &e) {
|
||||
MessageBoxA(nullptr, e.what(), "BonDriver_PX4 (BonDriver::Init)", MB_OK);
|
||||
return false;
|
||||
} catch (...) {
|
||||
MessageBoxA(nullptr, "Fatal error!", "BonDriver_PX4 (BonDriver::Init)", MB_OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BonDriver::Term() noexcept
|
||||
{
|
||||
ioq_.reset();
|
||||
|
||||
if (quit_event_)
|
||||
CloseHandle(quit_event_);
|
||||
}
|
||||
|
||||
const BOOL BonDriver::OpenTuner()
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (open_)
|
||||
return TRUE;
|
||||
|
||||
try {
|
||||
SID_IDENTIFIER_AUTHORITY sia;
|
||||
PSID sid = nullptr;
|
||||
EXPLICIT_ACCESSW ea;
|
||||
PACL acl = nullptr;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
HANDLE startup_event;
|
||||
DWORD st;
|
||||
|
||||
sia = SECURITY_WORLD_SID_AUTHORITY;
|
||||
|
||||
if (!AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sid))
|
||||
throw BonDriverError("BonDriver::OpenTuner: AllocateAndInitializeSid() failed.");
|
||||
|
||||
memset(&ea, 0, sizeof(ea));
|
||||
ea.grfAccessPermissions = EVENT_ALL_ACCESS;
|
||||
ea.grfAccessMode = SET_ACCESS;
|
||||
ea.grfInheritance = NO_INHERITANCE;
|
||||
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
||||
ea.Trustee.ptstrName = (LPWSTR)sid;
|
||||
|
||||
if (SetEntriesInAclW(1, &ea, nullptr, &acl) != ERROR_SUCCESS) {
|
||||
LocalFree(sid);
|
||||
throw BonDriverError("BonDriver::OpenTuner: SetEntriesInAclW() failed.");
|
||||
}
|
||||
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE);
|
||||
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
startup_event = CreateEventW(&sa, TRUE, FALSE, L"DriverHost_PX4_StartupEvent");
|
||||
|
||||
LocalFree(acl);
|
||||
LocalFree(sid);
|
||||
|
||||
if (!startup_event) {
|
||||
throw BonDriverError("BonDriver::OpenTuner: CreateEventW(\"DriverHost_PX4_StartupEvent\") failed.");
|
||||
} else if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
|
||||
if (!CreateProcessW(driver_host_path_.c_str(), nullptr, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi)) {
|
||||
CloseHandle(startup_event);
|
||||
throw BonDriverError("BonDriver::OpenTuner: CreateProcessW() failed.");
|
||||
}
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
|
||||
st = WaitForSingleObject(startup_event, 10000);
|
||||
CloseHandle(startup_event);
|
||||
|
||||
if (st != WAIT_OBJECT_0)
|
||||
throw BonDriverError("BonDriver::OpenTuner: WaitForSingleObject() failed.");
|
||||
|
||||
std::unique_ptr<px4::PipeClient> ctrl_pipe(new px4::PipeClient());
|
||||
px4::PipeClient::PipeClientConfig ctrl_pipe_config;
|
||||
px4::command::ReceiverInfo ri_res;
|
||||
|
||||
ctrl_pipe_config.stream_read = false;
|
||||
ctrl_pipe_config.timeout = 2000;
|
||||
|
||||
if (!ctrl_pipe->Connect(L"px4_ctrl_pipe", ctrl_pipe_config, nullptr)) {
|
||||
throw BonDriverError("BonDriver::OpenTuner: control pipe: cannot connect.");
|
||||
}
|
||||
|
||||
ctrl_client_.SetPipe(ctrl_pipe);
|
||||
|
||||
for (std::size_t i = 0; ; i++) {
|
||||
const px4::command::ReceiverInfo &ri = receivers_.Get(i);
|
||||
|
||||
if (ctrl_client_.Open(ri, systems_, &ri_res))
|
||||
break;
|
||||
}
|
||||
|
||||
px4::PipeClient::PipeClientConfig data_pipe_config;
|
||||
|
||||
data_pipe_config.stream_read = true;
|
||||
data_pipe_config.timeout = 2000;
|
||||
|
||||
data_pipe_.reset(new px4::PipeClient());
|
||||
|
||||
if (!data_pipe_->Connect(L"px4_data_pipe", data_pipe_config, nullptr)) {
|
||||
throw BonDriverError("BonDriver::OpenTuner: data pipe: cannot connect.");
|
||||
}
|
||||
|
||||
px4::command::DataCmd data_cmd;
|
||||
std::size_t ret_size;
|
||||
|
||||
data_cmd.cmd = px4::command::DataCmdCode::SET_DATA_ID;
|
||||
data_cmd.data_id = ri_res.data_id;
|
||||
|
||||
if (!data_pipe_->Write(&data_cmd, sizeof(data_cmd), ret_size)) {
|
||||
data_pipe_.reset();
|
||||
ctrl_client_.Close();
|
||||
ctrl_client_.ClearPipe();
|
||||
throw BonDriverError("BonDriver::OpenTuner: command failed.");
|
||||
}
|
||||
|
||||
if (!ctrl_client_.SetCapture(true)) {
|
||||
data_pipe_.reset();
|
||||
ctrl_client_.Close();
|
||||
ctrl_client_.ClearPipe();
|
||||
throw BonDriverError("BonDriver::OpenTuner: command failed.");
|
||||
}
|
||||
|
||||
ioq_->Start();
|
||||
|
||||
open_ = TRUE;
|
||||
} catch (const std::out_of_range &) {
|
||||
ret = FALSE;
|
||||
MessageBoxA(nullptr, "BonDriver::OpenTuner: cannot open.", "BonDriver_PX4 (BonDriver::OpenTuner)", MB_OK | MB_ICONERROR);
|
||||
} catch (const std::exception &e) {
|
||||
ret = FALSE;
|
||||
MessageBoxA(nullptr, e.what(), "BonDriver_PX4 (BonDriver::OpenTuner)", MB_OK | MB_ICONERROR);
|
||||
} catch (...) {
|
||||
ret = FALSE;
|
||||
MessageBoxA(nullptr, "Fatal error!", "BonDriver_PX4 (BonDriver::OpenTuner)", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
if (!open_) {
|
||||
if (data_pipe_) {
|
||||
SetEvent(quit_event_);
|
||||
ioq_->Stop();
|
||||
data_pipe_.reset();
|
||||
}
|
||||
|
||||
ctrl_client_.ClearPipe();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BonDriver::CloseTuner()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (!open_)
|
||||
return;
|
||||
|
||||
if (data_pipe_) {
|
||||
SetEvent(quit_event_);
|
||||
ioq_->Stop();
|
||||
data_pipe_.reset();
|
||||
}
|
||||
|
||||
ctrl_client_.ClearPipe();
|
||||
|
||||
space_ = 0;
|
||||
ch_ = 0;
|
||||
|
||||
open_ = FALSE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const BOOL BonDriver::SetChannel(const BYTE bCh)
|
||||
{
|
||||
return SetChannel(0, bCh);
|
||||
}
|
||||
|
||||
const float BonDriver::GetSignalLevel(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (!open_)
|
||||
return 0.0f;
|
||||
|
||||
px4::command::StatSet stat_set;
|
||||
|
||||
stat_set.num = 1;
|
||||
stat_set.data[0].type = px4::command::StatType::CNR;
|
||||
stat_set.data[0].value = 0;
|
||||
|
||||
if (!ctrl_client_.ReadStats(stat_set))
|
||||
return 0.0f;
|
||||
|
||||
return static_cast<float>(stat_set.data[0].value) / 1000.0f;
|
||||
}
|
||||
|
||||
const DWORD BonDriver::WaitTsStream(const DWORD dwTimeOut)
|
||||
{
|
||||
return (ioq_->WaitDataBuffer(std::chrono::milliseconds((dwTimeOut == INFINITE) ? 5000 : dwTimeOut))) ? WAIT_OBJECT_0 : WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
const DWORD BonDriver::GetReadyCount(void)
|
||||
{
|
||||
return static_cast<::DWORD>(ioq_->GetDataBufferCount() + (ioq_->HaveReadingBuffer() ? 1 : 0));
|
||||
}
|
||||
|
||||
const BOOL BonDriver::GetTsStream(BYTE *pDst, DWORD *pdwSize, DWORD *pdwRemain)
|
||||
{
|
||||
if (!pDst || !pdwSize)
|
||||
return FALSE;
|
||||
|
||||
std::size_t size, remain;
|
||||
|
||||
if (!ioq_->Read(pDst, size, remain, false))
|
||||
return FALSE;
|
||||
|
||||
*pdwSize = static_cast<::DWORD>(size);
|
||||
if (pdwRemain)
|
||||
*pdwRemain = static_cast<::DWORD>(remain);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const BOOL BonDriver::GetTsStream(BYTE **ppDst, DWORD *pdwSize, DWORD *pdwRemain)
|
||||
{
|
||||
if (!ppDst || !pdwSize)
|
||||
return FALSE;
|
||||
|
||||
std::size_t size, remain;
|
||||
|
||||
if (!ioq_->ReadBuffer(reinterpret_cast<void **>(ppDst), size, remain, false))
|
||||
return FALSE;
|
||||
|
||||
*pdwSize = static_cast<::DWORD>(size);
|
||||
if (pdwRemain)
|
||||
*pdwRemain = static_cast<::DWORD>(remain);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BonDriver::PurgeTsStream(void)
|
||||
{
|
||||
ioq_->PurgeDataBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
void BonDriver::Release(void)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
LPCTSTR BonDriver::GetTunerName(void)
|
||||
{
|
||||
return name_.c_str();
|
||||
}
|
||||
|
||||
const BOOL BonDriver::IsTunerOpening(void)
|
||||
{
|
||||
return open_;
|
||||
}
|
||||
|
||||
LPCTSTR BonDriver::EnumTuningSpace(const DWORD dwSpace)
|
||||
{
|
||||
try {
|
||||
return chset_.GetSpaceName(dwSpace).c_str();
|
||||
} catch (const std::out_of_range&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LPCTSTR BonDriver::EnumChannelName(const DWORD dwSpace, const DWORD dwChannel)
|
||||
{
|
||||
try {
|
||||
return chset_.GetChannel(dwSpace, dwChannel).name.c_str();
|
||||
} catch (const std::out_of_range&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const BOOL BonDriver::SetChannel(const DWORD dwSpace, const DWORD dwChannel)
|
||||
{
|
||||
if (!open_)
|
||||
return FALSE;
|
||||
|
||||
if (!chset_.ExistsChannel(dwSpace, dwChannel))
|
||||
return FALSE;
|
||||
|
||||
const px4::ChannelSet::ChannelInfo &channel = chset_.GetChannel(dwSpace, dwChannel);
|
||||
px4::SystemType system = chset_.GetSpaceSystem(dwSpace);
|
||||
std::uint32_t real_freq, num_param = 0;
|
||||
|
||||
switch (system) {
|
||||
case px4::SystemType::ISDB_T:
|
||||
if ((channel.ptx_ch >= 3 && channel.ptx_ch <= 12) || (channel.ptx_ch >= 22 && channel.ptx_ch <= 62)) {
|
||||
// CATV C13-22ch, C23-63ch
|
||||
real_freq = 93143 + (channel.ptx_ch * 6000);
|
||||
|
||||
if (channel.ptx_ch == 12)
|
||||
real_freq += 2000;
|
||||
} else if (channel.ptx_ch >= 63 && channel.ptx_ch <= 112) {
|
||||
// UHF 13-62ch
|
||||
real_freq = 95143 + (channel.ptx_ch * 6000);
|
||||
} else {
|
||||
// unknown channel
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case px4::SystemType::ISDB_S:
|
||||
if (channel.ptx_ch <= 11) {
|
||||
// BS
|
||||
real_freq = 1049480 + (channel.ptx_ch * 38360);
|
||||
} else if (channel.ptx_ch <= 23) {
|
||||
// CS 110
|
||||
real_freq = 1613000 + ((channel.ptx_ch - 12) * 40000);
|
||||
} else {
|
||||
// unknown channel
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
num_param = 1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown system
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
px4::command::ParameterSet *param_set = reinterpret_cast<px4::command::ParameterSet*>(new std::uint8_t[sizeof(*param_set) - sizeof(param_set->params) + (sizeof(param_set->params[0]) * num_param)]);
|
||||
|
||||
param_set->system = system;
|
||||
param_set->freq = real_freq;
|
||||
param_set->num = num_param;
|
||||
|
||||
if (system == px4::SystemType::ISDB_S && num_param) {
|
||||
param_set->params[0].type = px4::command::ParameterType::STREAM_ID;
|
||||
param_set->params[0].value = channel.tsid;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
||||
try {
|
||||
ret = ctrl_client_.SetParams(*param_set);
|
||||
if (ret)
|
||||
ret = ctrl_client_.Tune();
|
||||
} catch (const std::exception &e) {
|
||||
MessageBoxA(nullptr, e.what(), "BonDriver_PX4 (BonDriver::SetChannel)", MB_OK | MB_ICONERROR);
|
||||
} catch (...) {
|
||||
MessageBoxA(nullptr, "Fatal error!", "BonDriver_PX4 (BonDriver::SetChannel)", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
delete[] reinterpret_cast<std::uint8_t*>(param_set);
|
||||
|
||||
if (ret) {
|
||||
// succeeded
|
||||
space_ = dwSpace;
|
||||
ch_ = dwChannel;
|
||||
}
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
const DWORD BonDriver::GetCurSpace(void)
|
||||
{
|
||||
return space_;
|
||||
}
|
||||
|
||||
const DWORD BonDriver::GetCurChannel(void)
|
||||
{
|
||||
return ch_;
|
||||
}
|
||||
|
||||
bool BonDriver::ReadProvider::Start()
|
||||
{
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BonDriver::ReadProvider::Stop()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool BonDriver::ReadProvider::Do(void *buf, std::size_t &size)
|
||||
{
|
||||
return parent_.data_pipe_->Read(buf, size, size, parent_.quit_event_);
|
||||
}
|
||||
|
||||
} // namespace px4
|
||||
|
||||
#pragma warning(disable: 4273)
|
||||
extern "C" IBonDriver* CreateBonDriver()
|
||||
{
|
||||
try {
|
||||
auto bon = new px4::BonDriver();
|
||||
|
||||
if (!bon)
|
||||
return nullptr;
|
||||
|
||||
if (!bon->Init()) {
|
||||
delete bon;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return bon;
|
||||
} catch (const std::exception &e) {
|
||||
MessageBoxA(nullptr, e.what(), "BonDriver_PX4 (CreateBonDriver)", MB_ICONERROR | MB_OK);
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
MessageBoxA(nullptr, "Fatal error!", "BonDriver_PX4 (CreateBonDriver)", MB_ICONERROR | MB_OK);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#pragma warning(default: 4273)
|
101
winusb/src/BonDriver_PX4/bon_driver.hpp
Normal file
101
winusb/src/BonDriver_PX4/bon_driver.hpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// bon_driver.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "IBonDriver2.h"
|
||||
#include "config.hpp"
|
||||
#include "chset.hpp"
|
||||
#include "receiver_info_set.hpp"
|
||||
#include "pipe_client.hpp"
|
||||
#include "command.hpp"
|
||||
#include "cmd_client.hpp"
|
||||
#include "io_queue.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class BonDriver final : public IBonDriver2 {
|
||||
public:
|
||||
BonDriver() noexcept;
|
||||
~BonDriver();
|
||||
|
||||
bool Init();
|
||||
void Term() noexcept;
|
||||
|
||||
// IBonDriver
|
||||
const BOOL OpenTuner(void) override;
|
||||
void CloseTuner(void) override;
|
||||
|
||||
const BOOL SetChannel(const BYTE bCh) override;
|
||||
const float GetSignalLevel(void) override;
|
||||
|
||||
const DWORD WaitTsStream(const DWORD dwTimeOut = 0) override;
|
||||
const DWORD GetReadyCount(void) override;
|
||||
|
||||
const BOOL GetTsStream(BYTE *pDst, DWORD *pdwSize, DWORD *pdwRemain) override;
|
||||
const BOOL GetTsStream(BYTE **ppDst, DWORD *pdwSize, DWORD *pdwRemain) override;
|
||||
|
||||
void PurgeTsStream(void) override;
|
||||
|
||||
void Release(void) override;
|
||||
|
||||
// IBonDriver2
|
||||
LPCTSTR GetTunerName(void) override;
|
||||
|
||||
const BOOL IsTunerOpening(void) override;
|
||||
|
||||
LPCTSTR EnumTuningSpace(const DWORD dwSpace) override;
|
||||
LPCTSTR EnumChannelName(const DWORD dwSpace, const DWORD dwChannel) override;
|
||||
|
||||
const BOOL SetChannel(const DWORD dwSpace, const DWORD dwChannel) override;
|
||||
|
||||
const DWORD GetCurSpace(void) override;
|
||||
const DWORD GetCurChannel(void) override;
|
||||
|
||||
private:
|
||||
class ReadProvider final : public IoQueue::IoProvider {
|
||||
public:
|
||||
explicit ReadProvider(BonDriver& parent) : parent_(parent) {}
|
||||
~ReadProvider() {}
|
||||
|
||||
bool Start() override;
|
||||
void Stop() override;
|
||||
bool Do(void *buf, std::size_t &size) override;
|
||||
|
||||
private:
|
||||
BonDriver &parent_;
|
||||
};
|
||||
|
||||
std::mutex mtx_;
|
||||
std::wstring driver_host_path_;
|
||||
px4::ConfigSet configs_;
|
||||
std::wstring name_;
|
||||
px4::SystemType systems_;
|
||||
px4::ChannelSet chset_;
|
||||
px4::ReceiverInfoSet receivers_;
|
||||
px4::CtrlCmdClient ctrl_client_;
|
||||
std::unique_ptr<px4::PipeClient> data_pipe_;
|
||||
BOOL open_;
|
||||
DWORD space_, ch_;
|
||||
|
||||
std::mutex stream_mtx_;
|
||||
std::unique_ptr<px4::IoQueue> ioq_;
|
||||
ReadProvider iorp_;
|
||||
std::size_t current_ofs_;
|
||||
HANDLE quit_event_;
|
||||
};
|
||||
|
||||
class BonDriverError : public std::runtime_error {
|
||||
public:
|
||||
explicit BonDriverError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
213
winusb/src/BonDriver_PX4/chset.cpp
Normal file
213
winusb/src/BonDriver_PX4/chset.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
// chset.cpp
|
||||
|
||||
#include "chset.hpp"
|
||||
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
bool ChannelSet::Load(const std::wstring &path, px4::SystemType system) noexcept
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock(mtx_);
|
||||
std::ifstream ifs(path);
|
||||
|
||||
if (!ifs.is_open())
|
||||
return false;
|
||||
|
||||
std::unordered_map<std::uint32_t, std::uint32_t> space_id_table;
|
||||
|
||||
while (true) {
|
||||
char line[256];
|
||||
std::streamsize gcount;
|
||||
char *tmp_head, *tmp_tail = nullptr;
|
||||
|
||||
if (!ifs.getline(line, 256))
|
||||
break;
|
||||
|
||||
gcount = ifs.gcount();
|
||||
if (!gcount)
|
||||
continue;
|
||||
|
||||
if (line[gcount] == '\r') {
|
||||
// CRLF
|
||||
line[gcount] = '\0';
|
||||
gcount--;
|
||||
}
|
||||
|
||||
if (line[0] == ';') {
|
||||
// comment
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '$') {
|
||||
// tuning space
|
||||
std::wstring name;
|
||||
std::uint32_t space_id;
|
||||
|
||||
tmp_head = line + 1;
|
||||
|
||||
// name
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
px4::util::ShiftJisToUtf16(tmp_head, name);
|
||||
|
||||
// space
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
space_id = px4::util::atoui(tmp_head);
|
||||
|
||||
space_id_table.emplace(space_id, next_space_id_);
|
||||
|
||||
if (!AddSpace(next_space_id_++, &name, system))
|
||||
return false;
|
||||
} else {
|
||||
// channel
|
||||
std::uint32_t space_id, ch_id;
|
||||
ChannelInfo ch;
|
||||
|
||||
tmp_head = line;
|
||||
|
||||
// name
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
px4::util::ShiftJisToUtf16(tmp_head, ch.name);
|
||||
|
||||
// space
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
space_id = px4::util::atoui(tmp_head);
|
||||
|
||||
try {
|
||||
space_id = space_id_table.at(space_id);
|
||||
} catch (const std::out_of_range&) {
|
||||
if (strict_)
|
||||
return false;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
// ch
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
ch_id = px4::util::atoui(tmp_head);
|
||||
|
||||
// ptx_ch
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
ch.ptx_ch = px4::util::atoui(tmp_head);
|
||||
|
||||
// tsid
|
||||
Split(&tmp_head, &tmp_tail, '\t');
|
||||
ch.tsid = static_cast<std::uint16_t>(px4::util::atoui(tmp_head));
|
||||
|
||||
if (!AddChannel(space_id, ch_id, ch))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChannelSet::Merge(ChannelSet &chset) noexcept
|
||||
{
|
||||
// TODO: Space ID<49><44><EFBFBD><EFBFBD><EFBFBD>炷
|
||||
try {
|
||||
for (auto it = chset.spaces_.cbegin(); it != chset.spaces_.cend(); ++it)
|
||||
spaces_.emplace_back(*it);
|
||||
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ChannelSet::ExistsSpace(std::uint32_t space_id) const noexcept
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
return (spaces_.size() > space_id);
|
||||
}
|
||||
|
||||
const std::wstring& ChannelSet::GetSpaceName(std::uint32_t space_id) const
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
return spaces_.at(space_id).name;
|
||||
}
|
||||
|
||||
px4::SystemType ChannelSet::GetSpaceSystem(std::uint32_t space_id) const
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
return spaces_.at(space_id).system;
|
||||
}
|
||||
|
||||
bool ChannelSet::ExistsChannel(std::uint32_t space_id, std::uint32_t ch_id) const noexcept
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
try {
|
||||
return !!spaces_.at(space_id).channels.count(ch_id);
|
||||
} catch (const std::out_of_range&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const px4::ChannelSet::ChannelInfo& ChannelSet::GetChannel(std::uint32_t space_id, std::uint32_t ch_id) const
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
return spaces_.at(space_id).channels.at(ch_id);
|
||||
}
|
||||
|
||||
bool ChannelSet::AddSpace(std::uint32_t space_id, const std::wstring *name, px4::SystemType system) noexcept
|
||||
{
|
||||
if (spaces_.size() > space_id) {
|
||||
auto& space = spaces_.at(space_id);
|
||||
|
||||
if (name && space.name.empty())
|
||||
space.name = *name;
|
||||
|
||||
if (space.system == px4::SystemType::UNSPECIFIED)
|
||||
space.system = system;
|
||||
} else if (name) {
|
||||
spaces_.emplace_back(SpaceInfo(*name, system));
|
||||
} else if (!strict_) {
|
||||
spaces_.emplace_back(SpaceInfo(system));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChannelSet::AddChannel(std::uint32_t space_id, std::uint32_t ch_id, const ChannelInfo &ch) noexcept
|
||||
{
|
||||
if (!AddSpace(space_id, nullptr))
|
||||
return false;
|
||||
|
||||
auto& space = spaces_.at(space_id);
|
||||
|
||||
if (space.channels.count(ch_id))
|
||||
space.channels.at(ch_id) = ch;
|
||||
else
|
||||
space.channels.emplace(ch_id, ch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChannelSet::Split(char **head, char **tail, char c) noexcept
|
||||
{
|
||||
char *h = *head, *t = *tail;
|
||||
|
||||
if (t)
|
||||
h = t + 1;
|
||||
|
||||
t = std::strchr(h, c);
|
||||
if (t)
|
||||
*t = '\0';
|
||||
|
||||
*head = h;
|
||||
*tail = t;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace px4
|
59
winusb/src/BonDriver_PX4/chset.hpp
Normal file
59
winusb/src/BonDriver_PX4/chset.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// chset.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "type.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class ChannelSet final {
|
||||
public:
|
||||
struct ChannelInfo final {
|
||||
ChannelInfo() noexcept : ptx_ch(0), tsid(0) {}
|
||||
std::wstring name;
|
||||
std::uint32_t ptx_ch;
|
||||
std::uint16_t tsid;
|
||||
};
|
||||
struct SpaceInfo final {
|
||||
explicit SpaceInfo(px4::SystemType system = px4::SystemType::UNSPECIFIED) noexcept : SpaceInfo(L"", system) {}
|
||||
explicit SpaceInfo(const std::wstring &name, px4::SystemType system = px4::SystemType::UNSPECIFIED) noexcept
|
||||
: name(name),
|
||||
system(system)
|
||||
{}
|
||||
std::wstring name;
|
||||
px4::SystemType system;
|
||||
std::unordered_map<std::uint32_t, ChannelInfo> channels;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit ChannelSet(bool strict = false) noexcept : next_space_id_(0) { SetStrict(strict); }
|
||||
~ChannelSet() {}
|
||||
|
||||
void SetStrict(bool strict) noexcept { strict_ = strict; }
|
||||
void Clear() noexcept { spaces_.clear(); next_space_id_ = 0; }
|
||||
bool Load(const std::wstring &path, px4::SystemType system) noexcept;
|
||||
bool Merge(ChannelSet &chset) noexcept;
|
||||
bool ExistsSpace(std::uint32_t space_id) const noexcept;
|
||||
const std::wstring& GetSpaceName(std::uint32_t space_id) const;
|
||||
px4::SystemType GetSpaceSystem(std::uint32_t space_id) const;
|
||||
bool ExistsChannel(std::uint32_t space_id, std::uint32_t ch_id) const noexcept;
|
||||
const ChannelInfo& GetChannel(std::uint32_t space_id, std::uint32_t ch_id) const;
|
||||
|
||||
private:
|
||||
bool AddSpace(uint32_t space_id, const std::wstring *name, px4::SystemType system = px4::SystemType::UNSPECIFIED) noexcept;
|
||||
bool AddChannel(uint32_t space_id, uint32_t ch_id, const ChannelInfo& ch) noexcept;
|
||||
static void Split(char **head, char **tail, char c) noexcept;
|
||||
|
||||
bool strict_;
|
||||
mutable std::shared_mutex mtx_;
|
||||
std::uint32_t next_space_id_;
|
||||
std::vector<SpaceInfo> spaces_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
152
winusb/src/BonDriver_PX4/cmd_client.cpp
Normal file
152
winusb/src/BonDriver_PX4/cmd_client.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
// cmd_client.cpp
|
||||
|
||||
#include "cmd_client.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
bool CtrlCmdClient::Open(const px4::command::ReceiverInfo &in, px4::SystemType systems, px4::command::ReceiverInfo *out) noexcept
|
||||
{
|
||||
px4::command::CtrlOpenCmd open_cmd;
|
||||
|
||||
if ((systems & in.systems) == px4::SystemType::UNSPECIFIED)
|
||||
return false;
|
||||
|
||||
open_cmd.cmd = px4::command::CtrlCmdCode::OPEN;
|
||||
open_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
wcscpy_s(open_cmd.receiver_info.device_name, in.device_name);
|
||||
open_cmd.receiver_info.device_guid = in.device_guid;
|
||||
wcscpy_s(open_cmd.receiver_info.receiver_name, in.receiver_name);
|
||||
open_cmd.receiver_info.receiver_guid = in.receiver_guid;
|
||||
open_cmd.receiver_info.systems = systems & in.systems;
|
||||
open_cmd.receiver_info.index = in.index;
|
||||
open_cmd.receiver_info.data_id = 0;
|
||||
|
||||
bool ret = Call(open_cmd);
|
||||
|
||||
if (out)
|
||||
*out = open_cmd.receiver_info;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::Close() noexcept
|
||||
{
|
||||
px4::command::CtrlCloseCmd close_cmd;
|
||||
|
||||
close_cmd.cmd = px4::command::CtrlCmdCode::CLOSE;
|
||||
close_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
|
||||
return Call(close_cmd);
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::GetInfo(px4::command::ReceiverInfo &receiver_info) noexcept
|
||||
{
|
||||
px4::command::CtrlReceiverInfoCmd info_cmd;
|
||||
|
||||
info_cmd.cmd = px4::command::CtrlCmdCode::GET_INFO;
|
||||
info_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
info_cmd.receiver_info = receiver_info;
|
||||
|
||||
bool ret = Call(info_cmd);
|
||||
|
||||
if (ret)
|
||||
receiver_info = info_cmd.receiver_info;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::SetCapture(bool capture) noexcept
|
||||
{
|
||||
px4::command::CtrlCaptureCmd capture_cmd;
|
||||
|
||||
capture_cmd.cmd = px4::command::CtrlCmdCode::SET_CAPTURE;
|
||||
capture_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
capture_cmd.capture = capture;
|
||||
|
||||
return Call(capture_cmd);
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::GetParams(px4::command::ParameterSet ¶m_set) noexcept
|
||||
{
|
||||
px4::command::CtrlParamsCmd params_cmd;
|
||||
|
||||
params_cmd.cmd = px4::command::CtrlCmdCode::GET_PARAMS;
|
||||
params_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
params_cmd.param_set = param_set;
|
||||
|
||||
bool ret = Call(params_cmd);
|
||||
|
||||
if (ret)
|
||||
param_set = params_cmd.param_set;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::SetParams(const px4::command::ParameterSet ¶m_set) noexcept
|
||||
{
|
||||
px4::command::CtrlParamsCmd params_cmd;
|
||||
|
||||
params_cmd.cmd = px4::command::CtrlCmdCode::SET_PARAMS;
|
||||
params_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
params_cmd.param_set = param_set;
|
||||
|
||||
return Call(params_cmd);
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::ClearParams() noexcept
|
||||
{
|
||||
px4::command::CtrlClearParamsCmd clear_cmd;
|
||||
|
||||
clear_cmd.cmd = px4::command::CtrlCmdCode::CLEAR_PARAMS;
|
||||
clear_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
|
||||
return Call(clear_cmd);
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::Tune() noexcept
|
||||
{
|
||||
px4::command::CtrlTuneCmd tune_cmd;
|
||||
|
||||
tune_cmd.cmd = px4::command::CtrlCmdCode::TUNE;
|
||||
tune_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
|
||||
return Call(tune_cmd);
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::SetLnbVoltage(std::int32_t voltage) noexcept
|
||||
{
|
||||
px4::command::CtrlLnbVoltageCmd lnb_cmd;
|
||||
|
||||
lnb_cmd.cmd = px4::command::CtrlCmdCode::SET_LNB_VOLTAGE;
|
||||
lnb_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
lnb_cmd.voltage = voltage;
|
||||
|
||||
return Call(lnb_cmd);
|
||||
}
|
||||
|
||||
bool CtrlCmdClient::ReadStats(px4::command::StatSet &stat_set) noexcept
|
||||
{
|
||||
px4::command::CtrlStatsCmd stat_cmd;
|
||||
|
||||
stat_cmd.cmd = px4::command::CtrlCmdCode::READ_STATS;
|
||||
stat_cmd.status = px4::command::CtrlStatusCode::NONE;
|
||||
stat_cmd.stat_set = stat_set;
|
||||
|
||||
bool ret = Call(stat_cmd);
|
||||
|
||||
if (ret)
|
||||
stat_set = stat_cmd.stat_set;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool CtrlCmdClient::Call(T& cmd) noexcept
|
||||
{
|
||||
if (!pipe_)
|
||||
return false;
|
||||
|
||||
return (pipe_->Call(&cmd, sizeof(cmd)) && cmd.status == px4::command::CtrlStatusCode::SUCCEEDED);
|
||||
}
|
||||
|
||||
} // namespace px4
|
47
winusb/src/BonDriver_PX4/cmd_client.hpp
Normal file
47
winusb/src/BonDriver_PX4/cmd_client.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// cmd_client.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "command.hpp"
|
||||
#include "pipe.hpp"
|
||||
#include "pipe_client.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class CtrlCmdClient final {
|
||||
public:
|
||||
explicit CtrlCmdClient(px4::PipeClient *pipe = nullptr) noexcept : pipe_(pipe) {}
|
||||
~CtrlCmdClient() {}
|
||||
|
||||
// cannot copy
|
||||
CtrlCmdClient(const CtrlCmdClient &) = delete;
|
||||
CtrlCmdClient& operator=(const CtrlCmdClient &) = delete;
|
||||
|
||||
// cannot move
|
||||
CtrlCmdClient(CtrlCmdClient &&) = delete;
|
||||
CtrlCmdClient& operator=(CtrlCmdClient &&) = delete;
|
||||
|
||||
void SetPipe(px4::PipeClient *pipe) noexcept { pipe_.reset(pipe); }
|
||||
void SetPipe(std::unique_ptr<px4::PipeClient> &pipe) noexcept { pipe_ = std::move(pipe); }
|
||||
void ClearPipe() noexcept { pipe_.reset(); }
|
||||
|
||||
bool Open(const px4::command::ReceiverInfo &in, px4::SystemType systems, px4::command::ReceiverInfo *out) noexcept;
|
||||
bool Close() noexcept;
|
||||
bool GetInfo(px4::command::ReceiverInfo &receiver_info) noexcept;
|
||||
bool SetCapture(bool capture) noexcept;
|
||||
bool GetParams(px4::command::ParameterSet ¶m_set) noexcept;
|
||||
bool SetParams(const px4::command::ParameterSet ¶m_set) noexcept;
|
||||
bool ClearParams() noexcept;
|
||||
bool Tune() noexcept;
|
||||
bool SetLnbVoltage(std::int32_t voltage) noexcept;
|
||||
bool ReadStats(px4::command::StatSet& stat_set) noexcept;
|
||||
|
||||
private:
|
||||
template <typename T> bool Call(T &cmd) noexcept;
|
||||
|
||||
std::unique_ptr<px4::PipeClient> pipe_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
3
winusb/src/BonDriver_PX4/dll.def
Normal file
3
winusb/src/BonDriver_PX4/dll.def
Normal file
@@ -0,0 +1,3 @@
|
||||
LIBRARY BonDriver_PX4
|
||||
EXPORTS
|
||||
CreateBonDriver
|
22
winusb/src/BonDriver_PX4/dllmain.cpp
Normal file
22
winusb/src/BonDriver_PX4/dllmain.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
// dllmain.cpp
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (!px4::util::path::Init(hinstDLL))
|
||||
ret = FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
417
winusb/src/BonDriver_PX4/io_queue.cpp
Normal file
417
winusb/src/BonDriver_PX4/io_queue.cpp
Normal file
@@ -0,0 +1,417 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* I/O queue operator (io_queue.cpp)
|
||||
*
|
||||
* Copyright (c) 2021 nns779
|
||||
*/
|
||||
|
||||
#include "io_queue.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
IoQueue::IoQueue(IoOperation io_op, IoProvider &iop, std::size_t buf_size, std::uintptr_t max, std::uintptr_t min)
|
||||
: io_op_(io_op),
|
||||
iop_(iop),
|
||||
buf_size_(buf_size),
|
||||
max_(max),
|
||||
min_(min),
|
||||
total_buf_num_(0),
|
||||
current_ofs_(0)
|
||||
{
|
||||
while (min--)
|
||||
IncreaseFreeBuffer();
|
||||
}
|
||||
|
||||
IoQueue::~IoQueue()
|
||||
{
|
||||
Stop();
|
||||
data_buf_.clear();
|
||||
free_buf_.clear();
|
||||
}
|
||||
|
||||
bool IoQueue::Start()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (th_)
|
||||
return true;
|
||||
|
||||
std::unique_lock<std::mutex> free_lock(free_mtx_);
|
||||
std::unique_lock<std::mutex> data_lock(data_mtx_);
|
||||
|
||||
for (auto it = free_buf_.begin(); it != free_buf_.end();) {
|
||||
if (!*it)
|
||||
it = free_buf_.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if (current_buf_) {
|
||||
free_buf_.push_back(std::move(current_buf_));
|
||||
current_ofs_ = 0;
|
||||
}
|
||||
|
||||
while (!data_buf_.empty()) {
|
||||
auto buf = std::move(data_buf_.front());
|
||||
data_buf_.pop_front();
|
||||
|
||||
if (!buf)
|
||||
continue;
|
||||
|
||||
free_buf_.push_back(std::move(buf));
|
||||
}
|
||||
|
||||
free_lock.unlock();
|
||||
free_cond_.notify_all();
|
||||
|
||||
data_lock.unlock();
|
||||
|
||||
th_.reset(new std::thread((io_op_ == IoOperation::READ) ? &px4::IoQueue::ReadWorker : &px4::IoQueue::WriteWorker, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoQueue::Stop()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (!th_)
|
||||
return true;
|
||||
|
||||
if (io_op_ == IoOperation::READ) {
|
||||
// stop ReadWorker
|
||||
PushBackFreeBuffer(nullptr);
|
||||
} else {
|
||||
if (current_buf_) {
|
||||
// flush
|
||||
PushBackDataBuffer(std::move(current_buf_));
|
||||
current_ofs_ = 0;
|
||||
}
|
||||
|
||||
// stop WriteWorker
|
||||
PushBackDataBuffer(nullptr);
|
||||
}
|
||||
|
||||
try {
|
||||
th_->join();
|
||||
} catch (...) {}
|
||||
|
||||
th_.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t IoQueue::GetDataBufferCount() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(data_mtx_);
|
||||
|
||||
return data_buf_.size();
|
||||
}
|
||||
|
||||
std::size_t IoQueue::GetFreeBufferCount() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(free_mtx_);
|
||||
|
||||
return free_buf_.size();
|
||||
}
|
||||
|
||||
bool IoQueue::WaitDataBuffer(std::chrono::milliseconds ms)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
std::unique_lock<std::mutex> data_lock(data_mtx_);
|
||||
|
||||
if (data_buf_.size())
|
||||
return true;
|
||||
|
||||
if (ms.count()) {
|
||||
if (data_cond_.wait_for(data_lock, ms) == std::cv_status::timeout)
|
||||
return false;
|
||||
} else {
|
||||
data_cond_.wait(data_lock);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IoQueue::PurgeDataBuffer()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
std::unique_lock<std::mutex> free_lock(free_mtx_);
|
||||
std::lock_guard<std::mutex> data_lock(data_mtx_);
|
||||
|
||||
if (current_buf_) {
|
||||
free_buf_.push_back(std::move(current_buf_));
|
||||
current_ofs_ = 0;
|
||||
}
|
||||
|
||||
while (!data_buf_.empty()) {
|
||||
auto buf = std::move(data_buf_.front());
|
||||
data_buf_.pop_front();
|
||||
|
||||
free_buf_.push_back(std::move(buf));
|
||||
}
|
||||
|
||||
free_lock.unlock();
|
||||
free_cond_.notify_all();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool IoQueue::Read(void *buf, std::size_t &size, std::size_t &remain_count, bool blocking)
|
||||
{
|
||||
if (io_op_ != IoOperation::READ)
|
||||
return false;
|
||||
|
||||
bool ret = false;
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
std::uint8_t *p = static_cast<std::uint8_t*>(buf);
|
||||
std::size_t remain = size;
|
||||
|
||||
while (remain) {
|
||||
if (!current_buf_) {
|
||||
current_buf_ = PopFrontDataBuffer(blocking);
|
||||
if (!current_buf_)
|
||||
break;
|
||||
}
|
||||
|
||||
auto buf = current_buf_.get();
|
||||
std::size_t rlen = ((buf->actual_length - current_ofs_) < remain) ? (buf->actual_length - current_ofs_) : remain;
|
||||
|
||||
std::memcpy(p, buf->buf.get() + current_ofs_, rlen);
|
||||
|
||||
current_ofs_ += rlen;
|
||||
p += rlen;
|
||||
remain -= rlen;
|
||||
|
||||
ret = true;
|
||||
|
||||
if (buf->actual_length == current_ofs_) {
|
||||
PushBackFreeBuffer(std::move(current_buf_));
|
||||
current_ofs_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size -= remain;
|
||||
remain_count = GetDataBufferCount() + ((current_buf_) ? 1 : 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IoQueue::ReadBuffer(void **buf, std::size_t &size, std::size_t &remain_count, bool blocking)
|
||||
{
|
||||
if (io_op_ != IoOperation::READ)
|
||||
return false;
|
||||
|
||||
remain_count = 0;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (current_buf_ && current_buf_->actual_length == current_ofs_) {
|
||||
PushBackFreeBuffer(std::move(current_buf_));
|
||||
current_ofs_ = 0;
|
||||
}
|
||||
|
||||
if (!current_buf_) {
|
||||
current_buf_ = PopFrontDataBuffer(blocking);
|
||||
if (!current_buf_)
|
||||
return false;
|
||||
}
|
||||
|
||||
*buf = current_buf_->buf.get() + current_ofs_;
|
||||
size = current_buf_->actual_length - current_ofs_;
|
||||
current_ofs_ = current_buf_->actual_length;
|
||||
remain_count = GetDataBufferCount();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoQueue::HaveReadingBuffer()
|
||||
{
|
||||
return !!current_buf_;
|
||||
}
|
||||
|
||||
bool IoQueue::Write(void *buf, std::size_t &size, bool blocking)
|
||||
{
|
||||
// not implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IoQueue::IncreaseFreeBuffer()
|
||||
{
|
||||
if (total_buf_num_ >= max_)
|
||||
return false;
|
||||
|
||||
auto buf = new IoBuffer;
|
||||
|
||||
buf->buf.reset(new std::uint8_t[buf_size_]);
|
||||
buf->actual_length = 0;
|
||||
|
||||
free_buf_.emplace_front(buf);
|
||||
total_buf_num_++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IoQueue::DecreaseFreeBuffer()
|
||||
{
|
||||
if (free_buf_.empty() || !free_buf_.front())
|
||||
return;
|
||||
|
||||
free_buf_.pop_front();
|
||||
total_buf_num_--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool IoQueue::PushBackDataBuffer(std::unique_ptr<IoBuffer> &&buf)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(data_mtx_);
|
||||
|
||||
data_buf_.push_back(std::move(buf));
|
||||
|
||||
lock.unlock();
|
||||
data_cond_.notify_all();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoQueue::PushBackFreeBuffer(std::unique_ptr<IoBuffer> &&buf)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(free_mtx_);
|
||||
|
||||
free_buf_.push_back(std::move(buf));
|
||||
|
||||
lock.unlock();
|
||||
free_cond_.notify_all();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<IoQueue::IoBuffer> IoQueue::PopFrontDataBuffer(bool wait)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(data_mtx_);
|
||||
|
||||
if (data_buf_.empty()) {
|
||||
if (wait) {
|
||||
do {
|
||||
data_cond_.wait(lock);
|
||||
} while (data_buf_.empty());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto buf = std::move(data_buf_.front());
|
||||
data_buf_.pop_front();
|
||||
|
||||
if (!buf)
|
||||
data_buf_.push_front(nullptr);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::unique_ptr<IoQueue::IoBuffer> IoQueue::PopBackFreeBuffer(bool wait)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(free_mtx_);
|
||||
|
||||
auto size = free_buf_.size();
|
||||
if (!size) {
|
||||
if (!IncreaseFreeBuffer()) {
|
||||
if (wait) {
|
||||
do {
|
||||
free_cond_.wait(lock);
|
||||
} while (free_buf_.empty());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
} else if (size > min_) {
|
||||
DecreaseFreeBuffer();
|
||||
}
|
||||
|
||||
auto buf = std::move(free_buf_.back());
|
||||
free_buf_.pop_back();
|
||||
|
||||
if (!buf)
|
||||
free_buf_.push_back(nullptr);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void IoQueue::ReadWorker()
|
||||
{
|
||||
if (!iop_.Start())
|
||||
return;
|
||||
|
||||
while (true) {
|
||||
auto buf = PopBackFreeBuffer(true);
|
||||
if (!buf) {
|
||||
PushBackDataBuffer(nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
std::size_t rofs = 0;
|
||||
bool quit = false;
|
||||
|
||||
while (rofs < buf_size_) {
|
||||
std::size_t rlen = buf_size_ - rofs;
|
||||
|
||||
if (!iop_.Do(buf->buf.get() + rofs, rlen)) {
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
rofs += rlen;
|
||||
}
|
||||
|
||||
buf->actual_length = rofs;
|
||||
PushBackDataBuffer(std::move(buf));
|
||||
|
||||
if (quit) {
|
||||
PushBackDataBuffer(nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iop_.Stop();
|
||||
}
|
||||
|
||||
void IoQueue::WriteWorker()
|
||||
{
|
||||
if (!iop_.Start())
|
||||
return;
|
||||
|
||||
while (true) {
|
||||
auto buf = PopFrontDataBuffer(true);
|
||||
if (!buf) {
|
||||
PushBackFreeBuffer(nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
std::size_t len = buf->actual_length, wofs = 0;
|
||||
bool quit = false;
|
||||
|
||||
while (wofs < len) {
|
||||
std::size_t wlen = len - wofs;
|
||||
|
||||
if (!iop_.Do(buf->buf.get() + wofs, wlen)) {
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
wofs += wlen;
|
||||
}
|
||||
|
||||
PushBackFreeBuffer(std::move(buf));
|
||||
|
||||
if (quit) {
|
||||
PushBackFreeBuffer(nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iop_.Stop();
|
||||
}
|
||||
|
||||
} // namespace px4
|
87
winusb/src/BonDriver_PX4/io_queue.hpp
Normal file
87
winusb/src/BonDriver_PX4/io_queue.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
// io_queue.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class IoQueue final {
|
||||
public:
|
||||
enum class IoOperation : int {
|
||||
READ = 0,
|
||||
WRITE
|
||||
};
|
||||
|
||||
struct IoBuffer final {
|
||||
std::unique_ptr<std::uint8_t[]> buf;
|
||||
std::size_t actual_length;
|
||||
};
|
||||
|
||||
class IoProvider {
|
||||
public:
|
||||
IoProvider() noexcept {}
|
||||
virtual ~IoProvider() {}
|
||||
|
||||
virtual bool Start() = 0;
|
||||
virtual void Stop() = 0;
|
||||
virtual bool Do(void *buf, std::size_t &size) = 0;
|
||||
};
|
||||
|
||||
IoQueue(IoOperation io_op, IoProvider &iop, std::size_t buf_size, std::uintptr_t max = 32, std::uintptr_t min = 2);
|
||||
~IoQueue();
|
||||
|
||||
// cannot copy
|
||||
IoQueue(const IoQueue &) = delete;
|
||||
IoQueue& operator=(const IoQueue &) = delete;
|
||||
|
||||
bool Start();
|
||||
bool Stop();
|
||||
|
||||
std::size_t GetDataBufferCount() const;
|
||||
std::size_t GetFreeBufferCount() const;
|
||||
bool WaitDataBuffer(std::chrono::milliseconds ms);
|
||||
void PurgeDataBuffer();
|
||||
|
||||
bool Read(void *buf, std::size_t &size, std::size_t &remain_count, bool blocking);
|
||||
bool ReadBuffer(void **buf, std::size_t &size, std::size_t &remain_count, bool blocking);
|
||||
bool HaveReadingBuffer();
|
||||
bool Write(void *buf, std::size_t &size, bool blocking);
|
||||
|
||||
private:
|
||||
bool IncreaseFreeBuffer();
|
||||
void DecreaseFreeBuffer();
|
||||
bool PushBackDataBuffer(std::unique_ptr<IoBuffer> &&buf);
|
||||
bool PushBackFreeBuffer(std::unique_ptr<IoBuffer> &&buf);
|
||||
std::unique_ptr<IoBuffer> PopFrontDataBuffer(bool wait);
|
||||
std::unique_ptr<IoBuffer> PopBackFreeBuffer(bool wait);
|
||||
|
||||
void ReadWorker();
|
||||
void WriteWorker();
|
||||
|
||||
IoOperation io_op_;
|
||||
IoProvider &iop_;
|
||||
std::size_t buf_size_;
|
||||
std::uintptr_t max_;
|
||||
std::uintptr_t min_;
|
||||
std::mutex mtx_;
|
||||
std::size_t total_buf_num_;
|
||||
std::deque<std::unique_ptr<IoBuffer>> data_buf_;
|
||||
mutable std::mutex data_mtx_;
|
||||
std::deque<std::unique_ptr<IoBuffer>> free_buf_;
|
||||
mutable std::mutex free_mtx_;
|
||||
std::condition_variable data_cond_;
|
||||
std::condition_variable free_cond_;
|
||||
std::unique_ptr<IoBuffer> current_buf_;
|
||||
std::size_t current_ofs_;
|
||||
std::unique_ptr<std::thread> th_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
60
winusb/src/BonDriver_PX4/pipe_client.cpp
Normal file
60
winusb/src/BonDriver_PX4/pipe_client.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// pipe_client.cpp
|
||||
|
||||
#include "pipe_client.hpp"
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
PipeClient::PipeClient() noexcept
|
||||
: Pipe()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PipeClient::~PipeClient()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool PipeClient::Connect(const std::wstring &name, const PipeClientConfig &config, HANDLE cancel_event) noexcept
|
||||
{
|
||||
std::wstring path = L"\\\\.\\pipe\\" + name;
|
||||
HANDLE pipe_handle;
|
||||
|
||||
while (true) {
|
||||
DWORD mode;
|
||||
|
||||
if (!WaitNamedPipeW(path.c_str(), config.timeout)) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
pipe_handle = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
|
||||
if (pipe_handle == INVALID_HANDLE_VALUE) {
|
||||
DWORD ec = GetLastError();
|
||||
|
||||
if (ec == ERROR_PIPE_BUSY)
|
||||
continue;
|
||||
|
||||
error_.assign(ec, std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
mode = ((config.stream_read) ? PIPE_READMODE_BYTE : PIPE_READMODE_MESSAGE) | PIPE_WAIT;
|
||||
|
||||
if (!SetNamedPipeHandleState(pipe_handle, &mode, nullptr, nullptr)) {
|
||||
CloseHandle(pipe_handle);
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
SetHandle(pipe_handle);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace px4
|
27
winusb/src/BonDriver_PX4/pipe_client.hpp
Normal file
27
winusb/src/BonDriver_PX4/pipe_client.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// pipe_client.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pipe.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class PipeClient final : public px4::Pipe {
|
||||
public:
|
||||
struct PipeClientConfig {
|
||||
bool stream_read;
|
||||
std::uint32_t timeout;
|
||||
};
|
||||
|
||||
PipeClient() noexcept;
|
||||
~PipeClient();
|
||||
|
||||
bool Connect(const std::wstring &name, const PipeClientConfig &config, HANDLE cancel_event) noexcept;
|
||||
};
|
||||
|
||||
} // namespace px4
|
46
winusb/src/BonDriver_PX4/receiver_info_set.cpp
Normal file
46
winusb/src/BonDriver_PX4/receiver_info_set.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// receiver_info_set.cpp
|
||||
|
||||
#include "receiver_info_set.hpp"
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
void ReceiverInfoSet::Load(const px4::ConfigSet &configs) noexcept
|
||||
{
|
||||
for (int i = 0; i <= 512; i++) {
|
||||
wchar_t sct[32];
|
||||
|
||||
swprintf_s(sct, L"ReceiverDefinition%d", i);
|
||||
|
||||
if (!configs.Exists(sct))
|
||||
break;
|
||||
|
||||
const px4::Config &c = configs.Get(sct);
|
||||
const std::wstring &device_name = c.Get(L"DeviceName", L"");
|
||||
const std::wstring &device_guid_str = c.Get(L"DeviceGUID", L"");
|
||||
const std::wstring &receiver_name = c.Get(L"ReceiverName", L"");
|
||||
const std::wstring &receiver_guid_str = c.Get(L"ReceiverGUID", L"");
|
||||
const std::wstring &system_str = c.Get(L"System", L"");
|
||||
const std::wstring &index_str = c.Get(L"Index", L"-1");
|
||||
|
||||
px4::command::ReceiverInfo receiver_info = { 0 };
|
||||
|
||||
wcscpy_s(receiver_info.device_name, device_name.c_str());
|
||||
px4::util::ParseGuidStr(device_guid_str, receiver_info.device_guid);
|
||||
wcscpy_s(receiver_info.receiver_name, receiver_name.c_str());
|
||||
px4::util::ParseGuidStr(receiver_guid_str, receiver_info.receiver_guid);
|
||||
px4::util::ParseSystemStr(system_str, receiver_info.systems);
|
||||
receiver_info.index = static_cast<std::int32_t>(std::stol(index_str));
|
||||
receiver_info.data_id = 0;
|
||||
|
||||
receivers_.push_back(receiver_info);
|
||||
}
|
||||
}
|
||||
|
||||
const px4::command::ReceiverInfo& ReceiverInfoSet::Get(std::size_t i) const
|
||||
{
|
||||
return receivers_.at(i);
|
||||
}
|
||||
|
||||
} // namespace px4
|
25
winusb/src/BonDriver_PX4/receiver_info_set.hpp
Normal file
25
winusb/src/BonDriver_PX4/receiver_info_set.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// receiver_info_set.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "command.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class ReceiverInfoSet {
|
||||
public:
|
||||
ReceiverInfoSet() noexcept {}
|
||||
~ReceiverInfoSet() {}
|
||||
|
||||
void Load(const px4::ConfigSet &configs) noexcept;
|
||||
const px4::command::ReceiverInfo& Get(std::size_t i) const;
|
||||
|
||||
private:
|
||||
std::vector<px4::command::ReceiverInfo> receivers_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
30
winusb/src/BonDriver_PX4/resource.h
Normal file
30
winusb/src/BonDriver_PX4/resource.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// resource.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VER_FILE 0,4,0,0
|
||||
#define VER_FILE_STR "0.4.0"
|
||||
|
||||
#define VER_PRODUCT 0,4,0,0
|
||||
#define VER_PRODUCT_STR "0.4.0"
|
||||
|
||||
#define VER_COMMENTS_STR ""
|
||||
#define VER_COMPANYNAME_STR "nns779"
|
||||
#define VER_FILEDESCRIPTION_STR "BonDriver for PX4 Devices"
|
||||
#define VER_INTERNALNAME_STR "BonDriver_PX4.dll"
|
||||
#define VER_LEGALCOPYRIGHT_STR ""
|
||||
#define VER_LEGALTRADEMARKS_STR ""
|
||||
#define VER_ORIGINALFILENAME_STR VER_INTERNALNAME_STR
|
||||
#define VER_PRIVATEBUILD_STR ""
|
||||
#define VER_PRODUCTNAME_STR "BonDriver_PX4"
|
||||
#define VER_SPECIALBUILD_STR ""
|
||||
|
||||
#if defined(_DEBUG)
|
||||
#define VER_FLAGS VS_FF_PRERELEASE | VS_FF_DEBUG
|
||||
#elif defined(_DEBUG_MSG)
|
||||
#define VER_FLAGS VS_FF_PRERELEASE
|
||||
#else
|
||||
#define VER_FLAGS 0
|
||||
#endif
|
317
winusb/src/DriverHost_PX4/DriverHost_PX4.vcxproj
Normal file
317
winusb/src/DriverHost_PX4/DriverHost_PX4.vcxproj
Normal file
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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="Release-static|Win32">
|
||||
<Configuration>Release-static</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>
|
||||
<ProjectConfiguration Include="Release-static|x64">
|
||||
<Configuration>Release-static</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{4601F387-ACC7-445B-AD12-4D9C4B2EFB04}</ProjectGuid>
|
||||
<RootNamespace>DriverHostPX4</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<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'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)src\common;$(ProjectDir);$(ProjectDir)..\..\..\driver;</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)src\common;$(ProjectDir);$(ProjectDir)..\..\..\driver;</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)src\common;$(ProjectDir);$(ProjectDir)..\..\..\driver;</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)src\common;$(ProjectDir);$(ProjectDir)..\..\..\driver;</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)src\common;$(ProjectDir);$(ProjectDir)..\..\..\driver;</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)src\common;$(ProjectDir);$(ProjectDir)..\..\..\driver;</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winusb.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winusb.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_DEBUG_MSG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winusb.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winusb.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_DEBUG_MSG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winusb.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winusb.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\driver\cxd2856er.c" />
|
||||
<ClCompile Include="..\..\..\driver\cxd2858er.c" />
|
||||
<ClCompile Include="..\..\..\driver\it930x.c" />
|
||||
<ClCompile Include="..\..\..\driver\r850.c" />
|
||||
<ClCompile Include="..\..\..\driver\rt710.c" />
|
||||
<ClCompile Include="..\..\..\driver\tc90522.c" />
|
||||
<ClCompile Include="..\common\config.cpp" />
|
||||
<ClCompile Include="..\common\msg.c" />
|
||||
<ClCompile Include="..\common\pipe.cpp" />
|
||||
<ClCompile Include="..\common\util.cpp" />
|
||||
<ClCompile Include="ctrl_server.cpp" />
|
||||
<ClCompile Include="device_base.cpp" />
|
||||
<ClCompile Include="device_definition_set.cpp" />
|
||||
<ClCompile Include="device_manager.cpp" />
|
||||
<ClCompile Include="device_notifier.cpp" />
|
||||
<ClCompile Include="driver_host.cpp" />
|
||||
<ClCompile Include="itedtv_bus_winusb.c" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="misc_win.c" />
|
||||
<ClCompile Include="pipe_server.cpp" />
|
||||
<ClCompile Include="px4_device.cpp" />
|
||||
<ClCompile Include="pxmlt_device.cpp" />
|
||||
<ClCompile Include="receiver_base.cpp" />
|
||||
<ClCompile Include="receiver_manager.cpp" />
|
||||
<ClCompile Include="ringbuffer.cpp" />
|
||||
<ClCompile Include="server_base.cpp" />
|
||||
<ClCompile Include="stream_server.cpp" />
|
||||
<ClCompile Include="notify_icon.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\driver\cxd2856er.h" />
|
||||
<ClInclude Include="..\..\..\driver\cxd2858er.h" />
|
||||
<ClInclude Include="..\..\..\driver\i2c_comm.h" />
|
||||
<ClInclude Include="..\..\..\driver\it930x.h" />
|
||||
<ClInclude Include="..\..\..\driver\itedtv_bus.h" />
|
||||
<ClInclude Include="..\..\..\driver\r850.h" />
|
||||
<ClInclude Include="..\..\..\driver\rt710.h" />
|
||||
<ClInclude Include="..\..\..\driver\tc90522.h" />
|
||||
<ClInclude Include="..\common\command.hpp" />
|
||||
<ClInclude Include="..\common\config.hpp" />
|
||||
<ClInclude Include="..\common\msg.h" />
|
||||
<ClInclude Include="..\common\pipe.hpp" />
|
||||
<ClInclude Include="..\common\type.hpp" />
|
||||
<ClInclude Include="..\common\util.hpp" />
|
||||
<ClInclude Include="ctrl_server.hpp" />
|
||||
<ClInclude Include="device_base.hpp" />
|
||||
<ClInclude Include="device_definition_set.hpp" />
|
||||
<ClInclude Include="device_manager.hpp" />
|
||||
<ClInclude Include="device_notifier.hpp" />
|
||||
<ClInclude Include="driver_host.hpp" />
|
||||
<ClInclude Include="misc_win.h" />
|
||||
<ClInclude Include="notify_icon.hpp" />
|
||||
<ClInclude Include="pipe_server.hpp" />
|
||||
<ClInclude Include="px4_device.hpp" />
|
||||
<ClInclude Include="pxmlt_device.hpp" />
|
||||
<ClInclude Include="receiver_base.hpp" />
|
||||
<ClInclude Include="receiver_manager.hpp" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="ringbuffer.hpp" />
|
||||
<ClInclude Include="server_base.hpp" />
|
||||
<ClInclude Include="stream_server.hpp" />
|
||||
<ClInclude Include="winusb_compat.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\pkg\DriverHost_PX4\DriverHost_PX4.ini" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DriverHost_PX4.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
214
winusb/src/DriverHost_PX4/DriverHost_PX4.vcxproj.filters
Normal file
214
winusb/src/DriverHost_PX4/DriverHost_PX4.vcxproj.filters
Normal file
@@ -0,0 +1,214 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="ソース ファイル">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="ヘッダー ファイル">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="リソース ファイル">
|
||||
<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="パッケージ">
|
||||
<UniqueIdentifier>{c7712df7-53c8-44b0-9b66-82d857601e6a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\driver\cxd2856er.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\driver\cxd2858er.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\driver\it930x.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\driver\r850.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\driver\rt710.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\driver\tc90522.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\config.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\msg.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\pipe.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\util.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ctrl_server.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="device_base.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="device_definition_set.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="device_manager.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="device_notifier.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="driver_host.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="itedtv_bus_winusb.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="misc_win.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pipe_server.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="px4_device.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pxmlt_device.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="receiver_base.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="receiver_manager.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ringbuffer.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="server_base.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stream_server.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="notify_icon.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\driver\cxd2856er.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\cxd2858er.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\i2c_comm.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\it930x.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\itedtv_bus.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\r850.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\rt710.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\driver\tc90522.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\command.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\config.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\msg.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\pipe.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\type.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\util.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ctrl_server.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="device_base.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="device_definition_set.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="device_manager.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="device_notifier.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driver_host.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="misc_win.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="notify_icon.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pipe_server.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="px4_device.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pxmlt_device.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="receiver_base.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="receiver_manager.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ringbuffer.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="server_base.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stream_server.hpp">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="winusb_compat.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\pkg\DriverHost_PX4\DriverHost_PX4.ini">
|
||||
<Filter>パッケージ</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DriverHost_PX4.rc">
|
||||
<Filter>リソース ファイル</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
217
winusb/src/DriverHost_PX4/ctrl_server.cpp
Normal file
217
winusb/src/DriverHost_PX4/ctrl_server.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
// ctrl_server.cpp
|
||||
|
||||
#include "ctrl_server.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
CtrlServer::CtrlServer(px4::ReceiverManager &receiver_manager)
|
||||
: ServerBase(L"px4_ctrl_pipe", receiver_manager)
|
||||
{
|
||||
pipe_config_.in_buffer_size = 512;
|
||||
pipe_config_.out_buffer_size = 512;
|
||||
pipe_config_.stream_pipe = false;
|
||||
pipe_config_.stream_read = false;
|
||||
pipe_config_.default_timeout = 2000;
|
||||
}
|
||||
|
||||
px4::ServerBase::Connection* CtrlServer::CreateConnection(std::unique_ptr<px4::PipeServer> &pipe)
|
||||
{
|
||||
return new CtrlConnection(*this, pipe);
|
||||
}
|
||||
|
||||
CtrlServer::CtrlConnection::CtrlConnection(ServerBase &parent, std::unique_ptr<px4::PipeServer> &pipe) noexcept
|
||||
: Connection(parent, pipe)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CtrlServer::CtrlConnection::Worker() noexcept
|
||||
{
|
||||
std::size_t size = config_.in_buffer_size;
|
||||
std::unique_ptr<std::uint8_t[]> buf(new std::uint8_t[size]);
|
||||
px4::command::ReceiverInfo info = { 0 };
|
||||
px4::ReceiverBase *receiver = nullptr;
|
||||
|
||||
while (true) {
|
||||
bool ret = true;
|
||||
std::size_t read;
|
||||
|
||||
if (!conn_->Read(buf.get(), size, read, quit_event_))
|
||||
break;
|
||||
|
||||
px4::command::CtrlCmdHeader *hdr = reinterpret_cast<px4::command::CtrlCmdHeader *>(buf.get());
|
||||
|
||||
switch (hdr->cmd) {
|
||||
case px4::command::CtrlCmdCode::GET_VERSION:
|
||||
{
|
||||
px4::command::CtrlVersionCmd *version = reinterpret_cast<px4::command::CtrlVersionCmd *>(buf.get());
|
||||
|
||||
version->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
version->driver_version = 0x00040000;
|
||||
version->cmd_version = px4::command::VERSION;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::OPEN:
|
||||
{
|
||||
if (receiver) {
|
||||
receiver->Close();
|
||||
receiver_manager_.ClearDataId(receiver);
|
||||
receiver = nullptr;
|
||||
}
|
||||
|
||||
px4::command::CtrlOpenCmd *open = reinterpret_cast<px4::command::CtrlOpenCmd *>(buf.get());
|
||||
|
||||
receiver = receiver_manager_.Search(open->receiver_info, info);
|
||||
if (receiver) {
|
||||
int ret;
|
||||
|
||||
ret = receiver->Open();
|
||||
if (!ret) {
|
||||
std::uint32_t data_id;
|
||||
|
||||
if (receiver_manager_.GenerateDataId(receiver, data_id)) {
|
||||
open->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
open->receiver_info = info;
|
||||
open->receiver_info.data_id = data_id;
|
||||
break;
|
||||
}
|
||||
|
||||
receiver->Close();
|
||||
}
|
||||
|
||||
receiver = nullptr;
|
||||
}
|
||||
|
||||
open->status = px4::command::CtrlStatusCode::FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::CLOSE:
|
||||
if (receiver) {
|
||||
receiver->Close();
|
||||
receiver_manager_.ClearDataId(receiver);
|
||||
receiver = nullptr;
|
||||
info = { 0 };
|
||||
|
||||
hdr->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
} else {
|
||||
hdr->status = px4::command::CtrlStatusCode::FAILED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case px4::command::CtrlCmdCode::GET_INFO:
|
||||
{
|
||||
px4::command::CtrlReceiverInfoCmd *receiver_info = reinterpret_cast<px4::command::CtrlReceiverInfoCmd *>(buf.get());
|
||||
|
||||
if (receiver) {
|
||||
receiver_info->receiver_info = info;
|
||||
hdr->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
} else {
|
||||
hdr->status = px4::command::CtrlStatusCode::FAILED;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::SET_CAPTURE:
|
||||
{
|
||||
px4::command::CtrlCaptureCmd *capture = reinterpret_cast<px4::command::CtrlCaptureCmd *>(buf.get());
|
||||
|
||||
if (receiver && !receiver->SetCapture((capture->capture) ? true : false))
|
||||
capture->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
capture->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::GET_PARAMS:
|
||||
{
|
||||
px4::command::CtrlParamsCmd *params = reinterpret_cast<px4::command::CtrlParamsCmd *>(buf.get());
|
||||
|
||||
if (receiver && receiver->GetParameters(params->param_set))
|
||||
params->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
params->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::SET_PARAMS:
|
||||
{
|
||||
px4::command::CtrlParamsCmd *params = reinterpret_cast<px4::command::CtrlParamsCmd *>(buf.get());
|
||||
|
||||
if (receiver && receiver->SetParameters(params->param_set))
|
||||
params->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
params->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::CLEAR_PARAMS:
|
||||
if (receiver && (receiver->ClearParameters(), true))
|
||||
hdr->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
hdr->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
|
||||
case px4::command::CtrlCmdCode::TUNE:
|
||||
if (receiver && !receiver->Tune())
|
||||
hdr->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
hdr->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
|
||||
case px4::command::CtrlCmdCode::SET_LNB_VOLTAGE:
|
||||
{
|
||||
px4::command::CtrlLnbVoltageCmd *lnb = reinterpret_cast<px4::command::CtrlLnbVoltageCmd *>(buf.get());
|
||||
|
||||
if (receiver && !receiver->SetLnbVoltage(lnb->voltage))
|
||||
lnb->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
lnb->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::command::CtrlCmdCode::READ_STATS:
|
||||
{
|
||||
px4::command::CtrlStatsCmd *stats = reinterpret_cast<px4::command::CtrlStatsCmd *>(buf.get());
|
||||
|
||||
if (receiver && receiver->ReadStats(stats->stat_set))
|
||||
stats->status = px4::command::CtrlStatusCode::SUCCEEDED;
|
||||
else
|
||||
stats->status = px4::command::CtrlStatusCode::FAILED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
hdr->status = px4::command::CtrlStatusCode::FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
std::size_t written;
|
||||
|
||||
if (!conn_->Write(buf.get(), read, written) || read != written)
|
||||
break;
|
||||
}
|
||||
|
||||
if (receiver) {
|
||||
receiver->Close();
|
||||
receiver_manager_.ClearDataId(receiver);
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
} // namespace px4
|
49
winusb/src/DriverHost_PX4/ctrl_server.hpp
Normal file
49
winusb/src/DriverHost_PX4/ctrl_server.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// ctrl_server.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "server_base.hpp"
|
||||
#include "pipe_server.hpp"
|
||||
#include "receiver_base.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class CtrlServer final : public px4::ServerBase {
|
||||
public:
|
||||
explicit CtrlServer(px4::ReceiverManager &receiver_manager);
|
||||
~CtrlServer() {}
|
||||
|
||||
// cannot copy
|
||||
CtrlServer(const CtrlServer &) = delete;
|
||||
CtrlServer& operator=(const CtrlServer &) = delete;
|
||||
|
||||
// cannot move
|
||||
CtrlServer(CtrlServer &&) = delete;
|
||||
CtrlServer& operator=(CtrlServer &&) = delete;
|
||||
|
||||
private:
|
||||
class CtrlConnection final : public px4::ServerBase::Connection {
|
||||
public:
|
||||
explicit CtrlConnection(ServerBase &parent, std::unique_ptr<px4::PipeServer> &pipe) noexcept;
|
||||
~CtrlConnection() {}
|
||||
|
||||
// cannot copy
|
||||
CtrlConnection(const CtrlConnection &) = delete;
|
||||
CtrlConnection& operator=(const CtrlConnection &) = delete;
|
||||
|
||||
// cannot move
|
||||
CtrlConnection(CtrlConnection &&) = delete;
|
||||
CtrlConnection& operator=(CtrlConnection &&) = delete;
|
||||
|
||||
private:
|
||||
void Worker() noexcept override;
|
||||
};
|
||||
|
||||
px4::ServerBase::Connection* CreateConnection(std::unique_ptr<px4::PipeServer> &pipe) override;
|
||||
};
|
||||
|
||||
} // namespace px4
|
67
winusb/src/DriverHost_PX4/device_base.cpp
Normal file
67
winusb/src/DriverHost_PX4/device_base.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// device_base.cpp
|
||||
|
||||
#include "device_base.hpp"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "msg.h"
|
||||
#include "command.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
DeviceBase::DeviceBase(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager)
|
||||
: device_def_(device_def),
|
||||
receiver_manager_(receiver_manager)
|
||||
{
|
||||
strncpy_s(dev_.driver_name, "px4_winusb", sizeof("px4_winusb"));
|
||||
sprintf_s(dev_.device_name, "%" PRIuPTR, index);
|
||||
|
||||
usb_dev_.winusb = nullptr;
|
||||
|
||||
usb_dev_.dev = CreateFileW(
|
||||
path.c_str(),
|
||||
GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
||||
nullptr);
|
||||
if (usb_dev_.dev == INVALID_HANDLE_VALUE)
|
||||
throw DeviceError("px4::DeviceBase::DeviceBase: CreateFileW() failed.");
|
||||
|
||||
if (!WinUsb_Initialize(usb_dev_.dev, &usb_dev_.winusb)) {
|
||||
CloseHandle(usb_dev_.dev);
|
||||
throw DeviceError("px4::DeviceBase::DeviceBase: WinUsb_Initialize() failed.");
|
||||
}
|
||||
|
||||
ULONG size;
|
||||
|
||||
if (!WinUsb_GetDescriptor(
|
||||
usb_dev_.winusb,
|
||||
USB_DEVICE_DESCRIPTOR_TYPE,
|
||||
0x00,
|
||||
0x0000,
|
||||
reinterpret_cast<PUCHAR>(&usb_dev_.descriptor),
|
||||
sizeof(usb_dev_.descriptor),
|
||||
&size)
|
||||
) {
|
||||
WinUsb_Free(usb_dev_.winusb);
|
||||
CloseHandle(usb_dev_.dev);
|
||||
throw DeviceError("px4::DeviceBase::DeviceBase: WinUsb_GetDescriptor(USB_DEVICE_DESCRIPTOR_TYPE) failed.");
|
||||
}
|
||||
}
|
||||
|
||||
DeviceBase::~DeviceBase()
|
||||
{
|
||||
if (usb_dev_.winusb) {
|
||||
WinUsb_Free(usb_dev_.winusb);
|
||||
usb_dev_.winusb = nullptr;
|
||||
}
|
||||
|
||||
if (usb_dev_.dev != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(usb_dev_.dev);
|
||||
usb_dev_.dev = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace px4
|
56
winusb/src/DriverHost_PX4/device_base.hpp
Normal file
56
winusb/src/DriverHost_PX4/device_base.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// device_base.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
#include <winusb.h>
|
||||
|
||||
#include "type.hpp"
|
||||
#include "command.hpp"
|
||||
#include "device_definition_set.hpp"
|
||||
#include "receiver_base.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
|
||||
#include "misc_win.h"
|
||||
#include "winusb_compat.h"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class DeviceBase {
|
||||
public:
|
||||
explicit DeviceBase(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager);
|
||||
virtual ~DeviceBase();
|
||||
|
||||
// cannot copy
|
||||
DeviceBase(const DeviceBase &) = delete;
|
||||
DeviceBase& operator=(const DeviceBase &) = delete;
|
||||
|
||||
// cannot move
|
||||
DeviceBase(DeviceBase &&) = delete;
|
||||
DeviceBase& operator=(DeviceBase &&) = delete;
|
||||
|
||||
virtual int Init() = 0;
|
||||
virtual void Term() = 0;
|
||||
virtual void SetAvailability(bool available) = 0;
|
||||
virtual px4::ReceiverBase* GetReceiver(int id) const = 0;
|
||||
|
||||
protected:
|
||||
const device& GetDevice() const { return dev_; }
|
||||
|
||||
const px4::DeviceDefinition &device_def_;
|
||||
px4::ReceiverManager &receiver_manager_;
|
||||
|
||||
device dev_;
|
||||
usb_device usb_dev_;
|
||||
};
|
||||
|
||||
class DeviceError : public std::runtime_error {
|
||||
public:
|
||||
explicit DeviceError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
72
winusb/src/DriverHost_PX4/device_definition_set.cpp
Normal file
72
winusb/src/DriverHost_PX4/device_definition_set.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// device_definition_set.cpp
|
||||
|
||||
#include "device_definition_set.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
void DeviceDefinitionSet::Load(const px4::ConfigSet &configs) noexcept
|
||||
{
|
||||
for (int i = 0; i < 512; i++) {
|
||||
wchar_t dev_sct[32];
|
||||
|
||||
swprintf_s(dev_sct, L"DeviceDefinition%d", i);
|
||||
|
||||
if (!configs.Exists(dev_sct))
|
||||
break;
|
||||
|
||||
const px4::Config &cd = configs.Get(dev_sct);
|
||||
|
||||
const std::wstring &dev_name = cd.Get(L"Name", L"");
|
||||
const std::wstring &dev_guid_str = cd.Get(L"GUID", L"");
|
||||
const std::wstring &dev_type = cd.Get(L"Type", L"PX4");
|
||||
const std::wstring &dev_intf_guid_str = cd.Get(L"DeviceInterfaceGUID", L"");
|
||||
|
||||
DeviceDefinition dev_def = {};
|
||||
|
||||
dev_def.name = dev_name;
|
||||
px4::util::ParseGuidStr(dev_guid_str, dev_def.guid);
|
||||
px4::util::ParseGuidStr(dev_intf_guid_str, dev_def.device_interface_guid);
|
||||
|
||||
for (int j = 0; j < 64; j++) {
|
||||
wchar_t rcvr_sct[64];
|
||||
|
||||
swprintf_s(rcvr_sct, L"DeviceDefinition%d.Receiver%d", i, j);
|
||||
|
||||
if (!configs.Exists(rcvr_sct))
|
||||
break;
|
||||
|
||||
const px4::Config &cr = configs.Get(rcvr_sct);
|
||||
|
||||
const std::wstring &rcvr_name = cr.Get(L"Name", L"");
|
||||
const std::wstring &rcvr_guid_str = cr.Get(L"GUID", L"");
|
||||
const std::wstring &rcvr_system_str = cr.Get(L"System", L"");
|
||||
const std::wstring &rcvr_index_str = cr.Get(L"Index", L"-1");
|
||||
|
||||
ReceiverDefinition rcvr_def = {};
|
||||
|
||||
rcvr_def.name = rcvr_name;
|
||||
px4::util::ParseGuidStr(rcvr_guid_str, rcvr_def.guid);
|
||||
px4::util::ParseSystemStr(rcvr_system_str, rcvr_def.systems);
|
||||
rcvr_def.index = static_cast<std::int32_t>(std::stol(rcvr_index_str));
|
||||
|
||||
dev_def.receivers.emplace_back(rcvr_def);
|
||||
}
|
||||
|
||||
if (!devices_.count(dev_type))
|
||||
devices_.emplace(dev_type, std::vector<px4::DeviceDefinition>());
|
||||
|
||||
devices_.at(dev_type).emplace_back(dev_def);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<DeviceDefinition>& DeviceDefinitionSet::Get(const std::wstring &type) const
|
||||
{
|
||||
return devices_.at(type);
|
||||
}
|
||||
|
||||
const std::unordered_map<std::wstring, std::vector<DeviceDefinition>>& DeviceDefinitionSet::GetAll() const
|
||||
{
|
||||
return devices_;
|
||||
}
|
||||
|
||||
} // namespace px4
|
47
winusb/src/DriverHost_PX4/device_definition_set.hpp
Normal file
47
winusb/src/DriverHost_PX4/device_definition_set.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// device_definition_set.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "type.hpp"
|
||||
#include "util.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
struct ReceiverDefinition final {
|
||||
std::wstring name;
|
||||
GUID guid;
|
||||
px4::SystemType systems;
|
||||
std::int32_t index;
|
||||
};
|
||||
|
||||
struct DeviceDefinition final {
|
||||
std::wstring name;
|
||||
GUID guid;
|
||||
GUID device_interface_guid;
|
||||
std::vector<ReceiverDefinition> receivers;
|
||||
};
|
||||
|
||||
class DeviceDefinitionSet final {
|
||||
public:
|
||||
DeviceDefinitionSet() noexcept {}
|
||||
~DeviceDefinitionSet() {};
|
||||
|
||||
void Load(const px4::ConfigSet &configs) noexcept;
|
||||
const std::vector<DeviceDefinition>& Get(const std::wstring &type) const;
|
||||
const std::unordered_map<std::wstring, std::vector<DeviceDefinition>>& GetAll() const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::wstring, std::vector<DeviceDefinition>> devices_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
162
winusb/src/DriverHost_PX4/device_manager.cpp
Normal file
162
winusb/src/DriverHost_PX4/device_manager.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// device_manager.cpp
|
||||
|
||||
#include "device_manager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
#include "px4_device.hpp"
|
||||
#include "pxmlt_device.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
void DeviceManager::NotifyHandler::Handle(px4::DeviceNotifyType type, const GUID &interface_guid, const wchar_t *path) noexcept
|
||||
{
|
||||
try {
|
||||
std::wstring path_lower = path;
|
||||
|
||||
std::transform(path_lower.cbegin(), path_lower.cend(), path_lower.begin(), tolower);
|
||||
|
||||
switch (type) {
|
||||
case px4::DeviceNotifyType::ARRIVAL:
|
||||
parent_.Add(path_lower, parent_.device_map_.at(interface_guid));
|
||||
break;
|
||||
|
||||
case px4::DeviceNotifyType::REMOVE:
|
||||
parent_.Remove(path_lower);
|
||||
break;
|
||||
}
|
||||
} catch (const std::out_of_range &) {}
|
||||
}
|
||||
|
||||
DeviceManager::DeviceManager(const px4::DeviceDefinitionSet &device_defs, px4::ReceiverManager &receiver_manager)
|
||||
: device_map_(),
|
||||
receiver_manager_(receiver_manager),
|
||||
mtx_(),
|
||||
index_(0),
|
||||
handler_(*this)
|
||||
{
|
||||
auto &all_devs = device_defs.GetAll();
|
||||
|
||||
for (auto it = all_devs.cbegin(); it != all_devs.cend(); ++it) {
|
||||
DeviceType type = DeviceType::UNKNOWN;
|
||||
|
||||
if (it->first == L"PX4")
|
||||
type = DeviceType::PX4;
|
||||
else if (it->first == L"PXMLT")
|
||||
type = DeviceType::PXMLT;
|
||||
|
||||
if (type == DeviceType::UNKNOWN)
|
||||
continue;
|
||||
|
||||
auto &devs = it->second;
|
||||
|
||||
for (auto it2 = devs.begin(); it2 != devs.end(); ++it2)
|
||||
device_map_.emplace(it2->device_interface_guid, std::move(std::pair<DeviceType, px4::DeviceDefinition>(type, *it2)));
|
||||
}
|
||||
|
||||
notifier_.reset(new px4::DeviceNotifier(&handler_));
|
||||
|
||||
for (auto it = device_map_.cbegin(); it != device_map_.cend(); ++it)
|
||||
Search(it->first, it->second);
|
||||
}
|
||||
|
||||
DeviceManager::~DeviceManager()
|
||||
{
|
||||
notifier_.reset();
|
||||
}
|
||||
|
||||
void DeviceManager::Search(const GUID &guid, const std::pair<DeviceType, px4::DeviceDefinition> &def)
|
||||
{
|
||||
HDEVINFO dev_info;
|
||||
|
||||
dev_info = SetupDiGetClassDevsW(&guid, nullptr, nullptr, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
||||
if (dev_info == INVALID_HANDLE_VALUE)
|
||||
throw DeviceManagerError("px4::DeviceManager::Search: SetupDiGetClassDevsW() failed.");
|
||||
|
||||
SP_DEVICE_INTERFACE_DATA intf_data;
|
||||
DWORD i = 0;
|
||||
|
||||
intf_data.cbSize = sizeof(intf_data);
|
||||
|
||||
while (SetupDiEnumDeviceInterfaces(dev_info, nullptr, &guid, i, &intf_data)) {
|
||||
DWORD detail_size;
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail_data;
|
||||
|
||||
SetupDiGetDeviceInterfaceDetailW(dev_info, &intf_data, nullptr, 0, &detail_size, nullptr);
|
||||
if (!detail_size)
|
||||
continue;
|
||||
|
||||
detail_data = reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_W *>(new std::uint8_t[detail_size]);
|
||||
detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
|
||||
|
||||
if (SetupDiGetDeviceInterfaceDetailW(dev_info, &intf_data, detail_data, detail_size, nullptr, nullptr)) {
|
||||
std::wstring path_lower = detail_data->DevicePath;
|
||||
|
||||
std::transform(path_lower.cbegin(), path_lower.cend(), path_lower.begin(), tolower);
|
||||
Add(path_lower, def);
|
||||
}
|
||||
|
||||
delete[] reinterpret_cast<std::uint8_t *>(detail_data);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(dev_info);
|
||||
}
|
||||
|
||||
|
||||
void DeviceManager::Add(const std::wstring &path, const std::pair<DeviceType, px4::DeviceDefinition> &def)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (Exists(path))
|
||||
return;
|
||||
|
||||
switch (def.first) {
|
||||
case px4::DeviceType::PX4:
|
||||
{
|
||||
auto dev = std::make_unique<Px4Device>(path, def.second, ++index_, receiver_manager_);
|
||||
|
||||
if (!dev->Init())
|
||||
devices_.emplace(path, std::move(dev));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::DeviceType::PXMLT:
|
||||
{
|
||||
auto dev = std::make_unique<PxMltDevice>(path, def.second, ++index_, receiver_manager_);
|
||||
|
||||
if (!dev->Init())
|
||||
devices_.emplace(path, std::move(dev));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DeviceManager::Remove(const std::wstring &path)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
if (!Exists(path))
|
||||
return;
|
||||
|
||||
devices_.at(path)->SetAvailability(false);
|
||||
devices_.erase(path);
|
||||
}
|
||||
|
||||
bool DeviceManager::Exists(const std::wstring &path) const
|
||||
{
|
||||
return !!devices_.count(path);
|
||||
}
|
||||
|
||||
} // namespace px4
|
74
winusb/src/DriverHost_PX4/device_manager.hpp
Normal file
74
winusb/src/DriverHost_PX4/device_manager.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// device_manager.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "device_notifier.hpp"
|
||||
#include "device_definition_set.hpp"
|
||||
#include "device_base.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
enum class DeviceType : std::uint32_t {
|
||||
UNKNOWN = 0,
|
||||
PX4,
|
||||
PXMLT
|
||||
};
|
||||
|
||||
class DeviceManager final {
|
||||
private:
|
||||
class NotifyHandler final : public px4::DeviceNotifyHandler {
|
||||
public:
|
||||
explicit NotifyHandler(DeviceManager &parent) : parent_(parent) {}
|
||||
~NotifyHandler() {}
|
||||
|
||||
void Handle(px4::DeviceNotifyType type, const GUID &interface_guid, const wchar_t *path) noexcept;
|
||||
|
||||
private:
|
||||
DeviceManager &parent_;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit DeviceManager(const px4::DeviceDefinitionSet &device_defs, px4::ReceiverManager &receiver_manager);
|
||||
~DeviceManager();
|
||||
|
||||
// cannot copy
|
||||
DeviceManager(const DeviceManager &) = delete;
|
||||
DeviceManager& operator=(const DeviceManager &) = delete;
|
||||
|
||||
// cannot move
|
||||
DeviceManager(DeviceManager &&) = delete;
|
||||
DeviceManager& operator=(DeviceManager &&) = delete;
|
||||
|
||||
private:
|
||||
void Search(const GUID &guid, const std::pair<DeviceType, px4::DeviceDefinition> &def);
|
||||
void Add(const std::wstring &path, const std::pair<DeviceType, px4::DeviceDefinition> &def);
|
||||
void Remove(const std::wstring &path);
|
||||
bool Exists(const std::wstring &path) const;
|
||||
|
||||
std::unordered_map<GUID, std::pair<DeviceType, px4::DeviceDefinition>> device_map_;
|
||||
px4::ReceiverManager &receiver_manager_;
|
||||
|
||||
std::mutex mtx_;
|
||||
std::unordered_map<std::wstring, std::unique_ptr<DeviceBase>> devices_;
|
||||
std::uintptr_t index_;
|
||||
NotifyHandler handler_;
|
||||
std::unique_ptr<px4::DeviceNotifier> notifier_;
|
||||
};
|
||||
|
||||
class DeviceManagerError : public std::runtime_error {
|
||||
public:
|
||||
explicit DeviceManagerError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
163
winusb/src/DriverHost_PX4/device_notifier.cpp
Normal file
163
winusb/src/DriverHost_PX4/device_notifier.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// device_notifier.cpp
|
||||
|
||||
#include "device_notifier.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
DeviceNotifier::DeviceNotifier(DeviceNotifyHandler *handler)
|
||||
: handler_(handler),
|
||||
hinst_(GetModuleHandleW(nullptr)),
|
||||
hwnd_(nullptr),
|
||||
notify_handle_(nullptr),
|
||||
mtx_(),
|
||||
cond_(),
|
||||
ready_(false),
|
||||
th_(&px4::DeviceNotifier::Worker, this)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
|
||||
cond_.wait(lock);
|
||||
|
||||
if (!ready_.load()) {
|
||||
lock.unlock();
|
||||
throw DeviceNotifierError("px4::DeviceNotifier::DeviceNotifier: failed.");
|
||||
}
|
||||
}
|
||||
|
||||
DeviceNotifier::~DeviceNotifier()
|
||||
{
|
||||
SendMessageW(hwnd_, WM_CLOSE, 0, 0);
|
||||
th_.join();
|
||||
}
|
||||
|
||||
LRESULT CALLBACK DeviceNotifier::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
void *p;
|
||||
DeviceNotifier *dn = nullptr;
|
||||
|
||||
p = reinterpret_cast<void *>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
|
||||
if (p) {
|
||||
dn = reinterpret_cast<DeviceNotifier *>(DecodePointer(p));
|
||||
} else if (uMsg == WM_CREATE && lParam) {
|
||||
dn = reinterpret_cast<DeviceNotifier *>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(EncodePointer(dn)));
|
||||
}
|
||||
|
||||
if (!dn)
|
||||
return -1;
|
||||
|
||||
std::unique_lock<std::mutex> lock(dn->mtx_, std::defer_lock);
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_CREATE:
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE_W dbdi;
|
||||
HDEVNOTIFY notify_handle;
|
||||
|
||||
dbdi.dbcc_size = sizeof(dbdi);
|
||||
dbdi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
|
||||
notify_handle = RegisterDeviceNotificationW(hwnd, &dbdi, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||
if (!notify_handle)
|
||||
return -1;
|
||||
|
||||
dn->notify_handle_ = notify_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwnd);
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
lock.lock();
|
||||
|
||||
if (dn->notify_handle_) {
|
||||
UnregisterDeviceNotification(dn->notify_handle_);
|
||||
dn->notify_handle_ = nullptr;
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE_W *dbdi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_W *>(lParam);
|
||||
|
||||
if (!dbdi || dbdi->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
|
||||
return TRUE;
|
||||
|
||||
lock.lock();
|
||||
|
||||
switch (wParam) {
|
||||
case DBT_DEVICEARRIVAL:
|
||||
dn->handler_->Handle(DeviceNotifyType::ARRIVAL, dbdi->dbcc_classguid, dbdi->dbcc_name);
|
||||
break;
|
||||
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
dn->handler_->Handle(DeviceNotifyType::REMOVE, dbdi->dbcc_classguid, dbdi->dbcc_name);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
void DeviceNotifier::Worker()
|
||||
{
|
||||
WCHAR class_name[] = TEXT("DeviceNotifier_MessageWindow");
|
||||
WNDCLASSEXW wc;
|
||||
MSG msg;
|
||||
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hinst_;
|
||||
wc.hIcon = nullptr;
|
||||
wc.hCursor = nullptr;
|
||||
wc.hbrBackground = nullptr;
|
||||
wc.lpszMenuName = nullptr;
|
||||
wc.lpszClassName = class_name;
|
||||
wc.hIconSm = nullptr;
|
||||
|
||||
if (!RegisterClassExW(&wc)) {
|
||||
ready_.store(false);
|
||||
cond_.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
hwnd_ = CreateWindowExW(0, class_name, nullptr, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, nullptr, hinst_, this);
|
||||
if (!hwnd_) {
|
||||
ready_.store(false);
|
||||
cond_.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
ready_.store(true);
|
||||
cond_.notify_all();
|
||||
|
||||
while (GetMessage(&msg, nullptr, 0, 0) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace px4
|
62
winusb/src/DriverHost_PX4/device_notifier.hpp
Normal file
62
winusb/src/DriverHost_PX4/device_notifier.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// device_notifier.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbt.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
enum class DeviceNotifyType {
|
||||
UNDEFINED = 0,
|
||||
ARRIVAL,
|
||||
REMOVE,
|
||||
};
|
||||
|
||||
class DeviceNotifyHandler {
|
||||
public:
|
||||
virtual ~DeviceNotifyHandler() {}
|
||||
|
||||
virtual void Handle(DeviceNotifyType type, const GUID &interface_guid, const wchar_t *path) noexcept = 0;
|
||||
};
|
||||
|
||||
class DeviceNotifier final {
|
||||
public:
|
||||
explicit DeviceNotifier(DeviceNotifyHandler *handler);
|
||||
~DeviceNotifier();
|
||||
|
||||
// cannot copy
|
||||
DeviceNotifier(const DeviceNotifier &) = delete;
|
||||
DeviceNotifier& operator=(const DeviceNotifier &) = delete;
|
||||
|
||||
// cannot move
|
||||
DeviceNotifier(DeviceNotifier &&) = delete;
|
||||
DeviceNotifier& operator=(DeviceNotifier &&) = delete;
|
||||
|
||||
private:
|
||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
void Worker();
|
||||
|
||||
DeviceNotifyHandler *handler_;
|
||||
HINSTANCE hinst_;
|
||||
HWND hwnd_;
|
||||
HDEVNOTIFY notify_handle_;
|
||||
std::mutex mtx_;
|
||||
std::condition_variable cond_;
|
||||
std::atomic_bool ready_;
|
||||
std::thread th_;
|
||||
};
|
||||
|
||||
class DeviceNotifierError : public std::runtime_error {
|
||||
public:
|
||||
explicit DeviceNotifierError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
99
winusb/src/DriverHost_PX4/driver_host.cpp
Normal file
99
winusb/src/DriverHost_PX4/driver_host.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// driver_host.cpp
|
||||
|
||||
#include "driver_host.hpp"
|
||||
|
||||
#include <aclapi.h>
|
||||
|
||||
#include "notify_icon.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
DriverHost::DriverHost()
|
||||
: startup_event_(nullptr)
|
||||
{
|
||||
configs_.Load(px4::util::path::GetFileBase() + L".ini");
|
||||
|
||||
dev_defs_.Load(configs_);
|
||||
}
|
||||
|
||||
DriverHost::~DriverHost()
|
||||
{
|
||||
ctrl_server_.reset();
|
||||
device_manager_.reset();
|
||||
|
||||
if (startup_event_)
|
||||
CloseHandle(startup_event_);
|
||||
}
|
||||
|
||||
void DriverHost::Run()
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY sia;
|
||||
PSID sid = nullptr;
|
||||
EXPLICIT_ACCESSW ea;
|
||||
PACL acl = nullptr;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
|
||||
sia = SECURITY_WORLD_SID_AUTHORITY;
|
||||
|
||||
if (!AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sid))
|
||||
throw DriverHostError("px4::DriverHost::Run: AllocateAndInitializeSid() failed.");
|
||||
|
||||
memset(&ea, 0, sizeof(ea));
|
||||
ea.grfAccessPermissions = EVENT_ALL_ACCESS;
|
||||
ea.grfAccessMode = SET_ACCESS;
|
||||
ea.grfInheritance = NO_INHERITANCE;
|
||||
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
||||
ea.Trustee.ptstrName = (LPWSTR)sid;
|
||||
|
||||
if (SetEntriesInAclW(1, &ea, nullptr, &acl) != ERROR_SUCCESS) {
|
||||
LocalFree(sid);
|
||||
throw DriverHostError("px4::DriverHost::Run: SetEntriesInAclW() failed.");
|
||||
}
|
||||
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE);
|
||||
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
startup_event_ = CreateEventW(&sa, TRUE, FALSE, L"DriverHost_PX4_StartupEvent");
|
||||
if (!startup_event_)
|
||||
throw DriverHostError("px4::DriverHost::Run: CreateEventW() failed.");
|
||||
|
||||
LocalFree(sid);
|
||||
|
||||
device_manager_.reset(new px4::DeviceManager(dev_defs_, receiver_manager_));
|
||||
|
||||
ctrl_server_.reset(new px4::CtrlServer(receiver_manager_));
|
||||
stream_server_.reset(new px4::StreamServer(receiver_manager_));
|
||||
|
||||
ctrl_server_->Start();
|
||||
stream_server_->Start();
|
||||
|
||||
SetEvent(startup_event_);
|
||||
|
||||
{
|
||||
NotifyIcon ni(L"ICON1", L"PX4 Device Driver");
|
||||
int n = 0;
|
||||
|
||||
while (n < 3) {
|
||||
Sleep(5000);
|
||||
if (!ctrl_server_->GetActiveConnectionCount() && !stream_server_->GetActiveConnectionCount())
|
||||
n++;
|
||||
else
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
stream_server_.reset();
|
||||
ctrl_server_.reset();
|
||||
device_manager_.reset();
|
||||
|
||||
CloseHandle(startup_event_);
|
||||
startup_event_ = nullptr;
|
||||
}
|
||||
|
||||
} // namespace px4
|
52
winusb/src/DriverHost_PX4/driver_host.hpp
Normal file
52
winusb/src/DriverHost_PX4/driver_host.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// driver_host.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "device_definition_set.hpp"
|
||||
#include "device_manager.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
#include "ctrl_server.hpp"
|
||||
#include "stream_server.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class DriverHost final {
|
||||
public:
|
||||
DriverHost();
|
||||
~DriverHost();
|
||||
|
||||
// cannot copy
|
||||
DriverHost(const DriverHost &) = delete;
|
||||
DriverHost& operator=(const DriverHost &) = delete;
|
||||
|
||||
// cannot move
|
||||
DriverHost(DriverHost &&) = delete;
|
||||
DriverHost& operator=(DriverHost &&) = delete;
|
||||
|
||||
void Run();
|
||||
|
||||
private:
|
||||
px4::ConfigSet configs_;
|
||||
px4::DeviceDefinitionSet dev_defs_;
|
||||
px4::ReceiverManager receiver_manager_;
|
||||
|
||||
HANDLE startup_event_;
|
||||
std::unique_ptr<px4::DeviceManager> device_manager_;
|
||||
std::unique_ptr<px4::CtrlServer> ctrl_server_;
|
||||
std::unique_ptr<px4::StreamServer> stream_server_;
|
||||
};
|
||||
|
||||
class DriverHostError : public std::runtime_error {
|
||||
public:
|
||||
explicit DriverHostError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
BIN
winusb/src/DriverHost_PX4/icon.ico
Normal file
BIN
winusb/src/DriverHost_PX4/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 288 KiB |
592
winusb/src/DriverHost_PX4/itedtv_bus_winusb.c
Normal file
592
winusb/src/DriverHost_PX4/itedtv_bus_winusb.c
Normal file
@@ -0,0 +1,592 @@
|
||||
// itedev_bus_winusb.c
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#error Unsupported platform.
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "itedtv_bus.h"
|
||||
|
||||
struct itedtv_usb_context;
|
||||
|
||||
struct itedtv_usb_work {
|
||||
struct itedtv_usb_context *ctx;
|
||||
OVERLAPPED ol;
|
||||
void *buffer;
|
||||
size_t size;
|
||||
bool can_submit;
|
||||
};
|
||||
|
||||
struct itedtv_usb_context {
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE ctrl_event[2];
|
||||
struct itedtv_bus *bus;
|
||||
itedtv_bus_stream_handler_t stream_handler;
|
||||
void *ctx;
|
||||
uint32_t num_urb;
|
||||
bool no_raw_io;
|
||||
uint32_t num_works;
|
||||
struct itedtv_usb_work *works;
|
||||
LONG streaming;
|
||||
HANDLE worker_thread;
|
||||
};
|
||||
|
||||
static int winerr_to_errno(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (GetLastError()) {
|
||||
case ERROR_SUCCESS:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case ERROR_INVALID_HANDLE:
|
||||
ret = EINVAL;
|
||||
break;
|
||||
|
||||
case ERROR_IO_PENDING:
|
||||
case ERROR_IO_INCOMPLETE:
|
||||
ret = ETIMEDOUT;
|
||||
break;
|
||||
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
ret = ENOMEM;
|
||||
break;
|
||||
|
||||
case ERROR_SEM_TIMEOUT:
|
||||
ret = ETIMEDOUT;
|
||||
break;
|
||||
|
||||
case ERROR_BAD_COMMAND:
|
||||
ret = EIO;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(dev, "winusb unknown error: 0x%08x\n", GetLastError());
|
||||
ret = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_ctrl_tx(struct itedtv_bus *bus, void *buf, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
ULONG rlen = 0;
|
||||
OVERLAPPED ol;
|
||||
|
||||
if (!buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
ol.hEvent = ctx->ctrl_event[0];
|
||||
ResetEvent(ol.hEvent);
|
||||
|
||||
/* Endpoint 0x02: Host->Device bulk endpoint for controlling the device */
|
||||
if (!WinUsb_WritePipe(dev->winusb, 0x02, buf, len, &rlen, &ol)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
WaitForSingleObject(ol.hEvent, bus->usb.ctrl_timeout);
|
||||
else
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
} else {
|
||||
dev_dbg(bus->dev, "itedtv_usb_ctrl_tx: WinUsb_WritePipe() TRUE\n");
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (!WinUsb_GetOverlappedResult(dev->winusb, &ol, &rlen, FALSE))
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
WinUsb_AbortPipe(dev->winusb, 0x02);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_ctrl_rx(struct itedtv_bus *bus, void *buf, int *len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
ULONG rlen = 0;
|
||||
OVERLAPPED ol;
|
||||
|
||||
if (!buf || !len || !*len)
|
||||
return -EINVAL;
|
||||
|
||||
ol.hEvent = ctx->ctrl_event[1];
|
||||
ResetEvent(ol.hEvent);
|
||||
|
||||
/* Endpoint 0x81: Device->Host bulk endpoint for controlling the device */
|
||||
if (!WinUsb_ReadPipe(dev->winusb, 0x81, buf, *len, &rlen, &ol)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
WaitForSingleObject(ol.hEvent, bus->usb.ctrl_timeout);
|
||||
else
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
} else {
|
||||
dev_dbg(bus->dev, "itedtv_usb_ctrl_rx: WinUsb_ReadPipe() TRUE\n");
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (!WinUsb_GetOverlappedResult(dev->winusb, &ol, &rlen, FALSE))
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
WinUsb_AbortPipe(dev->winusb, 0x81);
|
||||
|
||||
*len = (rlen <= INT_MAX) ? rlen : -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_stream_rx(struct itedtv_bus *bus, void *buf, int *len, int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
ULONG rlen = 0;
|
||||
OVERLAPPED ol;
|
||||
|
||||
if (!buf | !len || !*len)
|
||||
return -EINVAL;
|
||||
|
||||
ol.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!ol.hEvent) {
|
||||
*len = 0;
|
||||
return -winerr_to_errno(bus->dev);
|
||||
}
|
||||
|
||||
/* Endpoint 0x84: Device->Host bulk endpoint for receiving TS from the device */
|
||||
if (!WinUsb_ReadPipe(dev->winusb, 0x84, buf, *len, &rlen, &ol)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
WaitForSingleObject(ol.hEvent, timeout);
|
||||
else
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
} else {
|
||||
dev_dbg(bus->dev, "itedtv_usb_stream_rx: WinUsb_ReadPipe() TRUE\n");
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (!WinUsb_GetOverlappedResult(dev->winusb, &ol, &rlen, FALSE))
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
WinUsb_AbortPipe(dev->winusb, 0x84);
|
||||
|
||||
*len = (rlen <= INT_MAX) ? rlen : -1;
|
||||
CloseHandle(ol.hEvent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_alloc_work_buffers(struct itedtv_usb_context *ctx, uint32_t buf_size)
|
||||
{
|
||||
uint32_t i;
|
||||
struct itedtv_bus *bus = ctx->bus;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
uint32_t num = ctx->num_works;
|
||||
struct itedtv_usb_work *works = ctx->works;
|
||||
|
||||
if (!works)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
void *p;
|
||||
|
||||
works[i].ctx = ctx;
|
||||
|
||||
if (!works[i].ol.hEvent) {
|
||||
works[i].ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
if (!works[i].ol.hEvent) {
|
||||
dev_err(bus->dev, "itedtv_usb_alloc_work_buffers: CreateEventW() failed. (i: %u)\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (works[i].buffer && works[i].size != buf_size) {
|
||||
VirtualFree(works[i].buffer, 0, MEM_RELEASE);
|
||||
works[i].buffer = NULL;
|
||||
}
|
||||
|
||||
if (!works[i].buffer) {
|
||||
p = VirtualAlloc(NULL, buf_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!p) {
|
||||
dev_err(bus->dev, "itedtv_usb_alloc_work_buffers: VirtualAlloc() failed. (i: %u)\n", i);
|
||||
CloseHandle(works[i].ol.hEvent);
|
||||
works[i].ol.hEvent = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_alloc_work_buffers: p: %p, buf_size: %u\n", p, buf_size);
|
||||
|
||||
works[i].buffer = p;
|
||||
works[i].size = buf_size;
|
||||
}
|
||||
|
||||
works[i].can_submit = true;
|
||||
}
|
||||
|
||||
ctx->num_urb = i;
|
||||
|
||||
if (!i)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void itedtv_usb_free_work_buffers(struct itedtv_usb_context *ctx)
|
||||
{
|
||||
uint32_t i;
|
||||
struct usb_device *dev = ctx->bus->usb.dev;
|
||||
uint32_t num = ctx->num_works;
|
||||
struct itedtv_usb_work *works = ctx->works;
|
||||
|
||||
if (!works)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (works[i].ol.hEvent) {
|
||||
CloseHandle(works[i].ol.hEvent);
|
||||
works[i].ol.hEvent = NULL;
|
||||
}
|
||||
|
||||
if (works[i].buffer) {
|
||||
VirtualFree(works[i].buffer, 0, MEM_RELEASE);
|
||||
works[i].buffer = NULL;
|
||||
}
|
||||
|
||||
works[i].size = 0;
|
||||
works[i].can_submit = false;
|
||||
}
|
||||
|
||||
ctx->num_urb = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void itedtv_usb_clean_context(struct itedtv_usb_context *ctx)
|
||||
{
|
||||
if (ctx->works) {
|
||||
itedtv_usb_free_work_buffers(ctx);
|
||||
free(ctx->works);
|
||||
}
|
||||
|
||||
ctx->stream_handler = NULL;
|
||||
ctx->ctx = NULL;
|
||||
ctx->num_urb = 0;
|
||||
ctx->num_works = 0;
|
||||
ctx->works = NULL;
|
||||
}
|
||||
|
||||
unsigned __stdcall itedtv_winusb_worker(void *arg)
|
||||
{
|
||||
struct itedtv_usb_context *ctx = arg;
|
||||
struct itedtv_bus *bus = ctx->bus;
|
||||
uint32_t i, num, next_idx = 0;
|
||||
struct itedtv_usb_work *works;
|
||||
WINUSB_INTERFACE_HANDLE winusb;
|
||||
UCHAR raw_io;
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_winusb_worker: start\n");
|
||||
|
||||
num = ctx->num_urb;
|
||||
works = ctx->works;
|
||||
winusb = bus->usb.dev->winusb;
|
||||
raw_io = (ctx->no_raw_io) ? 0 : 1;
|
||||
|
||||
if (!WinUsb_SetPipePolicy(winusb, 0x84, RAW_IO, sizeof(raw_io), &raw_io)) {
|
||||
dev_err(bus->dev, "itedtv_winusb_worker: WinUsb_SetPipePolicy(RAW_IO, %u) failed.\n", raw_io);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!works[i].can_submit)
|
||||
continue;
|
||||
|
||||
works[i].can_submit = false;
|
||||
ResetEvent(works[i].ol.hEvent);
|
||||
|
||||
if (WinUsb_ReadPipe(winusb, 0x84, works[i].buffer, (ULONG)works[i].size, NULL, &works[i].ol))
|
||||
continue;
|
||||
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
continue;
|
||||
|
||||
dev_err(bus->dev, "itedtv_winusb_worker: WinUsb_ReadPipe() 1 failed. (%u, %u)\n", i, GetLastError());
|
||||
works[i].can_submit = true;
|
||||
|
||||
num = i;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_winusb_worker: num: %u\n", num);
|
||||
|
||||
while (ctx->streaming) {
|
||||
uint32_t idx = next_idx;
|
||||
DWORD ret, rlen = 0;
|
||||
struct itedtv_usb_work *work = &works[idx];
|
||||
|
||||
if (work->can_submit) {
|
||||
dev_dbg(bus->dev, "itedtv_winusb_worker: can_submit %u\n", idx);
|
||||
for (i = (idx + 1) % num; i != idx; i = (i + 1) % num) {
|
||||
if (!works[i].can_submit)
|
||||
break;
|
||||
}
|
||||
if (i == idx)
|
||||
break;
|
||||
|
||||
idx = i;
|
||||
work = &works[idx];
|
||||
}
|
||||
|
||||
ret = WaitForSingleObject(work->ol.hEvent, 500);
|
||||
if (ret == WAIT_TIMEOUT) {
|
||||
dev_dbg(bus->dev, "itedtv_winusb_worker: timeout %u\n", idx);
|
||||
continue;
|
||||
} else if (ret == WAIT_FAILED)
|
||||
break;
|
||||
|
||||
if (WinUsb_GetOverlappedResult(winusb, &work->ol, &rlen, TRUE))
|
||||
ctx->stream_handler(ctx->ctx, work->buffer, rlen);
|
||||
|
||||
next_idx = (idx + 1) % num;
|
||||
ResetEvent(work->ol.hEvent);
|
||||
|
||||
if (WinUsb_ReadPipe(winusb, 0x84, work->buffer, (ULONG)work->size, NULL, &work->ol))
|
||||
continue;
|
||||
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
continue;
|
||||
|
||||
dev_err(bus->dev, "itedtv_winusb_worker: WinUsb_ReadPipe() 2 failed. (%u, %u)\n", idx, GetLastError());
|
||||
work->can_submit = true;
|
||||
}
|
||||
|
||||
WinUsb_AbortPipe(winusb, 0x84);
|
||||
|
||||
if (raw_io) {
|
||||
raw_io = 0;
|
||||
WinUsb_SetPipePolicy(winusb, 0x84, RAW_IO, sizeof(raw_io), &raw_io);
|
||||
}
|
||||
|
||||
exit:
|
||||
dev_dbg(bus->dev, "itedtv_winusb_worker: exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int itedtv_usb_start_streaming(struct itedtv_bus *bus, itedtv_bus_stream_handler_t stream_handler, void *context)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 buf_size, num;
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
struct itedtv_usb_work *works;
|
||||
|
||||
if (!stream_handler)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_start_streaming\n");
|
||||
|
||||
EnterCriticalSection(&ctx->lock);
|
||||
|
||||
ctx->stream_handler = stream_handler;
|
||||
ctx->ctx = context;
|
||||
ctx->no_raw_io = bus->usb.streaming.no_raw_io;
|
||||
|
||||
buf_size = bus->usb.streaming.urb_buffer_size;
|
||||
num = bus->usb.streaming.urb_num;
|
||||
|
||||
if (num > 64)
|
||||
goto fail;
|
||||
|
||||
if (!ctx->no_raw_io && (buf_size % bus->usb.max_bulk_size))
|
||||
buf_size += bus->usb.max_bulk_size - (buf_size % bus->usb.max_bulk_size);
|
||||
|
||||
if (ctx->works && num != ctx->num_works) {
|
||||
itedtv_usb_free_work_buffers(ctx);
|
||||
free(ctx->works);
|
||||
ctx->works = NULL;
|
||||
}
|
||||
|
||||
ctx->num_works = num;
|
||||
|
||||
if (!ctx->works) {
|
||||
ctx->works = calloc(ctx->num_works, sizeof(*works));
|
||||
if (!ctx->works) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = itedtv_usb_alloc_work_buffers(ctx, buf_size);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
WinUsb_ResetPipe(bus->usb.dev->winusb, 0x84);
|
||||
InterlockedExchange(&ctx->streaming, 1);
|
||||
|
||||
ctx->worker_thread = (HANDLE)_beginthreadex(NULL, 0, itedtv_winusb_worker, ctx, 0, NULL);
|
||||
if (!ctx->worker_thread) {
|
||||
dev_err(bus->dev, "itedtv_usb_start_streaming: _beginthreadex() failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!SetThreadPriority(ctx->worker_thread, THREAD_PRIORITY_TIME_CRITICAL))
|
||||
dev_dbg(bus->dev, "itedtv_usb_start_streaming: SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL) failed.\n");
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_start_streaming: num: %u\n", num);
|
||||
|
||||
LeaveCriticalSection(&ctx->lock);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
InterlockedExchange(&ctx->streaming, 0);
|
||||
|
||||
if (ctx->worker_thread) {
|
||||
WaitForSingleObject(ctx->worker_thread, INFINITE);
|
||||
CloseHandle(ctx->worker_thread);
|
||||
ctx->worker_thread = NULL;
|
||||
}
|
||||
|
||||
itedtv_usb_clean_context(ctx);
|
||||
|
||||
LeaveCriticalSection(&ctx->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_stop_streaming(struct itedtv_bus *bus)
|
||||
{
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_stop_streaming\n");
|
||||
|
||||
EnterCriticalSection(&ctx->lock);
|
||||
|
||||
InterlockedExchange(&ctx->streaming, 0);
|
||||
|
||||
WaitForSingleObject(ctx->worker_thread, INFINITE);
|
||||
CloseHandle(ctx->worker_thread);
|
||||
ctx->worker_thread = NULL;
|
||||
|
||||
itedtv_usb_clean_context(ctx);
|
||||
|
||||
LeaveCriticalSection(&ctx->lock);
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_stop_streaming: exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int itedtv_bus_init(struct itedtv_bus *bus)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
|
||||
switch (bus->type) {
|
||||
case ITEDTV_BUS_USB:
|
||||
{
|
||||
UCHAR raw_io;
|
||||
struct itedtv_usb_context *ctx;
|
||||
|
||||
if (!bus->usb.dev) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bus->usb.dev->descriptor.bcdUSB < 0x0110) {
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
raw_io = 1;
|
||||
if (!WinUsb_SetPipePolicy(bus->usb.dev->winusb, 0x84, RAW_IO, sizeof(raw_io), &raw_io)) {
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
break;
|
||||
}
|
||||
|
||||
ctx = malloc(sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&ctx->lock);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ctx->ctrl_event[i] = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
if (!ctx->ctrl_event[i]) {
|
||||
ret = -winerr_to_errno(bus->dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctx->bus = bus;
|
||||
ctx->stream_handler = NULL;
|
||||
ctx->ctx = NULL;
|
||||
ctx->num_urb = 0;
|
||||
ctx->num_works = 0;
|
||||
ctx->works = NULL;
|
||||
ctx->streaming = 0;
|
||||
ctx->worker_thread = NULL;
|
||||
|
||||
bus->usb.priv = ctx;
|
||||
|
||||
if (!bus->usb.max_bulk_size)
|
||||
bus->usb.max_bulk_size = (bus->usb.dev->descriptor.bcdUSB == 0x0110) ? 64 : 512;
|
||||
|
||||
bus->ops.ctrl_tx = itedtv_usb_ctrl_tx;
|
||||
bus->ops.ctrl_rx = itedtv_usb_ctrl_rx;
|
||||
bus->ops.stream_rx = itedtv_usb_stream_rx;
|
||||
bus->ops.start_streaming = itedtv_usb_start_streaming;
|
||||
bus->ops.stop_streaming = itedtv_usb_stop_streaming;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int itedtv_bus_term(struct itedtv_bus *bus)
|
||||
{
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
|
||||
switch (bus->type) {
|
||||
case ITEDTV_BUS_USB:
|
||||
{
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
|
||||
if (ctx) {
|
||||
itedtv_usb_stop_streaming(bus);
|
||||
CloseHandle(ctx->ctrl_event[0]);
|
||||
CloseHandle(ctx->ctrl_event[1]);
|
||||
DeleteCriticalSection(&ctx->lock);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_bus_term: exit\n");
|
||||
|
||||
memset(bus, 0, sizeof(*bus));
|
||||
|
||||
return 0;
|
||||
}
|
51
winusb/src/DriverHost_PX4/main.cpp
Normal file
51
winusb/src/DriverHost_PX4/main.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// main.cpp
|
||||
|
||||
#define msg_prefix "DriverHost_PX4"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "driver_host.hpp"
|
||||
#include "util.hpp"
|
||||
#include "msg.h"
|
||||
|
||||
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR pCmdLine, _In_ int nCmdShow)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
FILE *fp;
|
||||
|
||||
AllocConsole();
|
||||
|
||||
freopen_s(&fp, "CONOUT$", "w", stdout);
|
||||
freopen_s(&fp, "CONOUT$", "w", stderr);
|
||||
|
||||
msg_set_mode(MSG_MODE_CONSOLE);
|
||||
#else
|
||||
msg_set_mode(MSG_MODE_DEBUGGER);
|
||||
#endif
|
||||
|
||||
msg_info("Start\n");
|
||||
|
||||
px4::util::path::Init(hInstance);
|
||||
|
||||
try {
|
||||
px4::DriverHost host;
|
||||
|
||||
host.Run();
|
||||
} catch (const std::runtime_error & e) {
|
||||
msg_err("%s\n", e.what());
|
||||
MessageBoxA(nullptr, e.what(), "DriverHost_PX4 (wWinMain)", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
msg_info("Exiting...\n");
|
||||
|
||||
#ifdef _DEBUG
|
||||
Sleep(2000);
|
||||
FreeConsole();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
75
winusb/src/DriverHost_PX4/misc_win.c
Normal file
75
winusb/src/DriverHost_PX4/misc_win.c
Normal file
@@ -0,0 +1,75 @@
|
||||
// misc_win.c
|
||||
|
||||
#include "misc_win.h"
|
||||
|
||||
int request_firmware(const struct firmware **p, const char *name, struct device *dummy)
|
||||
{
|
||||
int ret = 0;
|
||||
HANDLE file;
|
||||
LARGE_INTEGER size;
|
||||
DWORD remain;
|
||||
struct firmware *fw;
|
||||
uint8_t *buf = NULL, *data;
|
||||
|
||||
file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
ret = -ENOENT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!GetFileSizeEx(file, &size)) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (size.HighPart) {
|
||||
ret = -EFBIG;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buf = malloc(sizeof(*fw) + size.LowPart);
|
||||
if (!buf) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fw = (struct firmware *)buf;
|
||||
data = buf + sizeof(*fw);
|
||||
|
||||
remain = size.LowPart;
|
||||
|
||||
while (remain) {
|
||||
DWORD read = 0;
|
||||
|
||||
if (!ReadFile(file, data + (size.LowPart - remain), remain, &read, NULL)) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
remain -= read;
|
||||
}
|
||||
|
||||
fw->size = size.LowPart;
|
||||
fw->data = data;
|
||||
|
||||
*p = fw;
|
||||
|
||||
CloseHandle(file);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (buf)
|
||||
free(buf);
|
||||
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void release_firmware(const struct firmware *fw)
|
||||
{
|
||||
free((void *)fw);
|
||||
return;
|
||||
}
|
112
winusb/src/DriverHost_PX4/misc_win.h
Normal file
112
winusb/src/DriverHost_PX4/misc_win.h
Normal file
@@ -0,0 +1,112 @@
|
||||
// misc_win.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#define msleep(ms) Sleep(ms)
|
||||
#define mdelay(ms) /* do nothing*/
|
||||
|
||||
#define GFP_KERNEL 0
|
||||
#define GFP_ATOMIC 0
|
||||
|
||||
#define kmalloc(size, gfp) malloc(size)
|
||||
#define kcalloc(n, size, gfp) calloc(n, size)
|
||||
#define kfree(p) free(p)
|
||||
|
||||
static inline void * kzalloc(size_t size, int dummy)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = malloc(size);
|
||||
if (p)
|
||||
memset(p, 0, size);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
struct mutex {
|
||||
CRITICAL_SECTION s;
|
||||
};
|
||||
|
||||
static inline void mutex_init(struct mutex *lock)
|
||||
{
|
||||
InitializeCriticalSection(&lock->s);
|
||||
}
|
||||
|
||||
static inline void mutex_destroy(struct mutex *lock)
|
||||
{
|
||||
DeleteCriticalSection(&lock->s);
|
||||
}
|
||||
|
||||
static inline void mutex_lock(struct mutex *lock)
|
||||
{
|
||||
EnterCriticalSection(&lock->s);
|
||||
}
|
||||
|
||||
static inline void mutex_unlock(struct mutex *lock)
|
||||
{
|
||||
LeaveCriticalSection(&lock->s);
|
||||
}
|
||||
|
||||
struct device {
|
||||
char driver_name[64];
|
||||
char device_name[64];
|
||||
};
|
||||
|
||||
#define printk(format, ...) msg_printf(format, ##__VA_ARGS__)
|
||||
|
||||
#define dev_print(level, dev, format, ...) msg_printf("[" level "] %s %s: " format, (dev)->driver_name, (dev)->device_name, ##__VA_ARGS__)
|
||||
|
||||
#define dev_err(dev, format, ...) dev_print("ERR", dev, format, ##__VA_ARGS__)
|
||||
#define dev_warn(dev, format, ...) dev_print("WARN", dev, format, ##__VA_ARGS__)
|
||||
#define dev_info(dev, format, ...) dev_print("INFO", dev, format, ##__VA_ARGS__)
|
||||
#if defined(_DEBUG) || defined(_DEBUG_MSG)
|
||||
#define dev_dbg(dev, format, ...) dev_print("DBG", dev, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define dev_dbg(dev, format, ...)
|
||||
#endif
|
||||
|
||||
typedef int atomic_t;
|
||||
|
||||
static inline void atomic_set(atomic_t *p, int v)
|
||||
{
|
||||
_ReadWriteBarrier();
|
||||
*p = v;
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
static inline int atomic_read(const atomic_t *p)
|
||||
{
|
||||
int v;
|
||||
|
||||
_ReadWriteBarrier();
|
||||
v = *p;
|
||||
_ReadWriteBarrier();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
struct firmware {
|
||||
size_t size;
|
||||
const u8 *data;
|
||||
};
|
||||
|
||||
int request_firmware(const struct firmware **fw, const char *name, struct device *);
|
||||
void release_firmware(const struct firmware *fw);
|
139
winusb/src/DriverHost_PX4/notify_icon.cpp
Normal file
139
winusb/src/DriverHost_PX4/notify_icon.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
// notify_icon.cpp
|
||||
|
||||
#include "notify_icon.hpp"
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
#define WM_NOTIFYICON (WM_USER + 0x100);
|
||||
|
||||
UINT NotifyIcon::next_id_ = 1;
|
||||
|
||||
NotifyIcon::NotifyIcon(LPCWSTR icon_name, std::wstring tip)
|
||||
: hinst_(GetModuleHandleW(nullptr)),
|
||||
hwnd_(nullptr),
|
||||
param_(new CreateParam(icon_name, tip)),
|
||||
mtx_(),
|
||||
cond_(),
|
||||
ready_(false),
|
||||
th_(&px4::NotifyIcon::Worker, this)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
|
||||
cond_.wait(lock);
|
||||
param_.release();
|
||||
|
||||
if (!ready_.load()) {
|
||||
lock.unlock();
|
||||
throw NotifyIconError("px4::NotifyIcon::NotifyIcon: failed.");
|
||||
}
|
||||
}
|
||||
|
||||
NotifyIcon::~NotifyIcon()
|
||||
{
|
||||
SendMessageW(hwnd_, WM_CLOSE, 0, 0);
|
||||
th_.join();
|
||||
}
|
||||
|
||||
LRESULT CALLBACK NotifyIcon::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
void *p;
|
||||
NotifyIcon *ni = nullptr;
|
||||
static NOTIFYICONDATAW nid;
|
||||
|
||||
p = reinterpret_cast<void *>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
|
||||
if (p) {
|
||||
ni = reinterpret_cast<NotifyIcon *>(DecodePointer(p));
|
||||
} else if (uMsg == WM_CREATE && lParam) {
|
||||
ni = reinterpret_cast<NotifyIcon *>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(EncodePointer(ni)));
|
||||
}
|
||||
|
||||
if (!ni)
|
||||
return -1;
|
||||
|
||||
std::unique_lock<std::mutex> lock(ni->mtx_, std::defer_lock);
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_CREATE:
|
||||
{
|
||||
nid.cbSize = sizeof(NOTIFYICONDATAW);
|
||||
nid.hWnd = hwnd;
|
||||
nid.uID = next_id_++;
|
||||
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
||||
nid.uCallbackMessage = WM_NOTIFYICON;
|
||||
nid.hIcon = LoadIconW(ni->hinst_, ni->param_->icon_name);
|
||||
wcscpy_s(nid.szTip, sizeof(nid.szTip) / sizeof(nid.szTip[0]), ni->param_->tip.c_str());
|
||||
|
||||
Shell_NotifyIconW(NIM_ADD, &nid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwnd);
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
lock.lock();
|
||||
|
||||
Shell_NotifyIcon(NIM_DELETE, &nid);
|
||||
DestroyIcon(nid.hIcon);
|
||||
|
||||
lock.unlock();
|
||||
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
void NotifyIcon::Worker()
|
||||
{
|
||||
WCHAR class_name[] = TEXT("NotifyIcon_MessageWindow");
|
||||
WNDCLASSEXW wc;
|
||||
MSG msg;
|
||||
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hinst_;
|
||||
wc.hIcon = nullptr;
|
||||
wc.hCursor = nullptr;
|
||||
wc.hbrBackground = nullptr;
|
||||
wc.lpszMenuName = nullptr;
|
||||
wc.lpszClassName = class_name;
|
||||
wc.hIconSm = nullptr;
|
||||
|
||||
if (!RegisterClassExW(&wc)) {
|
||||
ready_.store(false);
|
||||
cond_.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
hwnd_ = CreateWindowExW(0, class_name, nullptr, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, nullptr, hinst_, this);
|
||||
if (!hwnd_) {
|
||||
ready_.store(false);
|
||||
cond_.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
ready_.store(true);
|
||||
cond_.notify_all();
|
||||
|
||||
while (GetMessage(&msg, nullptr, 0, 0) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace px4
|
58
winusb/src/DriverHost_PX4/notify_icon.hpp
Normal file
58
winusb/src/DriverHost_PX4/notify_icon.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// notify_icon.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class NotifyIcon final {
|
||||
public:
|
||||
NotifyIcon(LPCWSTR icon_name, std::wstring tip);
|
||||
~NotifyIcon();
|
||||
|
||||
// cannot copy
|
||||
NotifyIcon(const NotifyIcon &) = delete;
|
||||
NotifyIcon& operator=(const NotifyIcon &) = delete;
|
||||
|
||||
// cannot move
|
||||
NotifyIcon(NotifyIcon &&) = delete;
|
||||
NotifyIcon& operator=(NotifyIcon &&) = delete;
|
||||
|
||||
private:
|
||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
void Worker();
|
||||
|
||||
struct CreateParam {
|
||||
CreateParam(LPCWSTR icon_name, std::wstring &tip)
|
||||
: icon_name(icon_name), tip(tip)
|
||||
{
|
||||
}
|
||||
|
||||
LPCWSTR icon_name;
|
||||
std::wstring &tip;
|
||||
};
|
||||
|
||||
static UINT next_id_;
|
||||
HINSTANCE hinst_;
|
||||
HWND hwnd_;
|
||||
std::unique_ptr<CreateParam> param_;
|
||||
std::mutex mtx_;
|
||||
std::condition_variable cond_;
|
||||
std::atomic_bool ready_;
|
||||
std::thread th_;
|
||||
};
|
||||
|
||||
class NotifyIconError : public std::runtime_error {
|
||||
public:
|
||||
explicit NotifyIconError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
98
winusb/src/DriverHost_PX4/pipe_server.cpp
Normal file
98
winusb/src/DriverHost_PX4/pipe_server.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// pipe_server.cpp
|
||||
|
||||
#include "pipe_server.hpp"
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
PipeServer::PipeServer() noexcept
|
||||
: Pipe()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PipeServer::~PipeServer()
|
||||
{
|
||||
if (!IsConnected())
|
||||
return;
|
||||
|
||||
FlushFileBuffers(handle_);
|
||||
DisconnectNamedPipe(handle_);
|
||||
}
|
||||
|
||||
bool PipeServer::Accept(const std::wstring &name, const PipeServerConfig &config, HANDLE ready_event, HANDLE cancel_event, DWORD timeout) noexcept
|
||||
{
|
||||
if (IsConnected())
|
||||
return false;
|
||||
|
||||
bool ret = false;
|
||||
std::wstring path = L"\\\\.\\pipe\\" + name;
|
||||
OVERLAPPED ol = { 0 };
|
||||
DWORD mode = 0;
|
||||
HANDLE pipe_handle = nullptr;
|
||||
|
||||
ol.hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!ol.hEvent) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mode |= (config.stream_pipe) ? PIPE_TYPE_BYTE : PIPE_TYPE_MESSAGE;
|
||||
mode |= (config.stream_read) ? PIPE_READMODE_BYTE : PIPE_READMODE_MESSAGE;
|
||||
mode |= PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS;
|
||||
|
||||
pipe_handle = CreateNamedPipeW(
|
||||
path.c_str(),
|
||||
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
mode,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
static_cast<DWORD>(config.out_buffer_size),
|
||||
static_cast<DWORD>(config.in_buffer_size),
|
||||
config.default_timeout,
|
||||
nullptr);
|
||||
if (pipe_handle == INVALID_HANDLE_VALUE) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ready_event)
|
||||
SetEvent(ready_event);
|
||||
|
||||
if (ConnectNamedPipe(pipe_handle, &ol)) {
|
||||
ret = true;
|
||||
goto exit;
|
||||
} else {
|
||||
DWORD err = GetLastError();
|
||||
|
||||
if (err == ERROR_IO_PENDING || err == ERROR_PIPE_LISTENING) {
|
||||
HANDLE handles[2] = { ol.hEvent, cancel_event };
|
||||
DWORD res, t;
|
||||
|
||||
res = WaitForMultipleObjects((cancel_event) ? 2 : 1, handles, FALSE, INFINITE);
|
||||
if (res == WAIT_OBJECT_0 && GetOverlappedResult(pipe_handle, &ol, &t, TRUE))
|
||||
ret = true;
|
||||
else
|
||||
error_.assign(err, std::system_category());
|
||||
} else if (err == ERROR_PIPE_CONNECTED) {
|
||||
ret = true;
|
||||
} else {
|
||||
error_.assign(err, std::system_category());
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
if (ret) {
|
||||
SetHandle(pipe_handle);
|
||||
} else {
|
||||
if (pipe_handle && pipe_handle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pipe_handle);
|
||||
}
|
||||
|
||||
if (ol.hEvent)
|
||||
CloseHandle(ol.hEvent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace px4
|
30
winusb/src/DriverHost_PX4/pipe_server.hpp
Normal file
30
winusb/src/DriverHost_PX4/pipe_server.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// pipe_server.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pipe.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class PipeServer final : public px4::Pipe {
|
||||
public:
|
||||
struct PipeServerConfig {
|
||||
bool stream_pipe;
|
||||
bool stream_read;
|
||||
std::size_t out_buffer_size;
|
||||
std::size_t in_buffer_size;
|
||||
std::uint32_t default_timeout;
|
||||
};
|
||||
|
||||
PipeServer() noexcept;
|
||||
~PipeServer();
|
||||
|
||||
bool Accept(const std::wstring &name, const PipeServerConfig &config, HANDLE ready_event, HANDLE cancel_event, DWORD timeout = INFINITE) noexcept;
|
||||
};
|
||||
|
||||
} // namespace px4
|
1395
winusb/src/DriverHost_PX4/px4_device.cpp
Normal file
1395
winusb/src/DriverHost_PX4/px4_device.cpp
Normal file
File diff suppressed because it is too large
Load Diff
200
winusb/src/DriverHost_PX4/px4_device.hpp
Normal file
200
winusb/src/DriverHost_PX4/px4_device.hpp
Normal file
@@ -0,0 +1,200 @@
|
||||
// px4_device.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "device_definition_set.hpp"
|
||||
#include "device_base.hpp"
|
||||
#include "receiver_base.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
#include "ringbuffer.hpp"
|
||||
|
||||
#include "winusb_compat.h"
|
||||
|
||||
#include "i2c_comm.h"
|
||||
#include "it930x.h"
|
||||
#include "itedtv_bus.h"
|
||||
#include "tc90522.h"
|
||||
#include "r850.h"
|
||||
#include "rt710.h"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
#define PX4_DEVICE_TS_SYNC_COUNT 4U
|
||||
#define PX4_DEVICE_TS_SYNC_SIZE (188U * PX4_DEVICE_TS_SYNC_COUNT)
|
||||
|
||||
struct Px4DeviceConfig final {
|
||||
Px4DeviceConfig()
|
||||
: usb{ 816, 816, 5, false },
|
||||
device{ 2048, 2000, true }
|
||||
{}
|
||||
struct {
|
||||
unsigned int xfer_packets;
|
||||
unsigned int urb_max_packets;
|
||||
unsigned int max_urbs;
|
||||
bool no_raw_io;
|
||||
} usb;
|
||||
struct {
|
||||
unsigned int receiver_max_packets;
|
||||
int psb_purge_timeout;
|
||||
bool discard_null_packets;
|
||||
} device;
|
||||
};
|
||||
|
||||
class Px4Device final : public px4::DeviceBase {
|
||||
public:
|
||||
Px4Device() = delete;
|
||||
Px4Device(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager);
|
||||
~Px4Device();
|
||||
|
||||
// cannot copy
|
||||
Px4Device(const Px4Device &) = delete;
|
||||
Px4Device& operator=(const Px4Device &) = delete;
|
||||
|
||||
// cannot move
|
||||
Px4Device(Px4Device &&) = delete;
|
||||
Px4Device& operator=(Px4Device &&) = delete;
|
||||
|
||||
int Init() override;
|
||||
void Term() override;
|
||||
void SetAvailability(bool available) override;
|
||||
px4::ReceiverBase * GetReceiver(int id) const override;
|
||||
|
||||
private:
|
||||
struct SerialNumber final {
|
||||
std::uint64_t serial_number;
|
||||
std::uint8_t dev_id;
|
||||
};
|
||||
struct StreamContext final {
|
||||
std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf[4];
|
||||
std::uint8_t remain_buf[PX4_DEVICE_TS_SYNC_SIZE];
|
||||
std::size_t remain_len;
|
||||
};
|
||||
|
||||
class MultiDevice final {
|
||||
public:
|
||||
enum class Mode {
|
||||
ALL = 0,
|
||||
S_ONLY,
|
||||
S0_ONLY,
|
||||
S1_ONLY
|
||||
};
|
||||
|
||||
~MultiDevice();
|
||||
|
||||
// cannot copy
|
||||
MultiDevice(const MultiDevice &) = delete;
|
||||
MultiDevice& operator=(const MultiDevice &) = delete;
|
||||
|
||||
// cannot move
|
||||
MultiDevice(MultiDevice &&) = delete;
|
||||
MultiDevice& operator=(MultiDevice &&) = delete;
|
||||
|
||||
static bool Search(std::uint64_t serial_number, std::shared_ptr<MultiDevice> &mldev);
|
||||
static int Alloc(Px4Device &dev, Mode mode, std::shared_ptr<MultiDevice> &mldev);
|
||||
|
||||
int Add(Px4Device &dev);
|
||||
int Remove(Px4Device &dev);
|
||||
int SetPower(Px4Device &dev, std::uintptr_t index, bool state, bool *first);
|
||||
|
||||
private:
|
||||
MultiDevice(Mode mode, std::uint64_t serial_number);
|
||||
|
||||
std::uint8_t GetDeviceCount() const noexcept;
|
||||
bool GetReceiverStatus(std::uint8_t dev_id) const noexcept;
|
||||
bool IsPowerIntelockingRequried(std::uint8_t dev_id) const noexcept;
|
||||
|
||||
static std::mutex mldev_list_lock_;
|
||||
static std::unordered_map<std::uint64_t, std::shared_ptr<MultiDevice>> mldev_list_;
|
||||
|
||||
std::mutex lock_;
|
||||
std::uint64_t serial_number_;
|
||||
Mode mode_;
|
||||
Px4Device *dev_[2];
|
||||
bool power_state_[2];
|
||||
bool receiver_state_[2][4];
|
||||
};
|
||||
|
||||
class Px4Receiver final : public px4::ReceiverBase {
|
||||
public:
|
||||
Px4Receiver() = delete;
|
||||
Px4Receiver(Px4Device &parent, std::uintptr_t index);
|
||||
~Px4Receiver();
|
||||
|
||||
// cannot copy
|
||||
Px4Receiver(const Px4Receiver &) = delete;
|
||||
Px4Receiver& operator=(const Px4Receiver &) = delete;
|
||||
|
||||
// cannot move
|
||||
Px4Receiver(Px4Receiver &&) = delete;
|
||||
Px4Receiver& operator=(Px4Receiver &&) = delete;
|
||||
|
||||
int Init(bool sleep);
|
||||
void Term();
|
||||
|
||||
int Open() override;
|
||||
void Close() override;
|
||||
int Tune() override;
|
||||
int CheckLock(bool &locked) override;
|
||||
int SetLnbVoltage(std::int32_t voltage) override;
|
||||
int SetCapture(bool capture) override;
|
||||
int ReadStat(px4::command::StatType type, std::int32_t &value) override;
|
||||
|
||||
int InitPrimary();
|
||||
|
||||
private:
|
||||
static struct tc90522_regbuf tc_init_t0_[];
|
||||
static struct tc90522_regbuf tc_init_s0_[];
|
||||
static struct tc90522_regbuf tc_init_t_[];
|
||||
static struct tc90522_regbuf tc_init_s_[];
|
||||
|
||||
Px4Device &parent_;
|
||||
std::uintptr_t index_;
|
||||
|
||||
std::mutex lock_;
|
||||
px4::SystemType system_;
|
||||
std::atomic_bool init_;
|
||||
std::atomic_bool open_;
|
||||
std::condition_variable close_cond_;
|
||||
bool lnb_power_;
|
||||
tc90522_demod tc90522_;
|
||||
union {
|
||||
r850_tuner r850_;
|
||||
rt710_tuner rt710_;
|
||||
};
|
||||
std::atomic_bool streaming_;
|
||||
};
|
||||
|
||||
const i2c_comm_master& GetI2cMaster(int bus) const;
|
||||
|
||||
int SetBackendPower(bool state);
|
||||
int SetLnbVoltage(std::int32_t voltage);
|
||||
|
||||
int PrepareCapture();
|
||||
int StartCapture();
|
||||
int StopCapture();
|
||||
|
||||
static void StreamProcess(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf[], std::uint8_t **buf, std::size_t &len);
|
||||
static int StreamHandler(void *context, void *buf, std::uint32_t len);
|
||||
|
||||
Px4DeviceConfig config_;
|
||||
std::recursive_mutex lock_;
|
||||
std::atomic_bool available_;
|
||||
SerialNumber serial_;
|
||||
std::shared_ptr<MultiDevice> mldev_;
|
||||
std::atomic_bool init_;
|
||||
unsigned int open_count_;
|
||||
unsigned int lnb_power_count_;
|
||||
unsigned int streaming_count_;
|
||||
std::unique_ptr<Px4Receiver> receivers_[4];
|
||||
it930x_bridge it930x_;
|
||||
StreamContext stream_ctx_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
960
winusb/src/DriverHost_PX4/pxmlt_device.cpp
Normal file
960
winusb/src/DriverHost_PX4/pxmlt_device.cpp
Normal file
@@ -0,0 +1,960 @@
|
||||
// pxmlt_device.cpp
|
||||
|
||||
#include "pxmlt_device.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include "type.hpp"
|
||||
#include "command.hpp"
|
||||
#include "misc_win.h"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
const PxMltDevice::PxMltDeviceParam PxMltDevice::params_[][5] = {
|
||||
/* PX-MLT5U */
|
||||
{ { 0x65, 3, 4 }, { 0x6c, 1, 3 }, { 0x64, 1, 1 }, { 0x6c, 3, 2 }, { 0x64, 3, 0 } },
|
||||
/* PX-MLT5PE */
|
||||
{ { 0x65, 3, 0 }, { 0x6c, 1, 1 }, { 0x64, 1, 2 }, { 0x6c, 3, 3 }, { 0x64, 3, 4 } },
|
||||
/* PX-MLT8PE3 */
|
||||
{ { 0x65, 3, 0 }, { 0x6c, 3, 3 }, { 0x64, 3, 4 }, { 0x00, 0, 1 }, { 0x00, 0, 2 } },
|
||||
/* PX-MLT8PE5 */
|
||||
{ { 0x65, 1, 0 }, { 0x64, 1, 1 }, { 0x6c, 1, 2 }, { 0x6c, 3, 3 }, { 0x64, 3, 4 } },
|
||||
/* ISDB6014 V2.0 (4TS) */
|
||||
{ { 0x65, 3, 0 }, { 0x6c, 1, 1 }, { 0x64, 1, 2 }, { 0x64, 3, 4 }, { 0x00, 0, 3 } }
|
||||
};
|
||||
|
||||
PxMltDevice::PxMltDevice(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager)
|
||||
: DeviceBase(path, device_def, index, receiver_manager),
|
||||
config_(),
|
||||
lock_(),
|
||||
available_(false),
|
||||
init_(false),
|
||||
open_count_(0),
|
||||
lnb_power_count_(0),
|
||||
streaming_count_(0),
|
||||
tuner_lock_{}
|
||||
{
|
||||
if (usb_dev_.descriptor.idVendor != 0x0511)
|
||||
throw DeviceError("px4::PxMltDevice::PxMltDevice: unsupported device. (unknown vendor id)");
|
||||
|
||||
receiver_num_ = 5;
|
||||
|
||||
switch (usb_dev_.descriptor.idProduct) {
|
||||
case 0x084e:
|
||||
model_ = PxMltDeviceModel::PXMLT5U;
|
||||
break;
|
||||
|
||||
case 0x24e:
|
||||
model_ = PxMltDeviceModel::PXMLT5PE;
|
||||
break;
|
||||
|
||||
case 0x0252:
|
||||
model_ = PxMltDeviceModel::PXMLT8PE3;
|
||||
receiver_num_ = 3;
|
||||
break;
|
||||
|
||||
case 0x0253:
|
||||
model_ = PxMltDeviceModel::PXMLT8PE5;
|
||||
break;
|
||||
|
||||
case 0x0254:
|
||||
model_ = PxMltDeviceModel::ISDB6014_4TS;
|
||||
receiver_num_ = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw DeviceError("px4::PxMltDevice::PxMltDevice: unsupported device. (unknown product id)");
|
||||
}
|
||||
|
||||
memset(&it930x_, 0, sizeof(it930x_));
|
||||
memset(&stream_ctx_, 0, sizeof(stream_ctx_));
|
||||
}
|
||||
|
||||
PxMltDevice::~PxMltDevice()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
int PxMltDevice::Init()
|
||||
{
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::Init: init_: %s\n", (init_) ? "true" : "false");
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(lock_);
|
||||
|
||||
if (init_)
|
||||
return -EALREADY;
|
||||
|
||||
int ret = 0;
|
||||
itedtv_bus &bus = it930x_.bus;
|
||||
|
||||
bus.dev = &dev_;
|
||||
bus.type = ITEDTV_BUS_USB;
|
||||
bus.usb.dev = &usb_dev_;
|
||||
bus.usb.ctrl_timeout = 3000;
|
||||
|
||||
it930x_.dev = &dev_;
|
||||
it930x_.config.xfer_size = 188 * config_.usb.xfer_packets;
|
||||
it930x_.config.i2c_speed = 0x07;
|
||||
|
||||
ret = itedtv_bus_init(&bus);
|
||||
if (ret)
|
||||
goto fail_bus;
|
||||
|
||||
ret = it930x_init(&it930x_);
|
||||
if (ret)
|
||||
goto fail_bridge;
|
||||
|
||||
for (int i = 0; i < receiver_num_; i++) {
|
||||
it930x_stream_input &input = it930x_.config.input[i];
|
||||
|
||||
input.enable = true;
|
||||
input.is_parallel = false;
|
||||
input.port_number = params_[static_cast<int>(model_)][i].port_number;
|
||||
input.slave_number = i;
|
||||
input.i2c_bus = params_[static_cast<int>(model_)][i].i2c_bus;
|
||||
input.i2c_addr = params_[static_cast<int>(model_)][i].i2c_addr;
|
||||
input.packet_len = 188;
|
||||
input.sync_byte = ((i + 1) << 4) | 0x07;
|
||||
|
||||
receivers_[i].reset(new PxMltReceiver(*this, i));
|
||||
stream_ctx_.stream_buf[i] = receivers_[i]->GetStreamBuffer();
|
||||
}
|
||||
|
||||
for (int i = receiver_num_; i < 5; i++) {
|
||||
it930x_.config.input[i].enable = false;
|
||||
it930x_.config.input[i].port_number = params_[static_cast<int>(model_)][i].port_number;
|
||||
}
|
||||
|
||||
ret = it930x_load_firmware(&it930x_, "it930x-firmware.bin");
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_init_warm(&it930x_);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
/* GPIO */
|
||||
ret = it930x_set_gpio_mode(&it930x_, 7, IT930X_GPIO_OUT, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_write_gpio(&it930x_, 7, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_set_gpio_mode(&it930x_, 2, IT930X_GPIO_OUT, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_write_gpio(&it930x_, 2, false);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_set_gpio_mode(&it930x_, 11, IT930X_GPIO_OUT, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
/* LNB power supply: off */
|
||||
ret = it930x_write_gpio(&it930x_, 11, false);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
if (config_.device.discard_null_packets) {
|
||||
it930x_pid_filter filter;
|
||||
|
||||
filter.block = true;
|
||||
filter.num = 1;
|
||||
filter.pid[0] = 0x1fff;
|
||||
|
||||
for (int i = 0; i < receiver_num_; i++) {
|
||||
ret = it930x_set_pid_filter(&it930x_, i, &filter);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
}
|
||||
}
|
||||
|
||||
init_ = true;
|
||||
|
||||
for (auto it = device_def_.receivers.cbegin(); it != device_def_.receivers.cend(); ++it) {
|
||||
px4::command::ReceiverInfo ri;
|
||||
|
||||
if (it->index < 0 || it->index > 4)
|
||||
continue;
|
||||
|
||||
wcscpy_s(ri.device_name, device_def_.name.c_str());
|
||||
ri.device_guid = device_def_.guid;
|
||||
wcscpy_s(ri.receiver_name, it->name.c_str());
|
||||
ri.receiver_guid = it->guid;
|
||||
ri.systems = it->systems;
|
||||
ri.index = it->index;
|
||||
ri.data_id = 0;
|
||||
|
||||
receiver_manager_.Register(ri, receivers_[it->index].get());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_device:
|
||||
for (int i = 0; i < receiver_num_; i++) {
|
||||
stream_ctx_.stream_buf[i] = nullptr;
|
||||
receivers_[i].reset();
|
||||
}
|
||||
|
||||
it930x_term(&it930x_);
|
||||
|
||||
fail_bridge:
|
||||
itedtv_bus_term(&bus);
|
||||
|
||||
fail_bus:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PxMltDevice::Term()
|
||||
{
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::Term: init_: %s\n", (init_) ? "true" : "false");
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(lock_);
|
||||
|
||||
if (!init_)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < receiver_num_; i++)
|
||||
receiver_manager_.Unregister(receivers_[i].get());
|
||||
|
||||
lock.unlock();
|
||||
|
||||
for (int i = 0; i < receiver_num_; i++) {
|
||||
stream_ctx_.stream_buf[i] = nullptr;
|
||||
receivers_[i].reset();
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
|
||||
it930x_term(&it930x_);
|
||||
itedtv_bus_term(&it930x_.bus);
|
||||
|
||||
init_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
void PxMltDevice::SetAvailability(bool available)
|
||||
{
|
||||
available_ = available;
|
||||
}
|
||||
|
||||
ReceiverBase* PxMltDevice::GetReceiver(int id) const
|
||||
{
|
||||
if (id < 0 || id >= receiver_num_)
|
||||
throw std::out_of_range("receiver id out of range");
|
||||
|
||||
return receivers_[id].get();
|
||||
}
|
||||
|
||||
const i2c_comm_master& PxMltDevice::GetI2cMaster(int bus) const
|
||||
{
|
||||
if (bus < 1 || bus > 3)
|
||||
throw std::out_of_range("bus number out of range");
|
||||
|
||||
return it930x_.i2c_master[bus - 1];
|
||||
}
|
||||
|
||||
int PxMltDevice::SetBackendPower(bool state)
|
||||
{
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::SetBackendPower: state: %s\n", (state) ? "true" : "false");
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::recursive_mutex> lock(lock_);
|
||||
|
||||
if (!state && !available_)
|
||||
return 0;
|
||||
|
||||
if (state) {
|
||||
ret = it930x_write_gpio(&it930x_, 7, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
Sleep(80);
|
||||
|
||||
ret = it930x_write_gpio(&it930x_, 2, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
Sleep(20);
|
||||
} else {
|
||||
it930x_write_gpio(&it930x_, 2, false);
|
||||
it930x_write_gpio(&it930x_, 7, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PxMltDevice::SetLnbVoltage(std::int32_t voltage)
|
||||
{
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::SetLnbVoltage: voltage: %d\n", voltage);
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::recursive_mutex> lock(lock_);
|
||||
|
||||
assert((voltage && lnb_power_count_ >= 0) || (!voltage && lnb_power_count_ > 0));
|
||||
|
||||
if (!voltage) {
|
||||
lnb_power_count_--;
|
||||
if (!available_)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lnb_power_count_)
|
||||
ret = it930x_write_gpio(&it930x_, 11, !!voltage);
|
||||
|
||||
if (voltage && !ret)
|
||||
lnb_power_count_++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PxMltDevice::StartCapture()
|
||||
{
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::StartCapture\n");
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::recursive_mutex> lock(lock_);
|
||||
|
||||
if (!streaming_count_) {
|
||||
ret = it930x_purge_psb(&it930x_, config_.device.psb_purge_timeout);
|
||||
if (ret) {
|
||||
dev_err(&dev_, "px4::PxMltDevice::StartCapture: it930x_purge_psb() failed. (ret: %d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
it930x_.bus.usb.streaming.urb_buffer_size = 188 * config_.usb.urb_max_packets;
|
||||
it930x_.bus.usb.streaming.urb_num = config_.usb.max_urbs;
|
||||
it930x_.bus.usb.streaming.no_dma = true;
|
||||
it930x_.bus.usb.streaming.no_raw_io = config_.usb.no_raw_io;
|
||||
|
||||
stream_ctx_.remain_len = 0;
|
||||
|
||||
ret = itedtv_bus_start_streaming(&it930x_.bus, StreamHandler, this);
|
||||
if (ret) {
|
||||
dev_err(&dev_, "px4::PxMltDevice::StartCapture: itedtv_bus_start_streaming() failed. (ret: %d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
streaming_count_++;
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::StartCapture: streaming_count_: %u\n", streaming_count_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PxMltDevice::StopCapture()
|
||||
{
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::StopCapture\n");
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(lock_);
|
||||
|
||||
assert(streaming_count_ > 0);
|
||||
|
||||
streaming_count_--;
|
||||
if (!streaming_count_) {
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::StopCapture: stopping...\n");
|
||||
itedtv_bus_stop_streaming(&it930x_.bus);
|
||||
} else {
|
||||
dev_dbg(&dev_, "px4::PxMltDevice::StopCapture: streaming_count_: %u\n", streaming_count_);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PxMltDevice::StreamProcess(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf[], std::uint8_t **buf, std::size_t &len)
|
||||
{
|
||||
std::uint8_t *p = *buf;
|
||||
std::size_t remain = len;
|
||||
|
||||
while (remain) {
|
||||
std::size_t i;
|
||||
bool sync_remain = false;
|
||||
|
||||
for (i = 0; i < PXMLT_DEVICE_TS_SYNC_COUNT; i++) {
|
||||
if (((i + 1) * 188) <= remain) {
|
||||
if ((p[i * 188] & 0x8f) != 0x07)
|
||||
break;
|
||||
} else {
|
||||
sync_remain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sync_remain)
|
||||
break;
|
||||
|
||||
if (i < PXMLT_DEVICE_TS_SYNC_COUNT) {
|
||||
p++;
|
||||
remain--;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (remain >= 188 && ((p[0] & 0x8f) == 0x07)) {
|
||||
u8 id = (p[0] & 0x70) >> 4;
|
||||
|
||||
if (id && id < 6) {
|
||||
std::size_t pkt_len = 188;
|
||||
|
||||
p[0] = 0x47;
|
||||
stream_buf[id - 1]->Write(p, pkt_len);
|
||||
}
|
||||
|
||||
p += 188;
|
||||
remain -= 188;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
stream_buf[i]->NotifyWrite();
|
||||
|
||||
*buf = p;
|
||||
len = remain;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int PxMltDevice::StreamHandler(void *context, void *buf, std::uint32_t len)
|
||||
{
|
||||
PxMltDevice &obj = *static_cast<PxMltDevice*>(context);
|
||||
StreamContext &stream_ctx = obj.stream_ctx_;
|
||||
std::uint8_t *p = static_cast<std::uint8_t*>(buf);
|
||||
std::size_t remain = len;
|
||||
|
||||
if (stream_ctx.remain_len) {
|
||||
if ((stream_ctx.remain_len + len) >= PXMLT_DEVICE_TS_SYNC_SIZE) {
|
||||
std::uint8_t * remain_buf = stream_ctx.remain_buf;
|
||||
std::size_t t = PXMLT_DEVICE_TS_SYNC_SIZE - stream_ctx.remain_len;
|
||||
|
||||
memcpy(remain_buf + stream_ctx.remain_len, p, t);
|
||||
stream_ctx.remain_len = PXMLT_DEVICE_TS_SYNC_SIZE;
|
||||
|
||||
StreamProcess(stream_ctx.stream_buf, &remain_buf, stream_ctx.remain_len);
|
||||
if (!stream_ctx.remain_len) {
|
||||
p += t;
|
||||
remain -= t;
|
||||
}
|
||||
|
||||
stream_ctx.remain_len = 0;
|
||||
} else {
|
||||
memcpy(stream_ctx.remain_buf + stream_ctx.remain_len, p, len);
|
||||
stream_ctx.remain_len += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
StreamProcess(stream_ctx.stream_buf, &p, remain);
|
||||
|
||||
if (remain) {
|
||||
dev_dbg(&obj.dev_, "px4::PxMltDevice::StreamHandler: remain: %lu\n", remain);
|
||||
memcpy(stream_ctx.remain_buf, p, remain);
|
||||
stream_ctx.remain_len = remain;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const PxMltDevice::PxMltReceiver::PxMltReceiverCnTableIsdbS PxMltDevice::PxMltReceiver::isdbs_cn_table_[] = {
|
||||
{ 0x5af, 0 }, { 0x597, 100 }, { 0x57e, 200 }, { 0x567, 300 },
|
||||
{ 0x550, 400 }, { 0x539, 500 }, { 0x522, 600 }, { 0x50c, 700 },
|
||||
{ 0x4f6, 800 }, { 0x4e1, 900 }, { 0x4cc, 1000 }, { 0x4b6, 1100 },
|
||||
{ 0x4a1, 1200 }, { 0x48c, 1300 }, { 0x477, 1400 }, { 0x463, 1500 },
|
||||
{ 0x44f, 1600 }, { 0x43c, 1700 }, { 0x428, 1800 }, { 0x416, 1900 },
|
||||
{ 0x403, 2000 }, { 0x3ef, 2100 }, { 0x3dc, 2200 }, { 0x3c9, 2300 },
|
||||
{ 0x3b6, 2400 }, { 0x3a4, 2500 }, { 0x392, 2600 }, { 0x381, 2700 },
|
||||
{ 0x36f, 2800 }, { 0x35f, 2900 }, { 0x34e, 3000 }, { 0x33d, 3100 },
|
||||
{ 0x32d, 3200 }, { 0x31d, 3300 }, { 0x30d, 3400 }, { 0x2fd, 3500 },
|
||||
{ 0x2ee, 3600 }, { 0x2df, 3700 }, { 0x2d0, 3800 }, { 0x2c2, 3900 },
|
||||
{ 0x2b4, 4000 }, { 0x2a6, 4100 }, { 0x299, 4200 }, { 0x28c, 4300 },
|
||||
{ 0x27f, 4400 }, { 0x272, 4500 }, { 0x265, 4600 }, { 0x259, 4700 },
|
||||
{ 0x24d, 4800 }, { 0x241, 4900 }, { 0x236, 5000 }, { 0x22b, 5100 },
|
||||
{ 0x220, 5200 }, { 0x215, 5300 }, { 0x20a, 5400 }, { 0x200, 5500 },
|
||||
{ 0x1f6, 5600 }, { 0x1ec, 5700 }, { 0x1e2, 5800 }, { 0x1d8, 5900 },
|
||||
{ 0x1cf, 6000 }, { 0x1c6, 6100 }, { 0x1bc, 6200 }, { 0x1b3, 6300 },
|
||||
{ 0x1aa, 6400 }, { 0x1a2, 6500 }, { 0x199, 6600 }, { 0x191, 6700 },
|
||||
{ 0x189, 6800 }, { 0x181, 6900 }, { 0x179, 7000 }, { 0x171, 7100 },
|
||||
{ 0x169, 7200 }, { 0x161, 7300 }, { 0x15a, 7400 }, { 0x153, 7500 },
|
||||
{ 0x14b, 7600 }, { 0x144, 7700 }, { 0x13d, 7800 }, { 0x137, 7900 },
|
||||
{ 0x130, 8000 }, { 0x12a, 8100 }, { 0x124, 8200 }, { 0x11e, 8300 },
|
||||
{ 0x118, 8400 }, { 0x112, 8500 }, { 0x10c, 8600 }, { 0x107, 8700 },
|
||||
{ 0x101, 8800 }, { 0xfc, 8900 }, { 0xf7, 9000 }, { 0xf2, 9100 },
|
||||
{ 0xec, 9200 }, { 0xe7, 9300 }, { 0xe2, 9400 }, { 0xdd, 9500 },
|
||||
{ 0xd8, 9600 }, { 0xd4, 9700 }, { 0xcf, 9800 }, { 0xca, 9900 },
|
||||
{ 0xc6, 10000 }, { 0xc2, 10100 }, { 0xbe, 10200 }, { 0xb9, 10300 },
|
||||
{ 0xb5, 10400 }, { 0xb1, 10500 }, { 0xae, 10600 }, { 0xaa, 10700 },
|
||||
{ 0xa6, 10800 }, { 0xa3, 10900 }, { 0x9f, 11000 }, { 0x9b, 11100 },
|
||||
{ 0x98, 11200 }, { 0x95, 11300 }, { 0x91, 11400 }, { 0x8e, 11500 },
|
||||
{ 0x8b, 11600 }, { 0x88, 11700 }, { 0x85, 11800 }, { 0x82, 11900 },
|
||||
{ 0x7f, 12000 }, { 0x7c, 12100 }, { 0x7a, 12200 }, { 0x77, 12300 },
|
||||
{ 0x74, 12400 }, { 0x72, 12500 }, { 0x6f, 12600 }, { 0x6d, 12700 },
|
||||
{ 0x6b, 12800 }, { 0x68, 12900 }, { 0x66, 13000 }, { 0x64, 13100 },
|
||||
{ 0x61, 13200 }, { 0x5f, 13300 }, { 0x5d, 13400 }, { 0x5b, 13500 },
|
||||
{ 0x59, 13600 }, { 0x57, 13700 }, { 0x55, 13800 }, { 0x53, 13900 },
|
||||
{ 0x51, 14000 }, { 0x4f, 14100 }, { 0x4e, 14200 }, { 0x4c, 14300 },
|
||||
{ 0x4a, 14400 }, { 0x49, 14500 }, { 0x47, 14600 }, { 0x45, 14700 },
|
||||
{ 0x44, 14800 }, { 0x42, 14900 }, { 0x41, 15000 }, { 0x3f, 15100 },
|
||||
{ 0x3e, 15200 }, { 0x3c, 15300 }, { 0x3b, 15400 }, { 0x3a, 15500 },
|
||||
{ 0x38, 15600 }, { 0x37, 15700 }, { 0x36, 15800 }, { 0x34, 15900 },
|
||||
{ 0x33, 16000 }, { 0x32, 16100 }, { 0x31, 16200 }, { 0x30, 16300 },
|
||||
{ 0x2f, 16400 }, { 0x2e, 16500 }, { 0x2d, 16600 }, { 0x2c, 16700 },
|
||||
{ 0x2b, 16800 }, { 0x2a, 16900 }, { 0x29, 17000 }, { 0x28, 17100 },
|
||||
{ 0x27, 17200 }, { 0x26, 17300 }, { 0x25, 17400 }, { 0x24, 17500 },
|
||||
{ 0x23, 17600 }, { 0x22, 17800 }, { 0x21, 17900 }, { 0x20, 18000 },
|
||||
{ 0x1f, 18200 }, { 0x1e, 18300 }, { 0x1d, 18500 }, { 0x1c, 18700 },
|
||||
{ 0x1b, 18900 }, { 0x1a, 19000 }, { 0x19, 19200 }, { 0x18, 19300 },
|
||||
{ 0x17, 19500 }, { 0x16, 19700 }, { 0x15, 19900 }, { 0x14, 20000 }
|
||||
};
|
||||
|
||||
PxMltDevice::PxMltReceiver::PxMltReceiver(PxMltDevice &parent, std::uintptr_t index)
|
||||
: parent_(parent),
|
||||
index_(index),
|
||||
lock_(),
|
||||
open_(false),
|
||||
close_cond_(),
|
||||
lnb_power_(false),
|
||||
current_system_(px4::SystemType::UNSPECIFIED),
|
||||
streaming_(false)
|
||||
{
|
||||
auto i2c_addr = parent_.params_[static_cast<int>(parent_.model_)][index_].i2c_addr;
|
||||
auto i2c_bus = parent_.params_[static_cast<int>(parent_.model_)][index_].i2c_bus;
|
||||
|
||||
tuner_lock_ = &parent_.tuner_lock_[(i2c_bus == 3) ? 0 : 1];
|
||||
|
||||
const device *dev = &parent_.GetDevice();
|
||||
const i2c_comm_master *i2c = &parent_.GetI2cMaster(i2c_bus);
|
||||
|
||||
cxd2856er_.dev = dev;
|
||||
cxd2856er_.i2c = i2c;
|
||||
cxd2856er_.i2c_addr.slvx = i2c_addr + 2;
|
||||
cxd2856er_.i2c_addr.slvt = i2c_addr;
|
||||
cxd2856er_.config.xtal = 24000;
|
||||
cxd2856er_.config.tuner_i2c = true;
|
||||
|
||||
cxd2858er_.dev = dev;
|
||||
cxd2858er_.i2c = &cxd2856er_.i2c_master;
|
||||
cxd2858er_.i2c_addr = 0x60;
|
||||
cxd2858er_.config.xtal = 16000;
|
||||
cxd2858er_.config.ter.lna = true;
|
||||
cxd2858er_.config.sat.lna = true;
|
||||
}
|
||||
|
||||
PxMltDevice::PxMltReceiver::~PxMltReceiver()
|
||||
{
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::~PxMltReceiver(%u)\n", index_);
|
||||
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
|
||||
close_cond_.wait(lock, [this] { return !open_; });
|
||||
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::~PxMltReceiver(%u): exit\n", index_);
|
||||
}
|
||||
|
||||
int PxMltDevice::PxMltReceiver::Open()
|
||||
{
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Open(%u): open_: %s\n", index_, (open_) ? "true" : "false");
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
std::lock_guard<std::recursive_mutex> dev_lock(parent_.lock_);
|
||||
|
||||
if (open_)
|
||||
return -EALREADY;
|
||||
|
||||
if (!parent_.open_count_) {
|
||||
ret = parent_.SetBackendPower(true);
|
||||
if (ret) {
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Open(%u): SetBackendPower(true) failed. (ret: %d)\n", index_, ret);
|
||||
goto fail_power;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cxd2856er_init(&cxd2856er_);
|
||||
if (ret) {
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Open(%u): cxd2856er_init() failed. (ret: %d)\n", index_, ret);
|
||||
goto fail_demod_init;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> tuner_lock(*tuner_lock_);
|
||||
|
||||
ret = cxd2858er_init(&cxd2858er_);
|
||||
if (ret) {
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Open(%u): cxd2858er_init() failed. (ret: %d)\n", index_, ret);
|
||||
goto fail_tuner_init;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cxd2856er_write_slvt_reg(&cxd2856er_, 0x00, 0x00);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0xc4, 0x80, 0x88);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0xc5, 0x01, 0x01);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0xc6, 0x03, 0x1f);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg(&cxd2856er_, 0x00, 0x60);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0x52, 0x03, 0x1f);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg(&cxd2856er_, 0x00, 0x00);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0xc8, 0x03, 0x1f);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0xc9, 0x03, 0x1f);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg(&cxd2856er_, 0x00, 0xa0);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
ret = cxd2856er_write_slvt_reg_mask(&cxd2856er_, 0xb9, 0x01, 0x01);
|
||||
if (ret)
|
||||
goto fail_backend;
|
||||
|
||||
current_system_ = px4::SystemType::UNSPECIFIED;
|
||||
|
||||
parent_.open_count_++;
|
||||
open_ = true;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_backend:
|
||||
{
|
||||
std::lock_guard<std::mutex> tuner_lock(*tuner_lock_);
|
||||
cxd2858er_term(&cxd2858er_);
|
||||
}
|
||||
|
||||
fail_tuner_init:
|
||||
cxd2856er_term(&cxd2856er_);
|
||||
|
||||
fail_demod_init:
|
||||
if (!parent_.open_count_)
|
||||
parent_.SetBackendPower(true);
|
||||
|
||||
fail_power:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PxMltDevice::PxMltReceiver::Close()
|
||||
{
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Close(%u): open_: %s\n", index_, (open_) ? "true" : "false");
|
||||
|
||||
if (!open_)
|
||||
return;
|
||||
|
||||
SetCapture(false);
|
||||
SetLnbVoltage(0);
|
||||
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
std::lock_guard<std::recursive_mutex> dev_lock(parent_.lock_);
|
||||
|
||||
assert(parent_.open_count_ > 0);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> tuner_lock(*tuner_lock_);
|
||||
cxd2858er_term(&cxd2858er_);
|
||||
}
|
||||
|
||||
cxd2856er_term(&cxd2856er_);
|
||||
|
||||
parent_.open_count_--;
|
||||
if (!parent_.open_count_)
|
||||
parent_.SetBackendPower(false);
|
||||
|
||||
open_ = false;
|
||||
|
||||
lock.unlock();
|
||||
close_cond_.notify_all();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int PxMltDevice::PxMltReceiver::Tune()
|
||||
{
|
||||
if (!open_)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): freq: %u\n", index_, params_.freq);
|
||||
|
||||
int ret = 0;
|
||||
cxd2856er_system_params demod_params = { 0 };
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
|
||||
current_system_ = px4::SystemType::UNSPECIFIED;
|
||||
|
||||
switch (params_.system) {
|
||||
case px4::SystemType::ISDB_T:
|
||||
demod_params.bandwidth = (params_.bandwidth) ? params_.bandwidth : 6;
|
||||
|
||||
ret = cxd2856er_wakeup(&cxd2856er_, CXD2856ER_ISDB_T_SYSTEM, &demod_params);
|
||||
if (ret)
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2856er_wakeup(CXD2856ER_ISDB_T_SYSTEM) failed. (ret: %d)\n", index_, ret);
|
||||
|
||||
break;
|
||||
|
||||
case px4::SystemType::ISDB_S:
|
||||
if (params_.stream_id < 12) {
|
||||
ret = cxd2856er_set_slot_isdbs(&cxd2856er_, params_.stream_id);
|
||||
if (ret) {
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2856er_set_slot_isdbs(%u) failed. (ret: %d)\n", index_, params_.stream_id, ret);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = cxd2856er_set_tsid_isdbs(&cxd2856er_, params_.stream_id);
|
||||
if (ret) {
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2856er_set_tsid_isdbs(%u) failed. (ret: %d)\n", index_, params_.stream_id, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cxd2856er_wakeup(&cxd2856er_, CXD2856ER_ISDB_S_SYSTEM, &demod_params);
|
||||
if (ret)
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2856er_wakeup(CXD2856ER_ISDB_S_SYSTEM) failed. (ret: %d)\n", index_, ret);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> tuner_lock(*tuner_lock_);
|
||||
|
||||
switch (params_.system) {
|
||||
case px4::SystemType::ISDB_T:
|
||||
ret = cxd2858er_set_params_t(&cxd2858er_, CXD2858ER_ISDB_T_SYSTEM, params_.freq, 6);
|
||||
if (ret)
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2858er_set_params_t(%u, 6) failed. (ret: %d)\n");
|
||||
|
||||
break;
|
||||
|
||||
case px4::SystemType::ISDB_S:
|
||||
ret = cxd2858er_set_params_s(&cxd2858er_, CXD2858ER_ISDB_S_SYSTEM, params_.freq, 28860);
|
||||
if (ret)
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2858er_set_params_s(%u, 28860) failed. (ret: %d)\n");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2856er_post_tune(&cxd2856er_);
|
||||
if (ret)
|
||||
dev_err(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::Tune(%u): cxd2856er_post_tune() failed. (ret: %d)\n");
|
||||
else
|
||||
current_system_ = params_.system;
|
||||
|
||||
int i = 300;
|
||||
while (i--) {
|
||||
bool locked = false, unlocked = false;
|
||||
|
||||
switch (current_system_) {
|
||||
case px4::SystemType::ISDB_T:
|
||||
ret = cxd2856er_is_ts_locked_isdbt(&cxd2856er_, &locked, &unlocked);
|
||||
if (!ret && unlocked)
|
||||
ret = -ECANCELED;
|
||||
|
||||
break;
|
||||
|
||||
case px4::SystemType::ISDB_S:
|
||||
ret = cxd2856er_is_ts_locked_isdbs(&cxd2856er_, &locked);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (locked || ret)
|
||||
break;
|
||||
|
||||
lock_.unlock();
|
||||
msleep(10);
|
||||
lock_.lock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PxMltDevice::PxMltReceiver::CheckLock(bool &locked)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int PxMltDevice::PxMltReceiver::SetLnbVoltage(std::int32_t voltage)
|
||||
{
|
||||
if (!open_)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::SetLnbVoltage(%u): voltage: %d\n", index_, voltage);
|
||||
|
||||
if (voltage != 0 && voltage != 15)
|
||||
return -EINVAL;
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
if (lnb_power_ == !!voltage)
|
||||
return 0;
|
||||
|
||||
ret = parent_.SetLnbVoltage(voltage);
|
||||
if (!ret || !voltage)
|
||||
lnb_power_ = !!voltage;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PxMltDevice::PxMltReceiver::SetCapture(bool capture)
|
||||
{
|
||||
if (!open_)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(&parent_.dev_, "px4::PxMltDevice::PxMltReceiver::SetCapture(%u): capture: %s\n", index_, (capture) ? "true" : "false");
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
if ((capture && streaming_) || (!capture && !streaming_))
|
||||
return -EALREADY;
|
||||
|
||||
if (capture)
|
||||
ret = parent_.StartCapture();
|
||||
else
|
||||
ret = parent_.StopCapture();
|
||||
|
||||
if (!ret) {
|
||||
if (capture) {
|
||||
std::size_t size = 188 * parent_.config_.device.receiver_max_packets;
|
||||
|
||||
stream_buf_->Alloc(size);
|
||||
stream_buf_->SetThresholdSize(size / 10);
|
||||
stream_buf_->Start();
|
||||
} else {
|
||||
stream_buf_->Stop();
|
||||
}
|
||||
streaming_ = capture;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PxMltDevice::PxMltReceiver::ReadStat(px4::command::StatType type, std::int32_t &value)
|
||||
{
|
||||
if (!open_)
|
||||
return -EINVAL;
|
||||
|
||||
int ret = 0;
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
value = 0;
|
||||
|
||||
switch (type) {
|
||||
case px4::command::StatType::SIGNAL_STRENGTH:
|
||||
// not implemented
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
|
||||
case px4::command::StatType::CNR:
|
||||
switch (current_system_) {
|
||||
case px4::SystemType::ISDB_T:
|
||||
{
|
||||
std::uint16_t val;
|
||||
|
||||
ret = cxd2856er_read_cnr_raw_isdbt(&cxd2856er_, &val);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
value = static_cast<std::int32_t>((std::log10(val) * 10000) - 9031);
|
||||
break;
|
||||
}
|
||||
|
||||
case px4::SystemType::ISDB_S:
|
||||
{
|
||||
int i, i_min, i_max;
|
||||
std::uint16_t val;
|
||||
|
||||
ret = cxd2856er_read_cnr_raw_isdbs(&cxd2856er_, &val);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
i_min = 0;
|
||||
i_max = (sizeof(isdbs_cn_table_) / sizeof(isdbs_cn_table_[0])) - 1;
|
||||
|
||||
if (isdbs_cn_table_[i_min].val <= val) {
|
||||
value = isdbs_cn_table_[i_min].cnr;
|
||||
break;
|
||||
}
|
||||
if (isdbs_cn_table_[i_max].val >= val) {
|
||||
value = isdbs_cn_table_[i_max].cnr;
|
||||
break;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
i = i_min + (i_max - i_min) / 2;
|
||||
|
||||
if (isdbs_cn_table_[i].val == val) {
|
||||
value = isdbs_cn_table_[i].cnr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isdbs_cn_table_[i].val > val)
|
||||
i_min = i + 1;
|
||||
else
|
||||
i_max = i - 1;
|
||||
|
||||
if (i_max < i_min) {
|
||||
value = isdbs_cn_table_[i_max].cnr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace px4
|
157
winusb/src/DriverHost_PX4/pxmlt_device.hpp
Normal file
157
winusb/src/DriverHost_PX4/pxmlt_device.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
// pxmlt_device.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "device_definition_set.hpp"
|
||||
#include "device_base.hpp"
|
||||
#include "receiver_base.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
#include "ringbuffer.hpp"
|
||||
|
||||
#include "winusb_compat.h"
|
||||
|
||||
#include "i2c_comm.h"
|
||||
#include "it930x.h"
|
||||
#include "itedtv_bus.h"
|
||||
#include "cxd2856er.h"
|
||||
#include "cxd2858er.h"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
#define PXMLT_DEVICE_TS_SYNC_COUNT 4
|
||||
#define PXMLT_DEVICE_TS_SYNC_SIZE (188 * PXMLT_DEVICE_TS_SYNC_COUNT)
|
||||
|
||||
enum class PxMltDeviceModel {
|
||||
PXMLT5U = 0,
|
||||
PXMLT5PE,
|
||||
PXMLT8PE3,
|
||||
PXMLT8PE5,
|
||||
ISDB6014_4TS
|
||||
};
|
||||
|
||||
struct PxMltDeviceConfig final {
|
||||
PxMltDeviceConfig()
|
||||
: usb{ 816, 816, 5, false },
|
||||
device{ 2048, 2000, true }
|
||||
{}
|
||||
struct {
|
||||
unsigned int xfer_packets;
|
||||
unsigned int urb_max_packets;
|
||||
unsigned int max_urbs;
|
||||
bool no_raw_io;
|
||||
} usb;
|
||||
struct {
|
||||
unsigned int receiver_max_packets;
|
||||
int psb_purge_timeout;
|
||||
bool discard_null_packets;
|
||||
} device;
|
||||
};
|
||||
|
||||
class PxMltDevice final : public px4::DeviceBase {
|
||||
public:
|
||||
PxMltDevice() = delete;
|
||||
PxMltDevice(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager);
|
||||
~PxMltDevice();
|
||||
|
||||
// cannot copy
|
||||
PxMltDevice(const PxMltDevice &) = delete;
|
||||
PxMltDevice& operator=(const PxMltDevice &) = delete;
|
||||
|
||||
// cannot move
|
||||
PxMltDevice(PxMltDevice &&) = delete;
|
||||
PxMltDevice& operator=(PxMltDevice &&) = delete;
|
||||
|
||||
int Init() override;
|
||||
void Term() override;
|
||||
void SetAvailability(bool available) override;
|
||||
px4::ReceiverBase* GetReceiver(int id) const override;
|
||||
|
||||
private:
|
||||
struct StreamContext final {
|
||||
std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf[5];
|
||||
std::uint8_t remain_buf[PXMLT_DEVICE_TS_SYNC_SIZE];
|
||||
std::size_t remain_len;
|
||||
};
|
||||
|
||||
class PxMltReceiver final : public px4::ReceiverBase {
|
||||
public:
|
||||
PxMltReceiver() = delete;
|
||||
PxMltReceiver(PxMltDevice &parent, std::uintptr_t index);
|
||||
~PxMltReceiver();
|
||||
|
||||
// cannot copy
|
||||
PxMltReceiver(const PxMltReceiver &) = delete;
|
||||
PxMltReceiver& operator=(const PxMltReceiver &) = delete;
|
||||
|
||||
// cannot move
|
||||
PxMltReceiver(PxMltReceiver &&) = delete;
|
||||
PxMltReceiver& operator=(PxMltReceiver &&) = delete;
|
||||
|
||||
int Open() override;
|
||||
void Close() override;
|
||||
int Tune() override;
|
||||
int CheckLock(bool &locked) override;
|
||||
int SetLnbVoltage(std::int32_t voltage) override;
|
||||
int SetCapture(bool capture) override;
|
||||
int ReadStat(px4::command::StatType type, std::int32_t &value) override;
|
||||
|
||||
private:
|
||||
static const struct PxMltReceiverCnTableIsdbS final {
|
||||
uint16_t val;
|
||||
uint32_t cnr;
|
||||
} isdbs_cn_table_[];
|
||||
|
||||
PxMltDevice &parent_;
|
||||
std::uintptr_t index_;
|
||||
|
||||
std::mutex lock_;
|
||||
std::atomic_bool open_;
|
||||
std::condition_variable close_cond_;
|
||||
bool lnb_power_;
|
||||
std::mutex *tuner_lock_;
|
||||
cxd2856er_demod cxd2856er_;
|
||||
cxd2858er_tuner cxd2858er_;
|
||||
px4::SystemType current_system_;
|
||||
bool streaming_;
|
||||
};
|
||||
|
||||
const i2c_comm_master& GetI2cMaster(int bus) const;
|
||||
|
||||
int SetBackendPower(bool state);
|
||||
int SetLnbVoltage(std::int32_t voltage);
|
||||
|
||||
int StartCapture();
|
||||
int StopCapture();
|
||||
|
||||
static void StreamProcess(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf[], std::uint8_t **buf, std::size_t &len);
|
||||
static int StreamHandler(void *context, void *buf, std::uint32_t len);
|
||||
|
||||
static const struct PxMltDeviceParam final {
|
||||
std::uint8_t i2c_addr;
|
||||
std::uint8_t i2c_bus;
|
||||
std::uint8_t port_number;
|
||||
} params_[][5];
|
||||
|
||||
PxMltDeviceModel model_;
|
||||
PxMltDeviceConfig config_;
|
||||
std::recursive_mutex lock_;
|
||||
std::atomic_bool available_;
|
||||
std::atomic_bool init_;
|
||||
unsigned int open_count_;
|
||||
unsigned int lnb_power_count_;
|
||||
unsigned int streaming_count_;
|
||||
std::mutex tuner_lock_[2];
|
||||
int receiver_num_;
|
||||
std::unique_ptr<PxMltReceiver> receivers_[5];
|
||||
it930x_bridge it930x_;
|
||||
StreamContext stream_ctx_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
182
winusb/src/DriverHost_PX4/receiver_base.cpp
Normal file
182
winusb/src/DriverHost_PX4/receiver_base.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
// receiver_base.cpp
|
||||
|
||||
#include "receiver_base.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
ReceiverBase::ReceiverBase()
|
||||
{
|
||||
memset(¶ms_, 0, sizeof(params_));
|
||||
stream_buf_.reset(new StreamBuffer());
|
||||
}
|
||||
|
||||
ReceiverBase::~ReceiverBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ReceiverBase::GetParameters(px4::command::ParameterSet ¶m_set) noexcept
|
||||
{
|
||||
param_set.system = params_.system;
|
||||
param_set.freq = params_.freq;
|
||||
|
||||
for (std::uint32_t i = 0; i < param_set.num; i++) {
|
||||
switch (param_set.params[i].type) {
|
||||
case px4::command::ParameterType::BANDWIDTH:
|
||||
param_set.params[i].value = params_.bandwidth;
|
||||
break;
|
||||
|
||||
case px4::command::ParameterType::STREAM_ID:
|
||||
param_set.params[i].value = params_.stream_id;
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown parameter type
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReceiverBase::SetParameters(const px4::command::ParameterSet ¶m_set) noexcept
|
||||
{
|
||||
params_.system = param_set.system;
|
||||
params_.freq = param_set.freq;
|
||||
|
||||
for (std::uint32_t i = 0; i < param_set.num; i++) {
|
||||
switch (param_set.params[i].type) {
|
||||
case px4::command::ParameterType::BANDWIDTH:
|
||||
params_.bandwidth = param_set.params[i].value;
|
||||
break;
|
||||
|
||||
case px4::command::ParameterType::STREAM_ID:
|
||||
params_.stream_id = param_set.params[i].value;
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown parameter type
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReceiverBase::ClearParameters() noexcept
|
||||
{
|
||||
memset(¶ms_, 0, sizeof(params_));
|
||||
}
|
||||
|
||||
bool ReceiverBase::ReadStats(px4::command::StatSet &stat_set)
|
||||
{
|
||||
for (std::uint32_t i = 0; i < stat_set.num; i++) {
|
||||
if (ReadStat(stat_set.data[i].type, stat_set.data[i].value))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ReceiverBase::StreamBuffer::StreamBuffer()
|
||||
: write_size_(0),
|
||||
threshold_size_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ReceiverBase::StreamBuffer::~StreamBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ReceiverBase::StreamBuffer::SetThresholdSize(std::size_t size) noexcept
|
||||
{
|
||||
threshold_size_ = size;
|
||||
}
|
||||
|
||||
bool ReceiverBase::StreamBuffer::Alloc(std::size_t size)
|
||||
{
|
||||
return ringbuf_.Alloc(size);
|
||||
}
|
||||
|
||||
void ReceiverBase::StreamBuffer::Start() noexcept
|
||||
{
|
||||
stop_ = false;
|
||||
write_size_ = 0;
|
||||
|
||||
ringbuf_.Start();
|
||||
return;
|
||||
}
|
||||
|
||||
void ReceiverBase::StreamBuffer::Stop() noexcept
|
||||
{
|
||||
ringbuf_.Stop();
|
||||
|
||||
stop_ = true;
|
||||
cond_.notify_all();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ReceiverBase::StreamBuffer::StopRequest() noexcept
|
||||
{
|
||||
stop_ = true;
|
||||
cond_.notify_all();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool ReceiverBase::StreamBuffer::Write(const void *buf, std::size_t &size) noexcept
|
||||
{
|
||||
bool ret;
|
||||
|
||||
ret = ringbuf_.Write(buf, size);
|
||||
write_size_ += size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ReceiverBase::StreamBuffer::NotifyWrite() noexcept
|
||||
{
|
||||
if (write_size_ >= threshold_size_) {
|
||||
cond_.notify_all();
|
||||
write_size_ -= threshold_size_;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void ReceiverBase::StreamBuffer::HandleRead(std::size_t buf_size, std::function<bool(const void *buf, std::size_t size)> handler)
|
||||
{
|
||||
stop_ = false;
|
||||
|
||||
std::unique_ptr<std::uint8_t[]> buf(new std::uint8_t[buf_size]);
|
||||
std::uint8_t *p = buf.get();
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
|
||||
while (!ringbuf_.IsActive() && !stop_)
|
||||
cond_.wait(lock);
|
||||
|
||||
while (true) {
|
||||
while (!ringbuf_.GetReadableSize() && !stop_)
|
||||
cond_.wait(lock);
|
||||
|
||||
if (stop_)
|
||||
break;
|
||||
|
||||
std::size_t size = buf_size;
|
||||
|
||||
if (!ringbuf_.Read(p, size))
|
||||
break;
|
||||
|
||||
if (!size)
|
||||
continue;
|
||||
|
||||
if (!handler(p, size))
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace px4
|
86
winusb/src/DriverHost_PX4/receiver_base.hpp
Normal file
86
winusb/src/DriverHost_PX4/receiver_base.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// receiver_base.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "type.hpp"
|
||||
#include "command.hpp"
|
||||
#include "ringbuffer.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class ReceiverBase {
|
||||
public:
|
||||
struct Parameters {
|
||||
px4::SystemType system;
|
||||
std::uint32_t freq;
|
||||
std::uint32_t bandwidth;
|
||||
std::uint32_t stream_id;
|
||||
};
|
||||
|
||||
class StreamBuffer final {
|
||||
public:
|
||||
StreamBuffer();
|
||||
~StreamBuffer();
|
||||
|
||||
void SetThresholdSize(std::size_t size) noexcept;
|
||||
bool Alloc(std::size_t size);
|
||||
void Start() noexcept;
|
||||
void Stop() noexcept;
|
||||
void StopRequest() noexcept;
|
||||
bool Write(const void *buf, std::size_t &size) noexcept;
|
||||
void NotifyWrite() noexcept;
|
||||
void HandleRead(std::size_t buf_size, std::function<bool(const void *buf, std::size_t size)> handler);
|
||||
|
||||
private:
|
||||
std::mutex mtx_;
|
||||
px4::RingBuffer ringbuf_;
|
||||
std::atomic_bool stop_;
|
||||
std::condition_variable cond_;
|
||||
std::size_t write_size_;
|
||||
std::size_t threshold_size_;
|
||||
};
|
||||
|
||||
ReceiverBase();
|
||||
virtual ~ReceiverBase();
|
||||
|
||||
// cannot copy
|
||||
ReceiverBase(const ReceiverBase &) = delete;
|
||||
ReceiverBase& operator=(const ReceiverBase &) = delete;
|
||||
|
||||
// cannot move
|
||||
ReceiverBase(ReceiverBase &&) = delete;
|
||||
ReceiverBase& operator=(ReceiverBase &&) = delete;
|
||||
|
||||
bool GetParameters(px4::command::ParameterSet ¶m_set) noexcept;
|
||||
bool SetParameters(const px4::command::ParameterSet ¶m_set) noexcept;
|
||||
void ClearParameters() noexcept;
|
||||
bool ReadStats(px4::command::StatSet &stat_set);
|
||||
std::shared_ptr<StreamBuffer> GetStreamBuffer() noexcept { return stream_buf_; }
|
||||
|
||||
virtual int Open() = 0;
|
||||
virtual void Close() = 0;
|
||||
virtual int Tune() = 0;
|
||||
virtual int CheckLock(bool &locked) = 0;
|
||||
virtual int SetLnbVoltage(std::int32_t voltage) = 0;
|
||||
virtual int SetCapture(bool capture) = 0;
|
||||
virtual int ReadStat(px4::command::StatType type, std::int32_t &value) = 0;
|
||||
|
||||
protected:
|
||||
Parameters params_;
|
||||
std::shared_ptr<StreamBuffer> stream_buf_;
|
||||
};
|
||||
|
||||
class ReceiverError : public std::runtime_error {
|
||||
public:
|
||||
explicit ReceiverError(const std::string &what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
133
winusb/src/DriverHost_PX4/receiver_manager.cpp
Normal file
133
winusb/src/DriverHost_PX4/receiver_manager.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
// receiver_manager.cpp
|
||||
|
||||
#include "receiver_manager.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
bool ReceiverManager::Register(px4::command::ReceiverInfo &info, px4::ReceiverBase *receiver)
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock(mtx_);
|
||||
|
||||
if (data_.count(receiver))
|
||||
return false;
|
||||
|
||||
data_.emplace(receiver, ReceiverData{ info, false });
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReceiverManager::Unregister(px4::ReceiverBase *receiver)
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock(mtx_);
|
||||
|
||||
if (!data_.count(receiver))
|
||||
return false;
|
||||
|
||||
data_.erase(receiver);
|
||||
return true;
|
||||
}
|
||||
|
||||
static GUID empty_guid = { 0 };
|
||||
|
||||
px4::ReceiverBase* ReceiverManager::Search(px4::command::ReceiverInfo &key, px4::command::ReceiverInfo &info)
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
for (auto it = data_.cbegin(); it != data_.cend(); ++it) {
|
||||
const px4::command::ReceiverInfo& k = it->second.info;
|
||||
|
||||
if (k.data_id)
|
||||
continue;
|
||||
|
||||
if (key.device_name[0] && wcscmp(key.device_name, k.device_name))
|
||||
continue;
|
||||
|
||||
if (memcmp(&key.device_guid, &empty_guid, sizeof(key.device_guid) && memcmp(&key.device_guid, &k.device_guid, sizeof(key.device_guid))))
|
||||
continue;
|
||||
|
||||
if (key.receiver_name[0] && wcscmp(key.receiver_name, k.receiver_name))
|
||||
continue;
|
||||
|
||||
if (memcmp(&key.receiver_guid, &empty_guid, sizeof(key.receiver_guid) && memcmp(&key.receiver_guid, &k.receiver_guid, sizeof(key.receiver_guid))))
|
||||
continue;
|
||||
|
||||
if ((key.systems & k.systems) != key.systems)
|
||||
continue;
|
||||
|
||||
if ((key.index >= 0) && (key.index != k.index))
|
||||
continue;
|
||||
|
||||
info = k;
|
||||
|
||||
return it->first;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
px4::ReceiverBase* ReceiverManager::SearchByDataId(std::uint32_t data_id)
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(mtx_);
|
||||
|
||||
for (auto it = data_.begin(); it != data_.end(); ++it) {
|
||||
if (it->second.info.data_id != data_id || !it->second.valid_data_id)
|
||||
continue;
|
||||
|
||||
it->second.valid_data_id = false;
|
||||
return it->first;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ReceiverManager::GenerateDataId(px4::ReceiverBase *receiver, std::uint32_t &data_id)
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock(mtx_);
|
||||
|
||||
if (!data_.count(receiver))
|
||||
return false;
|
||||
|
||||
auto& v = data_.at(receiver);
|
||||
|
||||
if (v.info.data_id)
|
||||
return false;
|
||||
|
||||
while (true) {
|
||||
std::uint32_t tmp = std::random_device()();
|
||||
|
||||
if (!tmp)
|
||||
continue;
|
||||
|
||||
auto it = data_.cbegin();
|
||||
for (; it != data_.cend(); ++it) {
|
||||
if (it->second.info.data_id == tmp)
|
||||
break;
|
||||
}
|
||||
|
||||
if (it == data_.cend()) {
|
||||
v.info.data_id = data_id = tmp;
|
||||
v.valid_data_id = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReceiverManager::ClearDataId(px4::ReceiverBase *receiver)
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock(mtx_);
|
||||
|
||||
if (!data_.count(receiver))
|
||||
return;
|
||||
|
||||
auto& data = data_.at(receiver);
|
||||
|
||||
data.info.data_id = 0;
|
||||
data.valid_data_id = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace px4
|
43
winusb/src/DriverHost_PX4/receiver_manager.hpp
Normal file
43
winusb/src/DriverHost_PX4/receiver_manager.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// receiver_manager.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "command.hpp"
|
||||
#include "receiver_base.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class ReceiverManager final {
|
||||
public:
|
||||
ReceiverManager() {};
|
||||
~ReceiverManager() {};
|
||||
|
||||
// cannot copy
|
||||
ReceiverManager(const ReceiverManager &) = delete;
|
||||
ReceiverManager& operator=(const ReceiverManager &) = delete;
|
||||
|
||||
// cannot move
|
||||
ReceiverManager(ReceiverManager &&) = delete;
|
||||
ReceiverManager& operator=(ReceiverManager &&) = delete;
|
||||
|
||||
bool Register(px4::command::ReceiverInfo &info, px4::ReceiverBase *receiver);
|
||||
bool Unregister(px4::ReceiverBase *receiver);
|
||||
px4::ReceiverBase* Search(px4::command::ReceiverInfo &key, px4::command::ReceiverInfo &info);
|
||||
px4::ReceiverBase* SearchByDataId(std::uint32_t data_id);
|
||||
bool GenerateDataId(px4::ReceiverBase *receiver, std::uint32_t &data_id);
|
||||
void ClearDataId(px4::ReceiverBase *receiver);
|
||||
|
||||
private:
|
||||
struct ReceiverData {
|
||||
px4::command::ReceiverInfo info;
|
||||
bool valid_data_id;
|
||||
};
|
||||
|
||||
std::shared_mutex mtx_;
|
||||
std::unordered_map<px4::ReceiverBase*, ReceiverData> data_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
30
winusb/src/DriverHost_PX4/resource.h
Normal file
30
winusb/src/DriverHost_PX4/resource.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// resource.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VER_FILE 0,4,0,0
|
||||
#define VER_FILE_STR "0.4.0"
|
||||
|
||||
#define VER_PRODUCT 0,4,0,0
|
||||
#define VER_PRODUCT_STR "0.4.0"
|
||||
|
||||
#define VER_COMMENTS_STR ""
|
||||
#define VER_COMPANYNAME_STR "nns779"
|
||||
#define VER_FILEDESCRIPTION_STR "PX4 Device Driver (WinUSB)"
|
||||
#define VER_INTERNALNAME_STR "DriverHost_PX4.exe"
|
||||
#define VER_LEGALCOPYRIGHT_STR ""
|
||||
#define VER_LEGALTRADEMARKS_STR ""
|
||||
#define VER_ORIGINALFILENAME_STR VER_INTERNALNAME_STR
|
||||
#define VER_PRIVATEBUILD_STR ""
|
||||
#define VER_PRODUCTNAME_STR "DriverHost_PX4"
|
||||
#define VER_SPECIALBUILD_STR ""
|
||||
|
||||
#if defined(_DEBUG)
|
||||
#define VER_FLAGS VS_FF_PRERELEASE | VS_FF_DEBUG
|
||||
#elif defined(_DEBUG_MSG)
|
||||
#define VER_FLAGS VS_FF_PRERELEASE
|
||||
#else
|
||||
#define VER_FLAGS 0
|
||||
#endif
|
143
winusb/src/DriverHost_PX4/ringbuffer.cpp
Normal file
143
winusb/src/DriverHost_PX4/ringbuffer.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
// ringbuffer.cpp
|
||||
|
||||
#include "ringbuffer.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
RingBuffer::RingBuffer(std::size_t size)
|
||||
: state_(0),
|
||||
buf_(nullptr),
|
||||
actual_size_(0),
|
||||
head_(0),
|
||||
tail_(0)
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
RingBuffer::~RingBuffer()
|
||||
{
|
||||
Stop();
|
||||
|
||||
if (buf_)
|
||||
VirtualFree(buf_, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
bool RingBuffer::Alloc(std::size_t size)
|
||||
{
|
||||
if (state_)
|
||||
return false;
|
||||
|
||||
if (buf_ && buf_size_ != size) {
|
||||
VirtualFree(buf_, 0, MEM_RELEASE);
|
||||
buf_ = nullptr;
|
||||
buf_size_ = 0;
|
||||
}
|
||||
|
||||
if (!buf_ && size) {
|
||||
buf_ = reinterpret_cast<std::uint8_t*>(VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
|
||||
if (!buf_)
|
||||
return false;
|
||||
|
||||
buf_size_ = size;
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RingBuffer::Reset() noexcept
|
||||
{
|
||||
actual_size_ = 0;
|
||||
head_ = 0;
|
||||
tail_ = 0;
|
||||
}
|
||||
|
||||
void RingBuffer::Start() noexcept
|
||||
{
|
||||
int expected = 0;
|
||||
|
||||
state_.compare_exchange_strong(expected, 1);
|
||||
}
|
||||
|
||||
void RingBuffer::Stop() noexcept
|
||||
{
|
||||
state_ = 0;
|
||||
}
|
||||
|
||||
bool RingBuffer::Read(void *buf, std::size_t &size) noexcept
|
||||
{
|
||||
#if 0
|
||||
int expected_state = 1;
|
||||
|
||||
state_.compare_exchange_strong(expected_state, 2);
|
||||
#endif
|
||||
|
||||
std::size_t actual_size = actual_size_;
|
||||
std::intptr_t head = head_;
|
||||
std::size_t buf_size = buf_size_;
|
||||
std::size_t read_size = (size <= actual_size) ? size : actual_size;
|
||||
|
||||
if (read_size) {
|
||||
std::size_t tmp = (head + read_size <= buf_size) ? read_size : (buf_size - head);
|
||||
|
||||
memcpy(buf, buf_ + head, tmp);
|
||||
|
||||
if (tmp < read_size) {
|
||||
memcpy(reinterpret_cast<std::uint8_t *>(buf) + tmp, buf_, read_size - tmp);
|
||||
head = read_size - tmp;
|
||||
} else {
|
||||
head = (head + read_size == buf_size) ? 0 : (head + read_size);
|
||||
}
|
||||
|
||||
head_ = head;
|
||||
actual_size_ -= read_size;
|
||||
}
|
||||
|
||||
size = read_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RingBuffer::Write(const void *buf, std::size_t &size) noexcept
|
||||
{
|
||||
#if 0
|
||||
if (state_ != 2)
|
||||
return false;
|
||||
#else
|
||||
if (!state_)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
std::size_t actual_size = actual_size_;
|
||||
std::intptr_t tail = tail_;
|
||||
std::size_t buf_size = buf_size_;
|
||||
std::size_t write_size = (actual_size + size <= buf_size) ? size : (buf_size - actual_size);
|
||||
|
||||
if (write_size) {
|
||||
std::size_t tmp = (tail + write_size <= buf_size) ? write_size : (buf_size - tail);
|
||||
|
||||
std::memcpy(buf_ + tail, buf, tmp);
|
||||
|
||||
if (tmp < write_size) {
|
||||
std::memcpy(buf_, reinterpret_cast<const std::uint8_t *>(buf) + tmp, write_size - tmp);
|
||||
tail = write_size - tmp;
|
||||
} else {
|
||||
tail = (tail + write_size == buf_size) ? 0 : (tail + write_size);
|
||||
}
|
||||
|
||||
tail_ = tail;
|
||||
actual_size_ += write_size;
|
||||
}
|
||||
|
||||
bool ret = (size == write_size);
|
||||
|
||||
size = write_size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace px4
|
36
winusb/src/DriverHost_PX4/ringbuffer.hpp
Normal file
36
winusb/src/DriverHost_PX4/ringbuffer.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// ringbuffer.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class RingBuffer final {
|
||||
public:
|
||||
explicit RingBuffer() : RingBuffer(0) {}
|
||||
explicit RingBuffer(std::size_t size);
|
||||
~RingBuffer();
|
||||
|
||||
bool Alloc(std::size_t size);
|
||||
void Reset() noexcept;
|
||||
void Start() noexcept;
|
||||
void Stop() noexcept;
|
||||
bool IsActive() noexcept { return (state_.load()); }
|
||||
bool Read(void *buf, std::size_t &size) noexcept;
|
||||
bool Write(const void *buf, std::size_t &size) noexcept;
|
||||
std::size_t GetReadableSize() const noexcept { return actual_size_; }
|
||||
std::size_t GetWritableSize() const noexcept { return buf_size_ - actual_size_; }
|
||||
|
||||
private:
|
||||
std::atomic_int state_;
|
||||
std::uint8_t *buf_;
|
||||
std::size_t buf_size_;
|
||||
std::atomic_size_t actual_size_;
|
||||
std::atomic_intptr_t head_; // read
|
||||
std::atomic_intptr_t tail_; // write
|
||||
};
|
||||
|
||||
} // namespace px4
|
204
winusb/src/DriverHost_PX4/server_base.cpp
Normal file
204
winusb/src/DriverHost_PX4/server_base.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
// server_base.cpp
|
||||
|
||||
#include "server_base.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
ServerBase::ServerBase(const std::wstring &pipe_name, px4::ReceiverManager &receiver_manager) noexcept
|
||||
: pipe_name_(pipe_name),
|
||||
receiver_manager_(receiver_manager),
|
||||
mtx_(),
|
||||
quit_event_(nullptr)
|
||||
{
|
||||
pipe_config_ = { 0 };
|
||||
}
|
||||
|
||||
ServerBase::~ServerBase()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
bool ServerBase::Start() noexcept
|
||||
{
|
||||
if (th_) {
|
||||
error_.assign(EINVAL, std::generic_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!quit_event_) {
|
||||
quit_event_ = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!quit_event_) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE ready_event;
|
||||
|
||||
ready_event = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!ready_event) {
|
||||
CloseHandle(quit_event_);
|
||||
quit_event_ = nullptr;
|
||||
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
th_.reset(new std::thread(&px4::ServerBase::Worker, this, ready_event));
|
||||
} catch (const std::system_error &e) {
|
||||
CloseHandle(ready_event);
|
||||
CloseHandle(quit_event_);
|
||||
quit_event_ = nullptr;
|
||||
|
||||
error_.assign(e.code().value(), e.code().category());
|
||||
return false;
|
||||
}
|
||||
|
||||
WaitForSingleObject(ready_event, INFINITE);
|
||||
CloseHandle(ready_event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ServerBase::Stop() noexcept
|
||||
{
|
||||
if (!th_) {
|
||||
error_.assign(EINVAL, std::generic_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
SetEvent(quit_event_);
|
||||
try {
|
||||
th_->join();
|
||||
} catch (...) {}
|
||||
|
||||
th_.reset();
|
||||
|
||||
try {
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
|
||||
while (conns_.size())
|
||||
cond_.wait(lock);
|
||||
|
||||
lock.unlock();
|
||||
} catch (...) {}
|
||||
|
||||
CloseHandle(quit_event_);
|
||||
quit_event_ = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t ServerBase::GetActiveConnectionCount() const noexcept
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
return conns_.size();
|
||||
}
|
||||
|
||||
void ServerBase::RemoveConnection(Connection *conn, bool destruct) noexcept
|
||||
{
|
||||
bool empty = false;
|
||||
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
for (auto it = conns_.begin(); it != conns_.end(); ++it) {
|
||||
if (it->get() == conn) {
|
||||
if (!destruct)
|
||||
it->release();
|
||||
|
||||
conns_.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
empty = !conns_.size();
|
||||
} catch (...) {}
|
||||
|
||||
if (empty)
|
||||
cond_.notify_all();
|
||||
}
|
||||
|
||||
void ServerBase::Worker(HANDLE ready_event) noexcept
|
||||
{
|
||||
while (true) {
|
||||
std::unique_ptr<px4::PipeServer> pipe(new px4::PipeServer());
|
||||
|
||||
if (!pipe->Accept(pipe_name_, pipe_config_, ready_event, quit_event_))
|
||||
break;
|
||||
|
||||
ready_event = NULL;
|
||||
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
|
||||
auto &p = conns_.emplace_back(std::unique_ptr<Connection>());
|
||||
p.reset(CreateConnection(pipe));
|
||||
if (!p->Start())
|
||||
break;
|
||||
} catch (...) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ServerBase::Connection::Connection(ServerBase &parent, std::unique_ptr<px4::PipeServer> &pipe) noexcept
|
||||
: parent_(parent),
|
||||
conn_(std::move(pipe)),
|
||||
config_(parent_.pipe_config_),
|
||||
receiver_manager_(parent_.receiver_manager_),
|
||||
quit_event_(parent.quit_event_),
|
||||
th_()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ServerBase::Connection::~Connection()
|
||||
{
|
||||
Stop();
|
||||
conn_.reset();
|
||||
|
||||
parent_.RemoveConnection(this, false);
|
||||
}
|
||||
|
||||
bool ServerBase::Connection::Start() noexcept
|
||||
{
|
||||
if (th_) {
|
||||
error_.assign(EINVAL, std::generic_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
th_.reset(new std::thread(&px4::ServerBase::Connection::Worker, this));
|
||||
} catch (const std::system_error &e) {
|
||||
error_.assign(static_cast<int>(e.code().value()), e.code().category());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ServerBase::Connection::Stop() noexcept
|
||||
{
|
||||
if (!th_) {
|
||||
error_.assign(EINVAL, std::generic_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (std::this_thread::get_id() == th_->get_id())
|
||||
th_->detach();
|
||||
else
|
||||
th_->join();
|
||||
} catch (...) {}
|
||||
|
||||
th_.reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace px4
|
87
winusb/src/DriverHost_PX4/server_base.hpp
Normal file
87
winusb/src/DriverHost_PX4/server_base.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
// server_base.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <system_error>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pipe_server.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class ServerBase {
|
||||
public:
|
||||
explicit ServerBase(const std::wstring &pipe_name, px4::ReceiverManager &receiver_manager) noexcept;
|
||||
virtual ~ServerBase();
|
||||
|
||||
// cannot copy
|
||||
ServerBase(const ServerBase &) = delete;
|
||||
ServerBase& operator=(const ServerBase &) = delete;
|
||||
|
||||
// cannot move
|
||||
ServerBase(ServerBase &&) = delete;
|
||||
ServerBase& operator=(ServerBase &&) = delete;
|
||||
|
||||
bool Start() noexcept;
|
||||
bool Stop() noexcept;
|
||||
|
||||
std::size_t GetActiveConnectionCount() const noexcept;
|
||||
|
||||
const std::error_condition& GetError() const noexcept { return error_; }
|
||||
|
||||
protected:
|
||||
class Connection {
|
||||
public:
|
||||
explicit Connection(ServerBase &parent, std::unique_ptr<px4::PipeServer> &pipe) noexcept;
|
||||
virtual ~Connection();
|
||||
|
||||
// cannot copy
|
||||
Connection(const Connection &) = delete;
|
||||
Connection& operator=(const Connection &) = delete;
|
||||
|
||||
// cannot move
|
||||
Connection(Connection &&) = delete;
|
||||
Connection& operator=(Connection &&) = delete;
|
||||
|
||||
bool Start() noexcept;
|
||||
bool Stop() noexcept;
|
||||
|
||||
const std::error_condition& GetError() const noexcept { return error_; }
|
||||
|
||||
protected:
|
||||
virtual void Worker() noexcept {};
|
||||
|
||||
ServerBase &parent_;
|
||||
std::unique_ptr<PipeServer> conn_;
|
||||
px4::PipeServer::PipeServerConfig config_;
|
||||
px4::ReceiverManager &receiver_manager_;
|
||||
HANDLE quit_event_;
|
||||
|
||||
std::error_condition error_;
|
||||
std::unique_ptr<std::thread> th_;
|
||||
};
|
||||
|
||||
virtual Connection* CreateConnection(std::unique_ptr<px4::PipeServer> &pipe) = 0;
|
||||
void RemoveConnection(Connection *conn, bool destruct) noexcept;
|
||||
void Worker(HANDLE ready_event) noexcept;
|
||||
|
||||
const std::wstring pipe_name_;
|
||||
px4::PipeServer::PipeServerConfig pipe_config_;
|
||||
px4::ReceiverManager &receiver_manager_;
|
||||
|
||||
std::error_condition error_;
|
||||
mutable std::mutex mtx_;
|
||||
std::condition_variable cond_;
|
||||
std::deque<std::unique_ptr<Connection>> conns_;
|
||||
HANDLE quit_event_;
|
||||
std::unique_ptr<std::thread> th_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
109
winusb/src/DriverHost_PX4/stream_server.cpp
Normal file
109
winusb/src/DriverHost_PX4/stream_server.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
// steram_server.cpp
|
||||
|
||||
#define msg_prefix "px4_winusb"
|
||||
|
||||
#include "stream_server.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "command.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
StreamServer::StreamServer(px4::ReceiverManager &receiver_manager) noexcept
|
||||
: ServerBase(L"px4_data_pipe", receiver_manager)
|
||||
{
|
||||
pipe_config_.in_buffer_size = 512;
|
||||
pipe_config_.out_buffer_size = 188 * 4096;
|
||||
pipe_config_.stream_pipe = false;
|
||||
pipe_config_.stream_read = false;
|
||||
pipe_config_.default_timeout = 2000;
|
||||
}
|
||||
|
||||
px4::ServerBase::Connection* StreamServer::CreateConnection(std::unique_ptr<px4::PipeServer> &pipe)
|
||||
{
|
||||
return new StreamConnection(*this, pipe);
|
||||
}
|
||||
|
||||
StreamServer::StreamConnection::StreamConnection(ServerBase &parent, std::unique_ptr<px4::PipeServer> &pipe) noexcept
|
||||
: Connection(parent, pipe)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StreamServer::StreamConnection::Worker() noexcept
|
||||
{
|
||||
std::size_t size = config_.in_buffer_size;
|
||||
std::unique_ptr<std::uint8_t[]> buf(new std::uint8_t[size]);
|
||||
px4::ReceiverBase *receiver = nullptr;
|
||||
std::unique_ptr<std::thread> stream_th;
|
||||
|
||||
while (true) {
|
||||
std::size_t read;
|
||||
|
||||
if (!conn_->Read(buf.get(), size, read, quit_event_))
|
||||
break;
|
||||
|
||||
int ret = true;
|
||||
px4::command::DataCmd *cmd = reinterpret_cast<px4::command::DataCmd *>(buf.get());
|
||||
|
||||
switch (cmd->cmd) {
|
||||
case px4::command::DataCmdCode::SET_DATA_ID:
|
||||
if (receiver)
|
||||
break;
|
||||
|
||||
receiver = receiver_manager_.SearchByDataId(cmd->data_id);
|
||||
if (!receiver) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
stream_th.reset(new std::thread(&px4::StreamServer::StreamConnection::StreamWorker, this, receiver->GetStreamBuffer()));
|
||||
} catch (...) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (receiver && stream_th) {
|
||||
receiver->GetStreamBuffer()->StopRequest();
|
||||
|
||||
stream_th->join();
|
||||
stream_th.reset();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void StreamServer::StreamConnection::StreamWorker(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf) noexcept
|
||||
{
|
||||
msg_dbg("px4::StreamServer::StreamConnection::StreamWorker\n");
|
||||
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
|
||||
stream_buf->HandleRead(config_.out_buffer_size / 4,
|
||||
[this](const void *buf, std::size_t size) {
|
||||
return conn_->Write(buf, size, size, quit_event_);
|
||||
}
|
||||
);
|
||||
|
||||
msg_dbg("px4::StreamServer::StreamConnection::StreamWorker: exit\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace px4
|
51
winusb/src/DriverHost_PX4/stream_server.hpp
Normal file
51
winusb/src/DriverHost_PX4/stream_server.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// stream_server.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
#include "server_base.hpp"
|
||||
#include "pipe_server.hpp"
|
||||
#include "receiver_base.hpp"
|
||||
#include "receiver_manager.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class StreamServer final : public px4::ServerBase {
|
||||
public:
|
||||
explicit StreamServer(px4::ReceiverManager &receiver_manager) noexcept;
|
||||
~StreamServer() {}
|
||||
|
||||
// cannot copy
|
||||
StreamServer(const StreamServer &) = delete;
|
||||
StreamServer& operator=(const StreamServer &) = delete;
|
||||
|
||||
// cannot move
|
||||
StreamServer(StreamServer &&) = delete;
|
||||
StreamServer& operator=(StreamServer &&) = delete;
|
||||
|
||||
private:
|
||||
class StreamConnection final : public px4::ServerBase::Connection {
|
||||
public:
|
||||
explicit StreamConnection(ServerBase &parent, std::unique_ptr<px4::PipeServer> &pipe) noexcept;
|
||||
~StreamConnection() {}
|
||||
|
||||
// cannot copy
|
||||
StreamConnection(const StreamConnection &) = delete;
|
||||
StreamConnection& operator=(const StreamConnection &) = delete;
|
||||
|
||||
// cannot move
|
||||
StreamConnection(StreamConnection &&) = delete;
|
||||
StreamConnection& operator=(StreamConnection &&) = delete;
|
||||
|
||||
private:
|
||||
void Worker() noexcept override;
|
||||
void StreamWorker(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf) noexcept;
|
||||
};
|
||||
|
||||
px4::ServerBase::Connection* CreateConnection(std::unique_ptr<px4::PipeServer> &pipe) override;
|
||||
};
|
||||
|
||||
} // namespace px4
|
12
winusb/src/DriverHost_PX4/winusb_compat.h
Normal file
12
winusb/src/DriverHost_PX4/winusb_compat.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// winusb_compat.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <winusb.h>
|
||||
|
||||
struct usb_device {
|
||||
HANDLE dev;
|
||||
WINUSB_INTERFACE_HANDLE winusb;
|
||||
USB_DEVICE_DESCRIPTOR descriptor;
|
||||
};
|
146
winusb/src/common/command.hpp
Normal file
146
winusb/src/common/command.hpp
Normal file
@@ -0,0 +1,146 @@
|
||||
// command.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cwchar>
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "type.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
#pragma pack(push, 8)
|
||||
|
||||
namespace command {
|
||||
static const std::uint32_t VERSION = 0x00040000U;
|
||||
|
||||
enum class CtrlCmdCode : std::uint32_t {
|
||||
UNDEFINED = 0,
|
||||
GET_VERSION = 1,
|
||||
OPEN = 8,
|
||||
CLOSE,
|
||||
GET_INFO,
|
||||
SET_CAPTURE,
|
||||
GET_PARAMS = 16,
|
||||
SET_PARAMS,
|
||||
CLEAR_PARAMS,
|
||||
TUNE,
|
||||
SET_LNB_VOLTAGE = 24,
|
||||
READ_STATS = 32,
|
||||
};
|
||||
|
||||
enum class CtrlStatusCode : std::uint32_t {
|
||||
NONE = 0, // request
|
||||
SUCCEEDED, // response
|
||||
FAILED, // response
|
||||
};
|
||||
|
||||
struct CtrlCmdHeader {
|
||||
CtrlCmdCode cmd;
|
||||
CtrlStatusCode status;
|
||||
};
|
||||
|
||||
struct CtrlVersionCmd : CtrlCmdHeader {
|
||||
std::uint32_t driver_version;
|
||||
std::uint32_t cmd_version;
|
||||
};
|
||||
|
||||
struct ReceiverInfo {
|
||||
wchar_t device_name[96];
|
||||
GUID device_guid; // not 'DeviceInterfaceGUID'
|
||||
wchar_t receiver_name[96];
|
||||
GUID receiver_guid;
|
||||
px4::SystemType systems;
|
||||
std::int32_t index;
|
||||
std::uint32_t data_id;
|
||||
};
|
||||
|
||||
struct CtrlOpenCmd : CtrlCmdHeader {
|
||||
ReceiverInfo receiver_info;
|
||||
};
|
||||
|
||||
struct CtrlCloseCmd : CtrlCmdHeader {
|
||||
// header only
|
||||
};
|
||||
|
||||
struct CtrlReceiverInfoCmd : CtrlCmdHeader {
|
||||
ReceiverInfo receiver_info;
|
||||
};
|
||||
|
||||
struct CtrlCaptureCmd : CtrlCmdHeader {
|
||||
bool capture;
|
||||
};
|
||||
|
||||
enum class ParameterType : std::uint32_t {
|
||||
UNDEFINED = 0,
|
||||
BANDWIDTH = 1,
|
||||
STREAM_ID = 16,
|
||||
};
|
||||
|
||||
struct Parameter {
|
||||
ParameterType type;
|
||||
std::uint32_t value;
|
||||
};
|
||||
|
||||
struct ParameterSet {
|
||||
px4::SystemType system;
|
||||
std::uint32_t freq;
|
||||
std::uint32_t num;
|
||||
Parameter params[1];
|
||||
};
|
||||
|
||||
struct CtrlParamsCmd : CtrlCmdHeader {
|
||||
ParameterSet param_set;
|
||||
};
|
||||
|
||||
struct CtrlClearParamsCmd : CtrlCmdHeader {
|
||||
// header only
|
||||
};
|
||||
|
||||
struct CtrlTuneCmd : CtrlCmdHeader {
|
||||
// header only
|
||||
};
|
||||
|
||||
struct CtrlLnbVoltageCmd : CtrlCmdHeader {
|
||||
std::int32_t voltage;
|
||||
};
|
||||
|
||||
enum class StatType : std::uint32_t {
|
||||
UNDEFINED = 0,
|
||||
SIGNAL_STRENGTH,
|
||||
CNR,
|
||||
};
|
||||
|
||||
struct Stat {
|
||||
StatType type;
|
||||
std::int32_t value;
|
||||
};
|
||||
|
||||
struct StatSet {
|
||||
std::uint32_t num;
|
||||
Stat data[1];
|
||||
};
|
||||
|
||||
struct CtrlStatsCmd : CtrlCmdHeader {
|
||||
StatSet stat_set;
|
||||
};
|
||||
|
||||
enum class DataCmdCode : std::uint32_t {
|
||||
UNDEFINED = 0,
|
||||
SET_DATA_ID,
|
||||
};
|
||||
|
||||
struct DataCmd {
|
||||
DataCmdCode cmd;
|
||||
union {
|
||||
std::uint32_t data_id;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace command
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
} // namespace px4
|
||||
|
105
winusb/src/common/config.cpp
Normal file
105
winusb/src/common/config.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// config.cpp
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
bool Config::Load(const std::wstring &path, const std::wstring §ion) noexcept
|
||||
{
|
||||
std::unique_ptr<WCHAR[]> data(new WCHAR[16384]);
|
||||
DWORD len;
|
||||
|
||||
values_.clear();
|
||||
|
||||
len = GetPrivateProfileSectionW(section.c_str(), data.get(), 16384, path.c_str());
|
||||
if (!len)
|
||||
return false;
|
||||
|
||||
WCHAR *p = data.get();
|
||||
|
||||
while (*p != L'\0') {
|
||||
wchar_t *split, *key, *value;
|
||||
std::size_t value_len;
|
||||
|
||||
split = std::wcschr(p, L'=');
|
||||
if (split == nullptr)
|
||||
continue;
|
||||
|
||||
*split = L'\0';
|
||||
key = p;
|
||||
value = split + 1;
|
||||
value_len = std::wcslen(value);
|
||||
|
||||
if ((value[0] == L'\"' && value[value_len - 1] == L'\"') ||
|
||||
(value[0] == L'\'' && value[value_len - 1] == L'\'')) {
|
||||
value[value_len - 1] = L'\0';
|
||||
value++;
|
||||
value_len--;
|
||||
}
|
||||
|
||||
values_.emplace(key, value);
|
||||
|
||||
p = value + value_len + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Config::Exists(const std::wstring &key) const noexcept
|
||||
{
|
||||
return !!values_.count(key);
|
||||
}
|
||||
|
||||
const std::wstring& Config::Get(const std::wstring &key) const
|
||||
{
|
||||
return values_.at(key);
|
||||
}
|
||||
|
||||
const std::wstring Config::Get(const std::wstring &key, const std::wstring &default_value) const
|
||||
{
|
||||
try {
|
||||
return Get(key);
|
||||
} catch (const std::out_of_range&) {
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigSet::Load(const std::wstring &path) noexcept
|
||||
{
|
||||
std::unique_ptr<WCHAR[]> sct(new WCHAR[8192]);
|
||||
DWORD len;
|
||||
|
||||
configs_.clear();
|
||||
|
||||
len = GetPrivateProfileSectionNamesW(sct.get(), 8192, path.c_str());
|
||||
if (!len)
|
||||
return false;
|
||||
|
||||
for (WCHAR *p = sct.get(); *p != L'\0'; p += std::wcslen(p) + 1) {
|
||||
auto v = configs_.emplace(p, Config());
|
||||
|
||||
if (!v.first->second.Load(path, p)) {
|
||||
configs_.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigSet::Exists(const std::wstring &sct) const noexcept
|
||||
{
|
||||
return !!configs_.count(sct);
|
||||
}
|
||||
|
||||
const px4::Config& ConfigSet::Get(const std::wstring &sct) const
|
||||
{
|
||||
return configs_.at(sct);
|
||||
}
|
||||
|
||||
} // namespace px4
|
38
winusb/src/common/config.hpp
Normal file
38
winusb/src/common/config.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class Config final {
|
||||
public:
|
||||
Config() noexcept {}
|
||||
~Config() {}
|
||||
|
||||
bool Load(const std::wstring &path, const std::wstring §ion) noexcept;
|
||||
bool Exists(const std::wstring &key) const noexcept;
|
||||
const std::wstring& Get(const std::wstring &key) const;
|
||||
const std::wstring Get(const std::wstring &key, const std::wstring &default_value) const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::wstring, std::wstring> values_;
|
||||
};
|
||||
|
||||
class ConfigSet final {
|
||||
public:
|
||||
ConfigSet() noexcept {}
|
||||
~ConfigSet() {}
|
||||
|
||||
bool Load(const std::wstring &path) noexcept;
|
||||
bool Exists(const std::wstring &sct) const noexcept;
|
||||
const px4::Config& Get(const std::wstring &sct) const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::wstring, Config> configs_;
|
||||
};
|
||||
|
||||
} // namespace px4
|
64
winusb/src/common/msg.c
Normal file
64
winusb/src/common/msg.c
Normal file
@@ -0,0 +1,64 @@
|
||||
// msg.c
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static enum msg_mode mode = MSG_MODE_NONE;
|
||||
static HANDLE file_handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
void msg_set_mode(enum msg_mode new_mode)
|
||||
{
|
||||
mode = new_mode;
|
||||
}
|
||||
|
||||
bool msg_open_file(const wchar_t *path)
|
||||
{
|
||||
if (file_handle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(file_handle);
|
||||
|
||||
file_handle = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
return (file_handle != INVALID_HANDLE_VALUE) ? true : false;
|
||||
}
|
||||
|
||||
void msg_close_file()
|
||||
{
|
||||
if (file_handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(file_handle);
|
||||
file_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int msg_printf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
int c;
|
||||
|
||||
if (mode == MSG_MODE_NONE)
|
||||
return 0;
|
||||
|
||||
va_start(args, format);
|
||||
c = vsprintf_s(buf, 1024, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (mode & MSG_MODE_CONSOLE)
|
||||
printf("%s", buf);
|
||||
|
||||
if (mode & MSG_MODE_DEBUGGER)
|
||||
OutputDebugStringA(buf);
|
||||
|
||||
if ((mode & MSG_MODE_LOG_FILE) && (file_handle != INVALID_HANDLE_VALUE)) {
|
||||
DWORD wb;
|
||||
|
||||
WriteFile(file_handle, buf, c, &wb, NULL);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
37
winusb/src/common/msg.h
Normal file
37
winusb/src/common/msg.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// msg.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <wctype.h>
|
||||
|
||||
enum msg_mode {
|
||||
MSG_MODE_NONE = 0x0000,
|
||||
MSG_MODE_CONSOLE = 0x0001,
|
||||
MSG_MODE_DEBUGGER = 0x0002,
|
||||
MSG_MODE_LOG_FILE = 0x0004
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void msg_set_mode(enum msg_mode new_mode);
|
||||
bool msg_open_file(const wchar_t *path);
|
||||
void msg_close_file();
|
||||
int msg_printf(const char *format, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef msg_prefix
|
||||
#define msg_prefix ""
|
||||
#endif
|
||||
|
||||
#define msg_err(format, ...) msg_printf("[ERR] " msg_prefix ": " format, ##__VA_ARGS__)
|
||||
#define msg_warn(format, ...) msg_printf("[WARN] " msg_prefix ": " format, ##__VA_ARGS__)
|
||||
#define msg_info(format, ...) msg_printf("[INFO] " msg_prefix ": " format, ##__VA_ARGS__)
|
||||
#if defined(_DEBUG) || defined(_DEBUG_MSG)
|
||||
#define msg_dbg(format, ...) msg_printf("[DBG] " msg_prefix ": " format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define msg_dbg(format, ...)
|
||||
#endif
|
160
winusb/src/common/pipe.cpp
Normal file
160
winusb/src/common/pipe.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
// pipe.cpp
|
||||
|
||||
#include "pipe.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
Pipe::Pipe(HANDLE handle) noexcept
|
||||
: handle_(handle),
|
||||
ol_event_()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Pipe::~Pipe()
|
||||
{
|
||||
if (!IsConnected())
|
||||
return;
|
||||
|
||||
CloseHandle(handle_);
|
||||
handle_ = INVALID_HANDLE_VALUE;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (ol_event_[i]) {
|
||||
CloseHandle(ol_event_[i]);
|
||||
ol_event_[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Pipe::Read(void *buf, std::size_t size, std::size_t &return_size) noexcept
|
||||
{
|
||||
return Read(buf, size, return_size, nullptr);
|
||||
}
|
||||
|
||||
bool Pipe::Read(void *buf, std::size_t size, std::size_t &return_size, HANDLE cancel_event) noexcept
|
||||
{
|
||||
if (!ol_event_[0]) {
|
||||
ol_event_[0] = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!ol_event_[0]) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD read = 0, err;
|
||||
OVERLAPPED ol = { 0 };
|
||||
|
||||
ResetEvent(ol_event_[0]);
|
||||
ol.hEvent = ol_event_[0];
|
||||
|
||||
if (ReadFile(handle_, buf, static_cast<DWORD>(size), &read, &ol)) {
|
||||
return_size = read;
|
||||
return true;
|
||||
}
|
||||
|
||||
err = GetLastError();
|
||||
if (err != ERROR_IO_PENDING) {
|
||||
error_.assign(err, std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE events[2] = { ol_event_[0], cancel_event };
|
||||
DWORD res;
|
||||
|
||||
res = WaitForMultipleObjects((cancel_event) ? 2 : 1, events, FALSE, INFINITE);
|
||||
if (res == WAIT_FAILED) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res != WAIT_OBJECT_0) {
|
||||
error_.assign(ECANCELED, std::generic_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetOverlappedResult(handle_, &ol, &read, TRUE)) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
return_size = read;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pipe::Write(const void *buf, std::size_t size, std::size_t &return_size) noexcept
|
||||
{
|
||||
return Write(buf, size, return_size, nullptr);
|
||||
}
|
||||
|
||||
bool Pipe::Write(const void *buf, std::size_t size, std::size_t &return_size, HANDLE cancel_event) noexcept
|
||||
{
|
||||
if (!ol_event_[1]) {
|
||||
ol_event_[1] = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!ol_event_[1]) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD written = 0, err;
|
||||
OVERLAPPED ol = { 0 };
|
||||
|
||||
ResetEvent(ol_event_[1]);
|
||||
ol.hEvent = ol_event_[1];
|
||||
|
||||
if (WriteFile(handle_, buf, static_cast<DWORD>(size), &written, &ol)) {
|
||||
return_size = written;
|
||||
return true;
|
||||
}
|
||||
|
||||
err = GetLastError();
|
||||
if (err != ERROR_IO_PENDING) {
|
||||
error_.assign(err, std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE events[2] = { ol_event_[1], cancel_event };
|
||||
DWORD res;
|
||||
|
||||
res = WaitForMultipleObjects((cancel_event) ? 2 : 1, events, FALSE, INFINITE);
|
||||
if (res == WAIT_FAILED) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res != WAIT_OBJECT_0) {
|
||||
error_.assign(ECANCELED, std::generic_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetOverlappedResult(handle_, &ol, &written, TRUE)) {
|
||||
error_.assign(GetLastError(), std::system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
return_size = written;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pipe::Call(void *buf, std::size_t size) noexcept
|
||||
{
|
||||
return Call(buf, size, buf, size);
|
||||
}
|
||||
|
||||
bool Pipe::Call(const void *buf_in, std::size_t size_in, void *buf_out, std::size_t size_out) noexcept
|
||||
{
|
||||
std::size_t ret_size;
|
||||
|
||||
if (!Write(buf_in, size_in, ret_size) || ret_size != size_in)
|
||||
return false;
|
||||
|
||||
if (!Read(buf_out, size_out, ret_size) || ret_size != size_out)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace px4
|
51
winusb/src/common/pipe.hpp
Normal file
51
winusb/src/common/pipe.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// pipe.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <system_error>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
class Pipe {
|
||||
public:
|
||||
explicit Pipe(HANDLE handle) noexcept; // for compatibility
|
||||
virtual ~Pipe();
|
||||
|
||||
// cannot copy
|
||||
Pipe(const Pipe &) = delete;
|
||||
Pipe& operator=(const Pipe &) = delete;
|
||||
|
||||
// cannot move
|
||||
Pipe(Pipe &&) = delete;
|
||||
Pipe& operator=(Pipe &&) = delete;
|
||||
|
||||
bool Read(void *buf, std::size_t size, std::size_t &return_size) noexcept;
|
||||
bool Read(void *buf, std::size_t size, std::size_t &return_size, HANDLE cancel_event) noexcept;
|
||||
bool Write(const void *buf, std::size_t size, std::size_t &return_size) noexcept;
|
||||
bool Write(const void *buf, std::size_t size, std::size_t &return_size, HANDLE cancel_event) noexcept;
|
||||
bool Call(void *buf, std::size_t size) noexcept;
|
||||
bool Call(const void *buf_in, std::size_t size_in, void *buf_out, std::size_t size_out) noexcept;
|
||||
|
||||
const std::error_condition& GetError() const noexcept { return error_; }
|
||||
|
||||
protected:
|
||||
Pipe() noexcept : Pipe(nullptr) {}
|
||||
|
||||
bool IsConnected() const noexcept { return (handle_ && handle_ != INVALID_HANDLE_VALUE); }
|
||||
void SetHandle(HANDLE handle) noexcept { handle_ = handle; }
|
||||
|
||||
std::error_condition error_;
|
||||
HANDLE handle_;
|
||||
HANDLE ol_event_[2]; // [0]: read, [1]: write
|
||||
};
|
||||
|
||||
class PipeError : public std::runtime_error {
|
||||
public:
|
||||
explicit PipeError(const std::string& what_arg) : runtime_error(what_arg.c_str()) {};
|
||||
};
|
||||
|
||||
} // namespace px4
|
63
winusb/src/common/type.hpp
Normal file
63
winusb/src/common/type.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// type.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
enum class SystemType : std::uint32_t {
|
||||
UNSPECIFIED = 0x00,
|
||||
ISDB_T = 0x10,
|
||||
ISDB_S = 0x20,
|
||||
};
|
||||
|
||||
constexpr SystemType operator&(SystemType left, SystemType right) noexcept
|
||||
{
|
||||
return static_cast<SystemType>(static_cast<std::uint32_t>(left) & static_cast<std::uint32_t>(right));
|
||||
}
|
||||
|
||||
constexpr SystemType operator|(SystemType left, SystemType right) noexcept
|
||||
{
|
||||
return static_cast<SystemType>(static_cast<std::uint32_t>(left) | static_cast<std::uint32_t>(right));
|
||||
}
|
||||
|
||||
constexpr SystemType& operator&=(SystemType& left, SystemType right) noexcept
|
||||
{
|
||||
left = static_cast<SystemType>(static_cast<std::uint32_t>(left) & static_cast<std::uint32_t>(right));
|
||||
return left;
|
||||
}
|
||||
|
||||
constexpr SystemType& operator|=(SystemType& left, SystemType right) noexcept
|
||||
{
|
||||
left = static_cast<SystemType>(static_cast<std::uint32_t>(left) | static_cast<std::uint32_t>(right));
|
||||
return left;
|
||||
}
|
||||
|
||||
} // namespace px4
|
||||
|
||||
static inline bool operator<(const GUID &left, const GUID &right) noexcept
|
||||
{
|
||||
return memcmp(&left, &right, sizeof(GUID)) < 0;
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<> struct hash<GUID> {
|
||||
std::size_t operator()(const GUID &guid) const noexcept
|
||||
{
|
||||
std::hash<std::size_t> hash;
|
||||
const std::size_t *p = reinterpret_cast<const std::size_t *>(&guid);
|
||||
std::size_t val = 0;
|
||||
|
||||
for (int i = 0; i < (sizeof(guid) / sizeof(std::size_t)); i++)
|
||||
val ^= hash(p[i]);
|
||||
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
182
winusb/src/common/util.cpp
Normal file
182
winusb/src/common/util.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
// util.cpp
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace px4 {
|
||||
|
||||
namespace util {
|
||||
|
||||
bool HexFromStr(const wchar_t c, std::uint8_t &v)
|
||||
{
|
||||
if (c >= L'0' && c <= L'9')
|
||||
v = c - '0';
|
||||
else if (c >= 'A' && c <= L'F')
|
||||
v = c - 'A' + 0x0a;
|
||||
else if (c >= 'a' && c <= L'f')
|
||||
v = c - 'a' + 0x0a;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexStrToUInt8(const wchar_t *str, std::uint8_t &v)
|
||||
{
|
||||
std::uint8_t t;
|
||||
|
||||
if (!HexFromStr(str[0], t))
|
||||
return false;
|
||||
|
||||
v = t << 4;
|
||||
|
||||
if (!HexFromStr(str[1], t))
|
||||
return false;
|
||||
|
||||
v |= t;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShiftJisToUtf16(const char *sjis, std::wstring &utf16)
|
||||
{
|
||||
int required_size;
|
||||
|
||||
required_size = MultiByteToWideChar(932, MB_ERR_INVALID_CHARS, sjis, -1, nullptr, 0);
|
||||
if (!required_size)
|
||||
return false;
|
||||
|
||||
WCHAR *buf = new WCHAR[required_size];
|
||||
|
||||
if (!MultiByteToWideChar(932, MB_ERR_INVALID_CHARS, sjis, -1, buf, required_size))
|
||||
return false;
|
||||
|
||||
utf16 = buf;
|
||||
delete[] buf;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseGuidStr(const std::wstring &utf16, GUID &guid)
|
||||
{
|
||||
GUID tmp;
|
||||
const wchar_t *str = utf16.c_str();
|
||||
wchar_t *end;
|
||||
|
||||
if (std::wcslen(str) != 38 ||
|
||||
str[0] != L'{' ||
|
||||
str[9] != L'-' ||
|
||||
str[14] != L'-' ||
|
||||
str[19] != L'-' ||
|
||||
str[24] != L'-' ||
|
||||
str[37] != L'}')
|
||||
return false;
|
||||
|
||||
tmp.Data1 = std::wcstoul(&str[1], &end, 16);
|
||||
if (end != &str[9])
|
||||
return false;
|
||||
|
||||
tmp.Data2 = static_cast<unsigned short>(std::wcstoul(&str[10], &end, 16));
|
||||
if (end != &str[14])
|
||||
return false;
|
||||
|
||||
tmp.Data3 = static_cast<unsigned short>(std::wcstoul(&str[15], &end, 16));
|
||||
if (end != &str[19])
|
||||
return false;
|
||||
|
||||
for (int i = 0, j = 0; i < 17; i += 2, j++) {
|
||||
if (i == 4)
|
||||
i++;
|
||||
|
||||
if (!HexStrToUInt8(&str[20 + i], tmp.Data4[j]))
|
||||
return false;
|
||||
}
|
||||
|
||||
guid = tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseSystemStr(const std::wstring &str, px4::SystemType &systems)
|
||||
{
|
||||
const wchar_t *head, *tail, *p, *split;
|
||||
|
||||
systems = px4::SystemType::UNSPECIFIED;
|
||||
|
||||
head = p = str.c_str();
|
||||
tail = head + std::wcslen(head);
|
||||
|
||||
while (p <= tail) {
|
||||
p += std::wcsspn(p, L", \t");
|
||||
|
||||
split = p + std::wcscspn(p, L", \t");
|
||||
if (split == p)
|
||||
split = tail;
|
||||
|
||||
if (!std::wcsncmp(L"ISDB-T", p, 6))
|
||||
systems |= px4::SystemType::ISDB_T;
|
||||
else if (!std::wcsncmp(L"ISDB-S", p, 6))
|
||||
systems |= px4::SystemType::ISDB_S;
|
||||
else {
|
||||
systems = px4::SystemType::UNSPECIFIED;
|
||||
return false;
|
||||
}
|
||||
|
||||
p = split + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace path {
|
||||
|
||||
static std::wstring dir_path;
|
||||
static std::wstring file_base;
|
||||
|
||||
bool Init(void *mod)
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
wchar_t *filename, *fileext;
|
||||
|
||||
if (!GetModuleFileNameW(static_cast<HMODULE>(mod), path, MAX_PATH - 4))
|
||||
return false;
|
||||
|
||||
filename = std::wcsrchr(path, L'\\');
|
||||
if (!filename)
|
||||
filename = std::wcsrchr(path, L'/');
|
||||
|
||||
if (!filename)
|
||||
filename = path;
|
||||
else
|
||||
filename++;
|
||||
|
||||
fileext = std::wcsrchr(filename, L'.');
|
||||
if (fileext)
|
||||
*fileext = L'\0';
|
||||
else
|
||||
fileext = filename + std::wcslen(filename);
|
||||
|
||||
file_base = std::wstring(path);
|
||||
|
||||
*filename = L'\0';
|
||||
dir_path = std::wstring(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::wstring& GetDir() noexcept
|
||||
{
|
||||
return dir_path;
|
||||
}
|
||||
|
||||
const std::wstring& GetFileBase() noexcept
|
||||
{
|
||||
return file_base;
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace px4
|
46
winusb/src/common/util.hpp
Normal file
46
winusb/src/common/util.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// util.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "type.hpp"
|
||||
|
||||
namespace px4 {
|
||||
|
||||
namespace util {
|
||||
|
||||
static std::uint32_t atoui(const char *str)
|
||||
{
|
||||
std::uint32_t value = 0;
|
||||
|
||||
for (; *str; str++) {
|
||||
if (*str < '0' || *str > '9')
|
||||
break;
|
||||
|
||||
value *= 10;
|
||||
value += *str - '0';
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool HexFromStr(const wchar_t c, std::uint8_t &v);
|
||||
bool HexStrToUInt8(const wchar_t *str, std::uint8_t &v);
|
||||
bool ShiftJisToUtf16(const char *sjis, std::wstring &utf16);
|
||||
bool ParseGuidStr(const std::wstring &utf16, GUID &guid);
|
||||
bool ParseSystemStr(const std::wstring &str, px4::SystemType &systems);
|
||||
|
||||
namespace path {
|
||||
|
||||
bool Init(void *mod);
|
||||
const std::wstring& GetDir() noexcept;
|
||||
const std::wstring& GetFileBase() noexcept;
|
||||
|
||||
} // namespace path
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace px4
|
241
winusb/src/fwtool/fwtool.vcxproj
Normal file
241
winusb/src/fwtool/fwtool.vcxproj
Normal file
@@ -0,0 +1,241 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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="Release-static|Win32">
|
||||
<Configuration>Release-static</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>
|
||||
<ProjectConfiguration Include="Release-static|x64">
|
||||
<Configuration>Release-static</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{BDBD265F-5914-426F-89F7-16478BE1AFCC}</ProjectGuid>
|
||||
<RootNamespace>fwtool</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<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'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(PlatformTarget)\$(Configuration)\</OutDir>
|
||||
<IntDir>build\$(PlatformTarget)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-static|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\fwtool\crc32.c" />
|
||||
<ClCompile Include="..\..\..\fwtool\fwtool.c" />
|
||||
<ClCompile Include="..\..\..\fwtool\tsv.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\fwtool\crc32.h" />
|
||||
<ClInclude Include="..\..\..\fwtool\tsv.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\fwtool\fwinfo.tsv" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
39
winusb/src/fwtool/fwtool.vcxproj.filters
Normal file
39
winusb/src/fwtool/fwtool.vcxproj.filters
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="ソース ファイル">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="ヘッダー ファイル">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="リソース ファイル">
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\fwtool\crc32.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\fwtool\fwtool.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\fwtool\tsv.c">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\fwtool\crc32.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\fwtool\tsv.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\fwtool\fwinfo.tsv" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user