remove windows driver (#1793)
@@ -98,7 +98,6 @@ As a universal car interface, it should support every reasonable software interf
|
||||
- [Python library](https://github.com/commaai/panda/tree/master/python)
|
||||
- [C++ library](https://github.com/commaai/openpilot/tree/master/selfdrive/boardd)
|
||||
- [socketcan in kernel](https://github.com/commaai/panda/tree/master/drivers/linux) (alpha)
|
||||
- [Windows J2534](https://github.com/commaai/panda/tree/master/drivers/windows)
|
||||
|
||||
## Licensing
|
||||
|
||||
|
||||
307
drivers/windows/.gitignore
vendored
@@ -1,307 +0,0 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
Debug_x86/
|
||||
Debug_x64/
|
||||
Release_x86/
|
||||
Release_x64/
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# installer
|
||||
*.exe
|
||||
*.zip
|
||||
@@ -1,38 +0,0 @@
|
||||
// ECUsim CLI.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ECUsim DLL\ECUsim.h"
|
||||
|
||||
std::unique_ptr<ECUsim> sim;
|
||||
|
||||
BOOL CtrlHandler(DWORD fdwCtrlType)
|
||||
{
|
||||
if (fdwCtrlType != CTRL_C_EVENT) return FALSE;
|
||||
|
||||
sim->stop();
|
||||
sim->join();
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
int main(int argc, // Number of strings in array argv
|
||||
char *argv[], // Array of command-line argument strings
|
||||
char *envp[]) // Array of environment variable strings
|
||||
{
|
||||
|
||||
int count;
|
||||
|
||||
// Display each command-line argument.
|
||||
std::cout << "\nCommand-line arguments:\n";
|
||||
for (count = 0; count < argc; count++)
|
||||
std::cout << " argv[" << count << "] " << argv[count] << "\n";
|
||||
|
||||
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
|
||||
|
||||
sim.reset(new ECUsim("", 500000));
|
||||
sim->join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D99E2FCD-21A4-4065-949A-31E34E0E69D1}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>ECUsimCLI</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</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)'=='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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</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;%(AdditionalDependencies);$(OutDir)ecusim.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</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;%(AdditionalDependencies);$(OutDir)ecusim.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);$(OutDir)ecusim.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);$(OutDir)ecusim.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\ECUsim DLL\ECUsim.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ECUsim CLI.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ECUsim DLL\ECUsim DLL.vcxproj">
|
||||
<Project>{96e0e646-ee76-444d-9a77-a0cd7f781deb}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ECUsim DLL\ECUsim.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ECUsim CLI.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// ECUsim CLI.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -1,15 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
@@ -1,197 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{96E0E646-EE76-444D-9A77-A0CD7F781DEB}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>ECUsimDLL</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</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)'=='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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>ecusim</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>ecusim</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>ecusim</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>ecusim</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ECUSIMDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</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;%(AdditionalDependencies);$(OutDir)panda.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;ECUSIMDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</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;%(AdditionalDependencies);$(OutDir)panda.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ECUSIMDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);$(OutDir)panda.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;ECUSIMDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);$(OutDir)panda.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\panda\panda.h" />
|
||||
<ClInclude Include="ECUsim.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ECUsim.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\panda\panda.vcxproj">
|
||||
<Project>{5528aefb-638d-49af-b9d4-965154e7d531}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ECUsim.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\panda\panda.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ECUsim.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,261 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "ECUsim.h"
|
||||
|
||||
ECUsim::ECUsim(std::string sn, unsigned long can_baud, bool ext_addr) :
|
||||
doloop(TRUE), verbose(TRUE), can11b_enabled(TRUE), can29b_enabled(TRUE), ext_addr(ext_addr){
|
||||
this->panda = panda::Panda::openPanda(sn);
|
||||
this->panda->set_can_speed_cbps(panda::PANDA_CAN1, can_baud / 100); //Don't pass in baud where baud%100 != 0
|
||||
this->panda->set_safety_mode(panda::SAFETY_ALLOUTPUT);
|
||||
this->panda->set_can_loopback(FALSE);
|
||||
this->panda->can_clear(panda::PANDA_CAN_RX);
|
||||
|
||||
DWORD threadid;
|
||||
this->thread_can = CreateThread(NULL, 0, _canthreadBootstrap, (LPVOID)this, 0, &threadid);
|
||||
}
|
||||
|
||||
ECUsim::~ECUsim() {
|
||||
this->stop();
|
||||
this->join();
|
||||
}
|
||||
|
||||
void ECUsim::stop() {
|
||||
this->doloop = FALSE;
|
||||
}
|
||||
|
||||
void ECUsim::join() {
|
||||
WaitForSingleObject(this->thread_can, INFINITE);
|
||||
}
|
||||
|
||||
DWORD WINAPI ECUsim::_canthreadBootstrap(LPVOID This) {
|
||||
return ((ECUsim*)This)->can_recv_thread_function();
|
||||
}
|
||||
|
||||
DWORD ECUsim::can_recv_thread_function() {
|
||||
while (this->doloop) {
|
||||
auto msgs = this->panda->can_recv();
|
||||
for (auto& msg : msgs) {
|
||||
if (msg.is_receipt) continue;
|
||||
if (msg.bus == 0 && !msg.is_receipt /*&& msg.len == 8*/ && msg.dat[0] >= 2) {
|
||||
if (this->verbose) {
|
||||
printf("Processing message (bus: %d; addr: %X; 29b: %d):\n ", msg.bus, msg.addr, msg.addr_29b);
|
||||
for (int i = 0; i < msg.len; i++) printf("%02X ", msg.dat[i]);
|
||||
printf("\n");
|
||||
}
|
||||
this->_CAN_process_msg(msg);
|
||||
} else {
|
||||
if (this->verbose) {
|
||||
printf("Rejecting message (bus: %d; addr: %X; 29b: %d):\n ", msg.bus, msg.addr, msg.addr_29b);
|
||||
for (int i = 0; i < msg.len; i++) printf("%02X ", msg.dat[i]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL ECUsim::_can_addr_matches(panda::PANDA_CAN_MSG& msg) {
|
||||
if (this->can11b_enabled && !msg.addr_29b && (msg.addr == 0x7DF || (msg.addr & 0x7F8) == 0x7E0)) {
|
||||
if (!this->ext_addr) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return msg.len >= 1 && msg.dat[0] == 0x13;//13 is an arbitrary address picked to test ext addresses
|
||||
}
|
||||
}
|
||||
if (this->can29b_enabled && msg.addr_29b && ((msg.addr & 0x1FFF00FF) == 0x18DB00F1 || (msg.addr & 0x1FFF00FF) == 0x18da00f1)) {
|
||||
if (!this->ext_addr) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return msg.len >= 1 && msg.dat[0] == 0x13;//13 is an arbitrary address picked to test ext addresses
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void ECUsim::_CAN_process_msg(panda::PANDA_CAN_MSG& msg) {
|
||||
std::string outmsg;
|
||||
uint32_t outaddr;
|
||||
uint8_t formatted_msg_buff[8];
|
||||
bool doreply = FALSE;
|
||||
|
||||
if (this->_can_addr_matches(msg)) {// && msg.len == 8) {
|
||||
uint8_t *dat = (this->ext_addr) ? &msg.dat[1] : &msg.dat[0];
|
||||
if ((dat[0] & 0xF0) == 0x10) {
|
||||
printf("Got a multiframe write request\n");
|
||||
outaddr = (msg.addr_29b) ? 0x18DAF1EF : 0x7E8;
|
||||
this->panda->can_send(outaddr, msg.addr_29b, (const uint8_t*)"\x30\x00\x00", 3, panda::PANDA_CAN1);
|
||||
return;
|
||||
}
|
||||
|
||||
/////////// Check if Flow Control Msg
|
||||
if ((dat[0] & 0xF0) == 0x30 && msg.len >= 3 && this->can_multipart_data.size() > 0) {
|
||||
if (this->verbose) printf("More data requested\n");
|
||||
uint8_t block_size = dat[1], sep_time_min = dat[2];
|
||||
outaddr = (msg.addr == 0x7DF || msg.addr == 0x7E0) ? 0x7E8 : 0x18DAF1EF; //ext addr 5th byte is just always 0x13 for simplicity
|
||||
|
||||
unsigned int msgnum = 1;
|
||||
while (this->can_multipart_data.size()) {
|
||||
unsigned int datalen = this->ext_addr ?
|
||||
min(6, this->can_multipart_data.size()): //EXT ADDR VALUE
|
||||
min(7, this->can_multipart_data.size()); //NORMAL ADDR VALUE
|
||||
|
||||
unsigned int idx = 0;
|
||||
if (this->ext_addr)
|
||||
formatted_msg_buff[idx++] = 0x13; //EXT ADDR
|
||||
formatted_msg_buff[idx++] = 0x20 | msgnum;
|
||||
for (int i = 0; i < datalen; i++) {
|
||||
formatted_msg_buff[i + idx] = this->can_multipart_data.front();
|
||||
this->can_multipart_data.pop();
|
||||
}
|
||||
for (int i = datalen + idx; i < sizeof(formatted_msg_buff); i++)
|
||||
formatted_msg_buff[i] = 0;
|
||||
|
||||
if (this->verbose) {
|
||||
printf("Multipart reply to %X.\n ", outaddr);
|
||||
for (int i = 0; i < datalen + idx; i++) printf("%02X ", formatted_msg_buff[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
this->panda->can_send(outaddr, msg.addr_29b, formatted_msg_buff, datalen + idx, panda::PANDA_CAN1);
|
||||
msgnum = (msgnum + 1) % 0x10;
|
||||
Sleep(10);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/////////// Normal message in
|
||||
outmsg = this->process_obd_msg(dat[1], dat[2], doreply);
|
||||
if (doreply) {
|
||||
outaddr = (msg.addr_29b) ? 0x18DAF1EF : 0x7E8;
|
||||
|
||||
if (outmsg.size() <= (this->ext_addr ? 4 : 5)) {
|
||||
unsigned int idx = 0;
|
||||
if(this->ext_addr)
|
||||
formatted_msg_buff[idx++] = 0x13; //EXT ADDR
|
||||
formatted_msg_buff[idx++] = outmsg.size() + 2;
|
||||
formatted_msg_buff[idx++] = 0x40 | dat[1];
|
||||
formatted_msg_buff[idx++] = dat[2]; //PID
|
||||
memcpy_s(&formatted_msg_buff[idx], sizeof(formatted_msg_buff) - idx, outmsg.c_str(), outmsg.size());
|
||||
for (int i = idx + outmsg.size(); i < 8; i++)
|
||||
formatted_msg_buff[i] = 0;
|
||||
|
||||
if (this->verbose) {
|
||||
printf("Replying to %X.\n ", outaddr);
|
||||
for (int i = 0; i < 8; i++) printf("%02X ", formatted_msg_buff[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
this->panda->can_send(outaddr, msg.addr_29b, formatted_msg_buff, 8, panda::PANDA_CAN1); //outmsg.size() + 3
|
||||
} else {
|
||||
uint8_t first_msg_len = this->ext_addr ?
|
||||
min(2, outmsg.size() % 7) : //EXT ADDR VALUES
|
||||
min(3, outmsg.size() % 7); //NORMAL ADDR VALUES
|
||||
uint8_t payload_len = outmsg.size() + 3;
|
||||
|
||||
unsigned int idx = 0;
|
||||
if (this->ext_addr)
|
||||
formatted_msg_buff[idx++] = 0x13; //EXT ADDR
|
||||
formatted_msg_buff[idx++] = 0x10 | ((payload_len >> 8) & 0xF);
|
||||
formatted_msg_buff[idx++] = payload_len & 0xFF;
|
||||
formatted_msg_buff[idx++] = 0x40 | dat[1];
|
||||
formatted_msg_buff[idx++] = dat[2]; //PID
|
||||
formatted_msg_buff[idx++] = 1;
|
||||
memcpy_s(&formatted_msg_buff[idx], sizeof(formatted_msg_buff) - idx, outmsg.c_str(), first_msg_len);
|
||||
|
||||
if (this->verbose) {
|
||||
printf("Replying FIRST FRAME to %X.\n ", outaddr);
|
||||
for (int i = 0; i < 8; i++) printf("%02X ", formatted_msg_buff[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
this->panda->can_send(outaddr, msg.addr_29b, formatted_msg_buff, 8, panda::PANDA_CAN1);
|
||||
for (int i = first_msg_len; i < outmsg.size(); i++)
|
||||
this->can_multipart_data.push(outmsg[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ECUsim::process_obd_msg(UCHAR mode, UCHAR pid, bool& return_data) {
|
||||
std::string tmp;
|
||||
return_data = TRUE;
|
||||
|
||||
switch (mode) {
|
||||
case 0x01: // Mode : Show current data
|
||||
switch (pid) {
|
||||
case 0x00: //List supported things
|
||||
return "\xff\xff\xff\xfe"; //b"\xBE\x1F\xB8\x10" #Bitfield, random features
|
||||
case 0x01: // Monitor Status since DTC cleared
|
||||
return std::string("\x00\x00\x00\x00", 4); //Bitfield, random features
|
||||
case 0x04: // Calculated engine load
|
||||
return "\x2f";
|
||||
case 0x05: // Engine coolant temperature
|
||||
return "\x3c";
|
||||
case 0x0B: // Intake manifold absolute pressure
|
||||
return "\x90";
|
||||
case 0x0C: // Engine RPM
|
||||
return "\x1A\xF8";
|
||||
case 0x0D: // Vehicle Speed
|
||||
return "\x53";
|
||||
case 0x10: // MAF air flow rate
|
||||
return "\x01\xA0";
|
||||
case 0x11: // Throttle Position
|
||||
return "\x90";
|
||||
case 0x33: // Absolute Barometric Pressure
|
||||
return "\x90";
|
||||
default:
|
||||
return_data = FALSE;
|
||||
return "";
|
||||
}
|
||||
case 0x09: // Mode : Request vehicle information
|
||||
switch (pid) {
|
||||
case 0x02: // Show VIN
|
||||
return "1D4GP00R55B123456";
|
||||
case 0xFC: // test long multi message.Ligned up for LIN responses
|
||||
for (int i = 0; i < 80; i++) {
|
||||
tmp += "\xAA\xAA";
|
||||
}
|
||||
return tmp;//">BBH", 0xAA, 0xAA, num + 1)
|
||||
case 0xFD: // test long multi message
|
||||
for (int i = 0; i < 80; i++) {
|
||||
tmp += "\xAA\xAA\xAA";
|
||||
tmp.push_back(i >> 24);
|
||||
tmp.push_back((i >> 16) & 0xFF);
|
||||
tmp.push_back((i >> 8) & 0xFF);
|
||||
tmp.push_back(i & 0xFF);
|
||||
}
|
||||
return "\xAA\xAA\xAA" + tmp;
|
||||
case 0xFE: // test very long multi message
|
||||
tmp = "\xAA\xAA\xAA";
|
||||
for (int i = 0; i < 584; i++) {
|
||||
tmp += "\xAA\xAA\xAA";
|
||||
tmp.push_back(i >> 24);
|
||||
tmp.push_back((i >> 16) & 0xFF);
|
||||
tmp.push_back((i >> 8) & 0xFF);
|
||||
tmp.push_back(i & 0xFF);
|
||||
}
|
||||
return tmp + "\xAA";
|
||||
case 0xFF:
|
||||
for (int i = 0; i < 584; i++) {
|
||||
tmp += "\xAA\xAA\xAA\xAA\xAA";
|
||||
tmp.push_back(((i + 1) >> 8) & 0xFF);
|
||||
tmp.push_back((i + 1) & 0xFF);
|
||||
}
|
||||
return std::string("\xAA\x00\x00", 3) + tmp;
|
||||
default:
|
||||
return_data = FALSE;
|
||||
return "";
|
||||
}
|
||||
case 0x3E:
|
||||
if (pid == 0) {
|
||||
return_data = TRUE;
|
||||
return "";
|
||||
}
|
||||
return_data = FALSE;
|
||||
return "";
|
||||
default:
|
||||
return_data = FALSE;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "panda_shared/panda.h"
|
||||
#include <queue>
|
||||
|
||||
// The following ifdef block is the standard way of creating macros which make exporting
|
||||
// from a DLL simpler. All files within this DLL are compiled with the ECUSIMDLL_EXPORTS
|
||||
// symbol defined on the command line. This symbol should not be defined on any project
|
||||
// that uses this DLL. This way any other project whose source files include this file see
|
||||
// ECUSIMDLL_API functions as being imported from a DLL, whereas this DLL sees symbols
|
||||
// defined with this macro as being exported.
|
||||
#ifdef ECUSIMDLL_EXPORTS
|
||||
#define ECUSIMDLL_API __declspec(dllexport)
|
||||
#else
|
||||
#define ECUSIMDLL_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
// This class is exported from the ECUsim DLL.dll
|
||||
class ECUSIMDLL_API ECUsim {
|
||||
public:
|
||||
ECUsim(std::string sn, unsigned long can_baud, bool ext_addr = FALSE);
|
||||
ECUsim(panda::Panda && p, unsigned long can_baud, bool ext_addr = FALSE);
|
||||
~ECUsim();
|
||||
|
||||
void stop();
|
||||
void join();
|
||||
|
||||
// Flag determines if verbose output is enabled
|
||||
volatile bool verbose;
|
||||
BOOL ext_addr;
|
||||
private:
|
||||
std::unique_ptr<panda::Panda> panda;
|
||||
|
||||
static DWORD WINAPI _canthreadBootstrap(LPVOID This);
|
||||
DWORD can_recv_thread_function();
|
||||
|
||||
BOOL _can_addr_matches(panda::PANDA_CAN_MSG & msg);
|
||||
|
||||
void _CAN_process_msg(panda::PANDA_CAN_MSG & msg);
|
||||
|
||||
std::string process_obd_msg(UCHAR mode, UCHAR pid, bool& return_data);
|
||||
|
||||
HANDLE thread_can;
|
||||
volatile bool doloop;
|
||||
std::queue<uint8_t> can_multipart_data;
|
||||
|
||||
BOOL can11b_enabled;
|
||||
BOOL can29b_enabled;
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "stdafx.h"
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// ECUsim DLL.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
@@ -1,144 +0,0 @@
|
||||
|
||||
# Windows driver
|
||||
```
|
||||
;" ^; ;' ",
|
||||
______/\\\\\\\\\\\____/\\\\\\\\\_______/\\\\\\\\\\\\\\\______/\\\\\\\\\\_____________/\\\____ ; s$$$$$$$s ;
|
||||
_____\/////\\\///___/\\\///////\\\____\/\\\///////////_____/\\\///////\\\__________/\\\\\____ , ss$$$$$$$$$$s ,'
|
||||
_________\/\\\_____\///______\//\\\___\/\\\_______________\///______/\\\_________/\\\/\\\____ ;s$$$$$$$$$$$$$$$
|
||||
_________\/\\\_______________/\\\/____\/\\\\\\\\\\\\_____________/\\\//________/\\\/\/\\\____ $$$$$$$$$$$$$$$$$$
|
||||
_________\/\\\____________/\\\//______\////////////\\\__________\////\\\_____/\\\/__\/\\\____ $$$$P""Y$$$Y""W$$$$$
|
||||
_________\/\\\_________/\\\//____________________\//\\\____________\//\\\__/\\\\\\\\\\\\\\\\_ $$$$ p"$$$"q $$$$$
|
||||
__/\\\___\/\\\_______/\\\/____________/\\\________\/\\\___/\\\______/\\\__\///////////\\\//__ $$$$ .$$$$$. $$$$
|
||||
_\//\\\\\\\\\_______/\\\\\\\\\\\\\\\_\//\\\\\\\\\\\\\/___\///\\\\\\\\\/_____________\/\\\____ _ $$$$$$$$$$$$$$$$
|
||||
__\/////////_______\///////////////___\/////////////_______\/////////_______________\///_____| | "Y$$$"*"$$$Y"
|
||||
_ __ __ _ _ __ __| | __ _"$b.$$"
|
||||
| '_ \ / _` | '_ \ / _` |/ _` |
|
||||
| |_) | (_| | | | | (_| | (_| |
|
||||
| .__/ \__,_|_| |_|\__,_|\__,_|
|
||||
| | A comma.ai product.
|
||||
|_| (Code by Jessy Diamond Exum)
|
||||
```
|
||||
|
||||
## Installing J2534 driver
|
||||
|
||||
[Download](https://github.com/commaai/panda/files/4844692/panda.J2534.driver.install.zip)
|
||||
|
||||
Depending on what version of windows you are on, you may need to separately install the WinUSB driver (see next section).
|
||||
|
||||
## Installing WinUSB driver
|
||||
|
||||
Installation automatically happens for Windows 8 and Windows 10 because the panda
|
||||
firmware contains the USB descriptors necessary to auto-install the WinUSB driver.
|
||||
|
||||
Windows 7 will not auto-install the WinUSB driver. You can use Zadig to install
|
||||
the WinUSB driver. This software is not tested on anything before 7.
|
||||
|
||||
More details here:
|
||||
[WinUSB (Winusb.sys) Installation](https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation)
|
||||
[WCID Devices](https://github.com/pbatard/libwdi/wiki/WCID-Devices)
|
||||
[Zadig for installing libusb compatible driver](https://github.com/pbatard/libwdi/wiki/Zadig)
|
||||
|
||||
## Using J2534
|
||||
|
||||
After installing the J2534 drivers for the panda, you can do... nothing.
|
||||
You first need to get a J2534 client that can load the drivers and talk to
|
||||
the panda for you.
|
||||
|
||||
A simple tool for testing J2534 drivers is DrewTech's 'J2534-1 Bus Analysis
|
||||
Tool' available in the 'Other Support Applications' section of their
|
||||
[Download Page](http://www.drewtech.com/downloads/#OtherSupportApplications).
|
||||
|
||||
## What is J2534?
|
||||
|
||||
J2534 is an API that tries to provide a consistent way to send/receive
|
||||
messages over the many different protocols supported by the OBD II
|
||||
port. The place this is perhaps most obvious, is sending data over
|
||||
different protocols (each using unique packetizing methods) using the
|
||||
same data format.
|
||||
|
||||
For each PassThru Device that should be used with J2534 (in this case,
|
||||
the panda), a 'driver' has to be written that can be loaded by a
|
||||
client application wanting to send/receive data.
|
||||
|
||||
A lot of J2534 has good ideas behind it, but the standard has some odd choices:
|
||||
|
||||
* Platform Locked: Requires using the Windows Registry to find installed J2534 libraries/drivers. Drivers have to be DLLs.
|
||||
* Architecture Locked: So far there is only support for x86.
|
||||
* No device autodetect, and poor support for selecting from multiple devices.
|
||||
* Constant vague language about important behavior (small differences between vendors).
|
||||
* Most common differences become standard in later revisions.
|
||||
|
||||
## Why use J2534 with the panda?
|
||||
|
||||
J2534 is the only interface supported by most professional grade
|
||||
vehicle diagnostics systems (such as HDS). These tools are useful for
|
||||
diagnosing vehicles, as well as reverse engineering some lesser known
|
||||
features.
|
||||
|
||||
## What parts are supported with panda?
|
||||
|
||||
- [ ] **J1850VPW** *(Outdated, and not physically supported by the panda)*
|
||||
- [ ] **J1850PWM** *(Outdated, and not physically supported by the panda)*
|
||||
- [X] **CAN**
|
||||
- [X] **ISO15765**
|
||||
- [X] **ISO9141**
|
||||
- [X] **ISO14230/KWP2000**
|
||||
|
||||
## Building the Project
|
||||
|
||||
This project is developed with Visual Studio 2017, the Windows SDK,
|
||||
and the Windows Driver Kit (WDK).
|
||||
|
||||
The WDK is only required for creating the signed WinUSB inf file. The
|
||||
WDK may also provide the headers for WinUSB.
|
||||
|
||||
To build all the projects required for the installer, in Visual
|
||||
Studio, select **Build->Batch Build.** In the project list select:
|
||||
|
||||
- **"panda"** *Release|x86*
|
||||
- **"panda"** *Release|x64*
|
||||
- **"panda Driver Package"** Debug|x86 (Note this inf file works with x86/amd64).
|
||||
- **"pandaJ2534DLL"** *Release|x86*
|
||||
|
||||
The installer is generated with [NullSoft NSIS](http://nsis.sourceforge.net/Main_Page).
|
||||
Use NSIS to run panda_install.nsi after building all the required projects.
|
||||
|
||||
Before generating the installer, you must go to copy vscruntimeinfo.nsh.sample to
|
||||
vscruntimeinfo.nsh and follow the instructions to bundle in the Visual Studio C
|
||||
Runtime required by your version of Visual Studio. Without this runtime, the panda
|
||||
code will not work, so without this file, the installer will refuse to build.
|
||||
|
||||
## Developing
|
||||
|
||||
- Edit and merge pandaJ2534DLL\J2534register_x64.reg to register your development J2534 DLL.
|
||||
- Add your output directory (panda\drivers\windows\Debug_x86) to your system PATH to avoid insanity.
|
||||
|
||||
## ToDo Items
|
||||
|
||||
- Apply a style-guide and consistent naming convention for Classes/Functions/Variables.
|
||||
- Send multiple messages (each with a different address) from a given connection at the same time.
|
||||
- Find more documentation about SW_CAN_PS (Single Wire CAN, aka GMLAN).
|
||||
- Find example of client using a _PS version of a protocol (PS is pin select, and may support using different CAN buses).
|
||||
|
||||
|
||||
## Known Issues
|
||||
|
||||
- ISO15765 Multi-frame TX: Hardware delays make transmission overshoot
|
||||
STMIN by several milliseconds. This does not violate the requirements
|
||||
of STMIN, it just means it is a little slower than it could be.
|
||||
|
||||
- All Tx messages from a single Connection are serialized. This can be
|
||||
relaxed to allow serialization of messages based on their address
|
||||
(making multiple queues, effectively one queue per address).
|
||||
|
||||
## Troubleshooting
|
||||
troubleshooting:
|
||||
1. Install DrewTech J2534-1 Bus Analysis Tool
|
||||
http://www.drewtech.com/downloads/tools/Drew%20Technologies%20Tool%20for%20J2534-1%20API%20v1.07.msi
|
||||
2. Open DrewTech tool and make sure it shows "panda" as a device listed (this means registry settings are correct)
|
||||
3. When DrewTech tool attempts to load the driver it will show an error if it fails
|
||||
4. To figure out why the driver fails to load install Process Monitor and filter by the appropriate process name
|
||||
https://docs.microsoft.com/en-us/sysinternals/downloads/procmon
|
||||
|
||||
## Other
|
||||
Panda head ASCII art by dcau
|
||||
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 348 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 109 KiB |
@@ -1,347 +0,0 @@
|
||||
When using the ISO 15765-4 protocol, only SingleFrame messages can be transmitted without a matching
|
||||
flow control filter. Also, PCI bytes are transparently added by the API. See PassThruStartMsgFilter
|
||||
and Appendix A for a discussion of flow control filters.
|
||||
|
||||
|
||||
|
||||
PassThruReadMsgs
|
||||
This function reads messages and indications from the receive buffer. All messages and indications shall
|
||||
be read in the order that they occurred on the bus. If a transmit message generated a loopback message
|
||||
and TxDone indication, the TxDone indication shall always be queued first. Except for loopback messages
|
||||
and indications, no messages shall be queued for reception without matching a PASS_FILTER
|
||||
(for non-ISO 15765) or FLOW_CONTROL filter (for ISO 15765). On ISO 15765, PCI bytes are transparently
|
||||
removed by the API. If the function is successful, a value of STATUS_NOERROR is returned.
|
||||
|
||||
|
||||
PassThruWriteMsgs
|
||||
Write timeout (in milliseconds). When a value of 0 is specified, the function queues as
|
||||
many of the specified messages as possible and returns immediately. When a value
|
||||
greater than 0 is specified, the function will block until the Timeout has expired, an error
|
||||
has occurred, or the desired number of messages have been transmitted on the vehicle
|
||||
network. Even if the device can buffer only one packet at a time, this function shall be
|
||||
able to send an arbitrary number of packets if a Timeout value is supplied. Since the
|
||||
function returns early if all the messages have been sent, there is normally no penalty for
|
||||
having a large timeout (several seconds). If the number of messages requested have
|
||||
been written, the function shall not return ERR_TIMEOUT, even if the timeout value is
|
||||
zero.
|
||||
|
||||
When an ERR_TIMEOUT is returned, only the number of messages that were sent on
|
||||
the vehicle network is known. The number of messages queued is unknown. Application
|
||||
writers should avoid this ambiguity by using a Timeout value large enough to work on
|
||||
slow devices and networks with arbitration delays.
|
||||
|
||||
|
||||
|
||||
PassThruStartPeriodicMsg
|
||||
This function will immediately queue the specified message for transmission, and repeat at the specified
|
||||
interval. Periodic messages are limited in length to a single frame message of 12 bytes or less, including
|
||||
header or CAN ID. Periodic messages shall have priority over messages queued with
|
||||
PassThruWriteMsgs, but periodic messages must not violate bus idle timing parameters (e.g. P3_MIN).
|
||||
Periodic messages shall generate TxDone indications (ISO 15765) and loopback messages (on any
|
||||
protocol, if enabled). On ISO 15765, periodic messages can be sent during a multi-frame transmission or
|
||||
reception. If the function is successful, a value of STATUS_NOERROR is returned. The Pass-Thru
|
||||
device must support a minimum of ten periodic messages.
|
||||
|
||||
PassThruDisconnect shall delete all periodic messages on that channel. PassThruClose shall delete all
|
||||
periodic messages on all channels for the device. All periodic messages will be stopped on a
|
||||
PassThruDisconnect for the associated protocol or a PassThruClose for the device.
|
||||
|
||||
|
||||
|
||||
PASSTHRUSTARTMSGFILTER
|
||||
This function starts filtering of incoming messages. If the function is successful, a value of
|
||||
STATUS_NOERROR is returned. A minimum of ten message filters shall be supported by the interface
|
||||
for each supported protocol. PassThruDisconnect shall delete all message filters on that channel.
|
||||
|
||||
PassThruClose shall delete all filters on all channels for the device. Pattern and Mask messages shall
|
||||
follow the protocol formats specified in Section 8. However, only the first twelve (12) bytes, including
|
||||
header or CAN ID, are used by the filter. ERR_INVALID_MSG shall be returned if the filter length
|
||||
exceeds 12. Note that this function does not clear any messages that may have been received and
|
||||
queued before the filter was set. Users are cautioned to consider performing a CLEAR_RX_BUFFER
|
||||
after starting a message filter to be sure that unwanted frames are purged from any receive buffers.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
FILTER RELATED STUFF
|
||||
For all protocols except ISO 15765:
|
||||
• PASS_FILTERs and BLOCK_FILTERs will be applied to all received messages. They shall not be
|
||||
applied to indications or loopback messages
|
||||
|
||||
• FLOW_CONTROL_FILTERs must not be used and shall cause the interface to return
|
||||
ERR_INVALID_FILTER_ID
|
||||
|
||||
• Both pMaskMsg and pPatternMsg must have the same DataSize and TxFlags. Otherwise, the
|
||||
interface shall return ERR_INVALID_MSG
|
||||
|
||||
• The default filter behavior after PassThruConnect is to block all messages, which means no messages
|
||||
will be placed in the receive queue until a PASS_FILTER has been set. Messages that match a
|
||||
PASS_FILTER can still be blocked by a BLOCK_FILTER
|
||||
|
||||
• Figure 16 and Figure 17 show how the message filtering mechanism operates
|
||||
|
||||
For ISO 15765:
|
||||
• PASS_FILTERs and BLOCK_FILTERs must not be used and shall cause the interface to return
|
||||
ERR_INVALID_FILTER_ID
|
||||
|
||||
• Filters shall not be applied to indications or loopback messages. When loopback is on, the original
|
||||
message shall be copied to the receive queue upon the last segment being transmitted on the bus.
|
||||
|
||||
• Non-segmented messages do not need to match a FLOW_CONTROL_FILTER.
|
||||
|
||||
• No segmented messages can be transmitted without matching an appropriate FLOW_CONTROL_FILTER.
|
||||
An appropriate filter is one in which the pFlowControlMsg CAN ID matches the messages to be
|
||||
transmitted. Also, the ISO 15765_ADDR_TYPE (reference TxFlags in Section 8.7.3) bits must match.
|
||||
If that bit is set, the first byte after the CAN IDs (the extended address)
|
||||
must match too.
|
||||
|
||||
• No message (segmented or unsegmented) shall be received without matching an appropriate
|
||||
FLOW_CONTROL_FILTER. An appropriate filter is one in which the pPatternMsg CAN ID matches
|
||||
the incoming message ID. If the ISO 15765_ADDR_TYPE (reference TxFlags in Section 8.7.3) bit is
|
||||
set in the filter, the first byte after the CAN IDs (the extended address) must match too.
|
||||
|
||||
• All 3 message pointers must have the same DataSize and TxFlags. Otherwise, the interface shall
|
||||
return ERR_INVALID_MSG.
|
||||
|
||||
• Both the pFlowControlMsg ID and the pPatternMsg ID must be unique (not match any IDs in any other
|
||||
filters). The only exception is that pPatternMsg can equal pFlowControlMsg to allow for receiving
|
||||
functionally addressed messages. In this case, only non-segmented messages can be received.
|
||||
|
||||
• See Appendix A for a detailed description of flow control filter usage.
|
||||
|
||||
|
||||
|
||||
|
||||
8.4 Format Checks for Messages Passed to the API
|
||||
The vendor DLL shall validate all PASSTHRU_MSG structures, and return an ERR_INVALID_MSG in the following cases:
|
||||
• DataSize violates Min Tx or Max Tx columns in Figure 42
|
||||
|
||||
• Source address (Data[3]) is different from the Node ID (Ioctl SET_CONFIG, Parameter NODE_ADDRESS) on J1850PWM
|
||||
|
||||
• The header length field is incorrect for the number of bytes in the message on ISO14230
|
||||
|
||||
• The CAN_29_BIT flag of the message does not match the CAN_29_BIT flag passed to
|
||||
PassThruConnect, unless the CAN_ID_BOTH bit was set on connect
|
||||
|
||||
The vendor DLL shall return ERR_MSG_PROTOCOL_ID when the ProtocolID field in the message does
|
||||
not match the Protocol ID specified when opening the channel.
|
||||
|
||||
|
||||
|
||||
8.5 Conventions for Returning Messages from the API
|
||||
When returning a message in PassThruReadMsg:
|
||||
– DataSize shall tell the application how many bytes in the Data array are valid. ExtraDataIndex will be
|
||||
the (non-zero) index of the last byte of the message. If ExtraDataIndex is not equal to DataSize there
|
||||
are extra data bytes after the message. If loopback is on, RxStatus must be consulted to tell if the
|
||||
message came via loopback.
|
||||
|
||||
– DataSize will be in the range shown in the Min Rx and Max Rx columns of Figure 42. If the device
|
||||
receives a message from the vehicle bus that is too long or too short, the message shall be discarded
|
||||
with no error.
|
||||
|
||||
– For received messages, ExtraDataIndex shall be equal to DataSize, except when the interface is
|
||||
returning SAE J1850 PWM IFR bytes. In no case shall ExtraDataIndex be larger than DataSize.
|
||||
|
||||
– When receiving a message on an SAE J1850 PWM channel, the message shall have any IFR bytes
|
||||
appended. In this case, ExtraDataIndex shall be the index of the first IFR byte, and DataSize shall be
|
||||
the total length of the original message plus all IFR bytes. For example, if there are two IFR bytes,
|
||||
DataSize will be incremented by two, and ExtraDataIndex will be DataSize - 2. When loopback is on,
|
||||
the loopback message shall contain any IFR bytes.
|
||||
|
||||
|
||||
|
||||
8.6 Conventions for Retuning Indications from the API
|
||||
When returning an indication in PassThruReadMsg:
|
||||
– ExtraDataIndex must be zero
|
||||
|
||||
– DataSize shall tell the application how many bytes in the Data array are valid
|
||||
|
||||
– RxStatus must be consulted to determine the indication type (See Section 8.4).
|
||||
|
||||
– A TxDone indication (ISO 15765 only) is generated by the DLL after a SingleFrame message is sent,
|
||||
or the last frame of a multi-segment transmission is sent. DataSize shall be 4 (or 5 when the message
|
||||
was using Extended Addressing). Data shall contain the CAN ID (and possible Extended Address) of
|
||||
the message just sent. If loopback is on, the TxDone indication shall precede the loopback message in
|
||||
the receive queue.
|
||||
|
||||
– An RxBreak indication (SAE J2610/SCI and SAE J1850VPW only) is generated by the DLL if a break
|
||||
is received.
|
||||
|
||||
– An RxStart indication is generated by the DLL when starting to receive a message on ISO9141 or
|
||||
ISO14230, or when receiving the FirstFrame signal of a multi-segment ISO 15765 message.
|
||||
|
||||
|
||||
|
||||
9.1 Naming of Files
|
||||
Each vendor will provide a different name implementation of the API DLL and a number of these
|
||||
implementations could simultaneously reside on the same PC. No vendor shall name its implementation
|
||||
“J2534.DLL”. All implementations shall have the string “32” suffixed to end of the name of the API DLL to
|
||||
indicate 32-bit. For example, if the company name is “Vendor X” the name could be VENDRX32.DLL.
|
||||
|
||||
For simplicity, an API DLL shall be named in accordance with the file allocation table (FAT) file system
|
||||
naming convention (which allows up to eight characters for the file name and three characters for the
|
||||
extension with no spaces anywhere). Note that, given this criteria, the major name of an API DLL can be
|
||||
no greater than six characters. The OEM application can determine the name of the appropriate vendor’s
|
||||
DLL using the Win32 Registry mechanism described in this section.
|
||||
|
||||
|
||||
|
||||
|
||||
A.1 Flow Control Overview
|
||||
ISO 15765-2 was designed to send blocks of up to 4095 bytes on top of the limited 8-byte payload of raw
|
||||
CAN frames. If the data is small enough, it can fit in a single frame and be transmitted like a raw CAN
|
||||
message with additional headers. Otherwise, the block is broken up into segments and becomes a
|
||||
segmented transmission, generating CAN frames in both directions. For flexibility, the receiver of the
|
||||
segments can control the rate at which the segments are sent.
|
||||
|
||||
Each transmission is actually part of a conversation between two nodes. There is no discovery
|
||||
mechanism for conversation partners. Therefore, each desired conversation must be pre-defined on each
|
||||
side before the conversation can start. Conversations are symmetric, meaning that either side can send a
|
||||
block of data to the other. A conversation can only have one transfer (in one direction) in progress at a
|
||||
time. One transfer must complete before the next transfer (in the same or in a different direction) can
|
||||
start. The device must support multiple transfers at once, as long as each one is part of a different
|
||||
conversation. Raw CAN frames are not allowed when using ISO15765-2.
|
||||
|
||||
A key feature of a conversation is that each side has a unique CAN ID, and each side uses their unique
|
||||
CAN ID for all transmissions during the conversation. No other CAN IDs are part of the conversation.
|
||||
Even though the useful data is only flowing in one direction, both sides are transmitting. One side is
|
||||
sending the flow control message to pace the segments of data coming from the other side.
|
||||
|
||||
For example, during OBD communication, a pass-thru device and an ECU might have a conversation.
|
||||
The pass-thru device will use the "Tester1" physical CAN ID ($241), and the first ECU will use the
|
||||
"ECU1" physical CAN ID ($641). During a multi-segment transfer, both sides will be transmitting using
|
||||
only their respective IDs. It does not matter if the data is being sent by the ECU or by the Tester, the IDs
|
||||
remain the same.
|
||||
|
||||
It is important to understand the difference between OBD Requests/Responses and ISO 15765-2
|
||||
transfers. The OBD Request is transmitted from the Tester to the ECU using functional addressing.
|
||||
Because segmented transfer is not possible on functional addresses, the message must fit in a single
|
||||
frame. The OBD Response is a message from the ECU to the Tester using physical addressing. Unlike
|
||||
other protocols, the responses are not sequential. In fact, the responses can overlap, as if each ECU
|
||||
were having a private conversation with the Tester. Some of the responses may fit in a single frame,
|
||||
while others will require a segmented transfer from the ECU to the tester.
|
||||
|
||||
|
||||
A.2 Transmitting a Segmented Message
|
||||
When PassThruWrite is called, the API will search the list of flow control filters, looking for a
|
||||
pFlowControlMsg that matches the CAN ID (and possible extended address) of the message being sent.
|
||||
Upon matching a filter, the pass-thru device will:
|
||||
|
||||
• Start the ISO 15765 transfer by sending a FirstFrame on the bus. The CAN ID of this segment was
|
||||
specified in both the message and the matching pFlowControlMsg. In our example, this is $241.
|
||||
|
||||
• Wait for a FlowControl frame from the conversation partner. The CAN ID to look for is specified in the
|
||||
corresponding pPatternMsg. In our example, this is $641.
|
||||
|
||||
• Transmit the message data in ConsecutiveFrames according to the FlowControl frame’s instructions
|
||||
for BS (BlockSize) and STmin (SeparationTime minimum). Again, the pass-thru device transmits using
|
||||
CAN ID specified in pFlowControlMsg. In our example, this is $241.
|
||||
|
||||
• Repeat the previous two steps as required.
|
||||
|
||||
• When finished, the pass-thru device will place a TxDone indication in the API receive queue. The data
|
||||
will contain the CAN ID specified in pFlowControlMsg. In our example, this is $241.
|
||||
|
||||
• If loopback is on, the entire message sent will appear in the API receive queue with the
|
||||
TX_MSG_TYPE bit set to 1 in RxStatus. The loopback shall not precede the TxDone indication.
|
||||
|
||||
Before any multi-segment transfer can take place, the conversation must be set up on both sides. It’s
|
||||
assumed that the ECU is already setup. The application is responsible for setting up the pass-thru device.
|
||||
This setup must be done once (and only once) per conversation. The setup involves a single call to
|
||||
PassThruStartMsgFilter, with the following parameters:
|
||||
|
||||
A.2.2 Data Transmission
|
||||
Once the conversation is set up, any number of messages (to the conversation partner) can be
|
||||
transmitted using PassThruWriteMsg. The interface shall handle all aspects of the transfer, including
|
||||
pacing (slowing) the transmission to the requirements of the receiver.
|
||||
|
||||
When there are multiple conversations setup, the pass-thru device will search all of the flow control filters
|
||||
for a matching pFlowControlMsg. If there is no match, the message cannot be sent because the pass-
|
||||
thru device doesn’t know which partner will be pacing the conversation.
|
||||
|
||||
When doing blocking writes, it is important to pick a timeout long enough to cover entire transfer, even if
|
||||
the ECU is pacing things slowly. Otherwise PassThruWriteMsg will return with a timeout, even though the
|
||||
transmission is proceeding normally.
|
||||
|
||||
|
||||
A.3 Transmitting an Unsegmented Message
|
||||
As a special case, transfers that fit in a single frame can be transmitted without setting up a conversation.
|
||||
This is useful during an OBD Request, which is a functionally addressed message that is broadcast to all
|
||||
ECUs. This message must be small enough to fit into a single frame (including headers) because it is not
|
||||
possible to do one segmented transfer to multiple ECUs.
|
||||
|
||||
When using functional addressing for an OBD Request, it is important to remember that there can be no
|
||||
direct reply. Instead, each ECU will send their OBD Response using physical addressing to their
|
||||
conversation partner (e.g. ECU1 to Tester1, ECU2 to Tester2) as defined by ISO 15765-4. The OBD
|
||||
Response may be a segmented transfer, or it may be a single frame.
|
||||
|
||||
In this case, no conversation setup is necessary. The call to PassThruWriteMsg is the same as above,
|
||||
except that the DataSize must be 7 bytes or less (6 bytes or less if extended addressing is turned on).
|
||||
The pass-thru device will automatically insert a PCI byte before transmission.
|
||||
|
||||
|
||||
A.4 Receiving a Segmented Message
|
||||
Message reception is asynchronous to the application. When a FirstFrame is seen on the bus, the pass-
|
||||
thru device will search the list of flow control filters, looking for a pPatternMsg message with the same
|
||||
CAN ID (and possible extended address) as the FirstFrame. Upon matching a filter, the pass-thru device will:
|
||||
|
||||
• Place an RxStart indication in the API receive queue. This indication has the START_OF_MESSAGE
|
||||
bit set in RxFlags. The message data will contain the CAN ID of the sender. In our example, this is
|
||||
$641. DataSize will be 4 bytes (5 with extended addressing), and ExtraDataIndex will be zero.
|
||||
|
||||
• Send a FlowControl frame to the conversation partner. The FlowStatus field shall be set to
|
||||
ontinueToSend. The CAN ID of this segment comes from the filter’s corresponding
|
||||
pFlowControlMsg. In our example, this CAN ID is $241. The BS (BlockSize) and STmin
|
||||
(SeparationTime minimum) parameters default to zero, but can be changed with the SET_CONFIGIoctl.
|
||||
|
||||
• Wait for the conversation partner to send C
|
||||
onsecutiveFrames containing the actual data. The
|
||||
partner’s CAN ID is specified in pPatternMsg. In our example, this CAN ID is $641.
|
||||
|
||||
• Repeat as necessary until the entire block has been received. When finished, the pass-thru device will
|
||||
put the assembled message into the API receive queue. The CAN ID of the assembled message will
|
||||
be the CAN ID of the sender. In our example, this CAN ID is $641.
|
||||
|
||||
If the FirstFrame does not match any flow control filters, then the message must be ignored by the
|
||||
device.
|
||||
|
||||
Segmented messages cause the API to generate an RxStart indication. This lets the application know
|
||||
that the device has started message reception. It may take a while before message reception is
|
||||
complete, especially if the application has increased BS and STmin.
|
||||
|
||||
Once the transfer is complete, the entire message can be read like on any other protocol. Usually,
|
||||
applications will call PassThruReadMsg again immediately after getting an RxStart indication. Application
|
||||
writers should not assume that the complete message will always follow the RxStart indication. If multiple
|
||||
conversations are setup, indications and messages from other conversations can be received in between
|
||||
the RxStart indication and the actual message. The parameters for PassThruReadMsg are exactly the
|
||||
same as in the previous section. The only difference is that the DataSize will be larger and
|
||||
ExtraDataIndex will be non-zero.
|
||||
|
||||
|
||||
|
||||
A.5 Receiving an Unsegmented Message
|
||||
No messages can be received until a conversation is setup. Each conversation setup will receive
|
||||
messages from exactly one CAN ID (and extended address if present). Because setup is bi-directional,
|
||||
the same PassThruStartMsgFilter call used for transmission will allow for message reception.
|
||||
|
||||
When a SingleFrame is seen on the bus, the pass-thru device will search the list of flow control filters,
|
||||
looking for a pPatternMsg message with the same C
|
||||
AN ID (and possible extended address) as the
|
||||
SingleFrame. Upon matching a filter, the pass-thru device will strip the PCI byte and queue the packet for
|
||||
reception. If the SingleFrame does not match a flow control filter, it must be discarded.
|
||||
|
||||
The only difference between the previous cases is that single-frame messages do not generate an
|
||||
RxStart indication.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 67 KiB |
@@ -1,2 +0,0 @@
|
||||
#32 bit: HKEY_LOCAL_MACHINE\SOFTWARE\PassThruSupport
|
||||
#64 bit: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\PassThruSupport
|
||||
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 45 KiB |
@@ -1,42 +0,0 @@
|
||||
From focum information on NI hardware: https://forums.ni.com/t5/Automotive-and-Embedded-Networks/15765-2-with-NI-products/td-p/1454256
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
Timeout Diag Command is the timeout in milliseconds the master
|
||||
waits for the response to a diagnostic request message. The default is
|
||||
1000 ms.
|
||||
|
||||
Timeout FC (Bs) is the timeout in milliseconds the master waits
|
||||
for a Flow Control frame after sending a First Frame or the last
|
||||
Consecutive Frame of a block. The default is 250 ms.
|
||||
|
||||
Timeout CF (Cr) is the timeout in milliseconds the master waits
|
||||
for a Consecutive Frame in a multiframe response. The default is
|
||||
250 ms.
|
||||
|
||||
Receive Block Size (BS) is the number of Consecutive Frames the
|
||||
slave sends in one block before waiting for the next Flow Control
|
||||
frame. A value of 0 (default) means all Consecutive Frames are sent
|
||||
in one run without interruption.
|
||||
|
||||
Wait Time CF (STmin) defines the minimum time for the slave to
|
||||
wait between sending two Consecutive Frames of a block. Values
|
||||
from 0 to 127 are wait times in milliseconds. Values 241 to 249
|
||||
(Hex F1 to F9) mean wait times of 100 μs to 900 μs, respectively.
|
||||
All other values are reserved. The default is 5 ms.
|
||||
|
||||
Max Wait Frames (N_WFTmax) is the maximum number of WAIT
|
||||
frames the master accepts before terminating the connection. The
|
||||
default is 10.
|
||||
|
||||
|
||||
There are no defined lower limits for these values; you can specify any
|
||||
value down to 0. However, as you correctly pointed out, the timing is
|
||||
done by Windows, and will be subject to the jitter introduced by the OS
|
||||
which can easily be in the order of 10s of milliseconds. It is however
|
||||
hard to give more accurate numbers as the actual jitter is dependent on
|
||||
the workload of the computer
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
J2534 04.04 does not appear to have default adjustable parameters for
|
||||
the timeout related fields. For now, these default values shall be used
|
||||
in the Panda J2534 implementation.
|
||||
@@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BD34DB24-F5DC-4992-A74F-05FAF731ABED}</ProjectGuid>
|
||||
<TemplateGuid>{a1357fe7-03e0-4d61-85f4-09c7ed38c0c1}</TemplateGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>$driverCurrentWindowsConfigurationName$ Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<RootNamespace>panda_Driver_Package</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<DriverType>Package</DriverType>
|
||||
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<DriverType>Package</DriverType>
|
||||
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<!-- Debug the associated application, not the WinUSB driver -->
|
||||
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
|
||||
<HardwareIdString />
|
||||
<CommandLine />
|
||||
<DeployFiles />
|
||||
<EnableVerifier>False</EnableVerifier>
|
||||
<AllDrivers>False</AllDrivers>
|
||||
<VerifyProjectOutput>True</VerifyProjectOutput>
|
||||
<VerifyDrivers />
|
||||
<VerifyFlags>133563</VerifyFlags>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<!-- Debug the associated application, not the WinUSB driver -->
|
||||
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
|
||||
<HardwareIdString />
|
||||
<CommandLine />
|
||||
<DeployFiles />
|
||||
<EnableVerifier>False</EnableVerifier>
|
||||
<AllDrivers>False</AllDrivers>
|
||||
<VerifyProjectOutput>True</VerifyProjectOutput>
|
||||
<VerifyDrivers />
|
||||
<VerifyFlags>133563</VerifyFlags>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="panda.inf" />
|
||||
<!-- Explicitly set all FilesToPackage since there is no dependency on a driver -->
|
||||
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
|
||||
<FilesToPackage Condition="$(KMDF_VERSION_MAJOR) == 1 and $(KMDF_VERSION_MINOR) < 13" Include="$(WDKContentRoot)redist\wdf\$(DDKPlatform)\WdfCoinstaller$(KMDF_VERSION_MAJOR_STRING)$(KMDF_VERSION_MINOR_STRING).dll" />
|
||||
</ItemGroup>
|
||||
<!-- INF handling depends on order. Some of the above ImportGroup nodes set up INF handling. -->
|
||||
<!-- Modify INF handling here. -->
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Inf>
|
||||
<!-- The WinUSB driver requires KMDF, so we must provide a KMDF version number in the INF. -->
|
||||
<!-- Use the user's KMDF setting (defaults to latest) -->
|
||||
<KmdfVersionNumber>$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)</KmdfVersionNumber>
|
||||
</Inf>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Inf>
|
||||
<!-- The WinUSB driver requires KMDF, so we must provide a KMDF version number in the INF. -->
|
||||
<!-- Use the user's KMDF setting (defaults to latest) -->
|
||||
<KmdfVersionNumber>$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)</KmdfVersionNumber>
|
||||
</Inf>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Driver Files">
|
||||
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
|
||||
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="panda.inf">
|
||||
<Filter>Driver Files</Filter>
|
||||
</Inf>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 95 KiB |
@@ -1,92 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2027
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pandaJ2534DLL", "pandaJ2534DLL\pandaJ2534DLL.vcxproj", "{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "panda", "panda\panda.vcxproj", "{5528AEFB-638D-49AF-B9D4-965154E7D531}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "panda_playground", "panda_playground\panda_playground.vcxproj", "{691DB635-C272-4B98-897E-0505B970DCA9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531} = {5528AEFB-638D-49AF-B9D4-965154E7D531}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "panda Driver Package", "panda Driver Package\panda Driver Package.vcxproj", "{BD34DB24-F5DC-4992-A74F-05FAF731ABED}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tests", "pandaJ2534DLL Test\pandaJ2534DLL Test.vcxproj", "{7912F978-B48C-4C5D-8BFD-5D1E22158E47}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ECUsim DLL", "ECUsim DLL\ECUsim DLL.vcxproj", "{96E0E646-EE76-444D-9A77-A0CD7F781DEB}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ECUsim CLI", "ECUsim CLI\ECUsim CLI.vcxproj", "{D99E2FCD-21A4-4065-949A-31E34E0E69D1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "panda_shared", "panda_shared\panda_shared.vcxitems", "{0C843279-68C7-4679-AE51-9BC463D50D1C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
panda_shared\panda_shared.vcxitems*{0c843279-68c7-4679-ae51-9bc463d50d1c}*SharedItemsImports = 9
|
||||
panda_shared\panda_shared.vcxitems*{5528aefb-638d-49af-b9d4-965154e7d531}*SharedItemsImports = 4
|
||||
panda_shared\panda_shared.vcxitems*{a2bb18a5-f26b-48d6-bbb5-b83d64473c77}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}.Release|x64.ActiveCfg = Release|Win32
|
||||
{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}.Release|x86.Build.0 = Release|Win32
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Debug|x64.Build.0 = Debug|x64
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Debug|x86.Build.0 = Debug|Win32
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Release|x64.ActiveCfg = Release|x64
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Release|x64.Build.0 = Release|x64
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Release|x86.ActiveCfg = Release|Win32
|
||||
{5528AEFB-638D-49AF-B9D4-965154E7D531}.Release|x86.Build.0 = Release|Win32
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Debug|x64.Build.0 = Debug|x64
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Debug|x86.Build.0 = Debug|Win32
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Release|x64.ActiveCfg = Release|x64
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Release|x64.Build.0 = Release|x64
|
||||
{691DB635-C272-4B98-897E-0505B970DCA9}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BD34DB24-F5DC-4992-A74F-05FAF731ABED}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{BD34DB24-F5DC-4992-A74F-05FAF731ABED}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BD34DB24-F5DC-4992-A74F-05FAF731ABED}.Release|x64.ActiveCfg = Release|Win32
|
||||
{BD34DB24-F5DC-4992-A74F-05FAF731ABED}.Release|x86.ActiveCfg = Release|Win32
|
||||
{7912F978-B48C-4C5D-8BFD-5D1E22158E47}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{7912F978-B48C-4C5D-8BFD-5D1E22158E47}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{7912F978-B48C-4C5D-8BFD-5D1E22158E47}.Debug|x86.Build.0 = Debug|Win32
|
||||
{7912F978-B48C-4C5D-8BFD-5D1E22158E47}.Release|x64.ActiveCfg = Release|Win32
|
||||
{7912F978-B48C-4C5D-8BFD-5D1E22158E47}.Release|x86.ActiveCfg = Release|Win32
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Debug|x64.Build.0 = Debug|x64
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Release|x64.ActiveCfg = Release|x64
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Release|x64.Build.0 = Release|x64
|
||||
{96E0E646-EE76-444D-9A77-A0CD7F781DEB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Debug|x64.Build.0 = Debug|x64
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Release|x64.ActiveCfg = Release|x64
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Release|x64.Build.0 = Release|x64
|
||||
{D99E2FCD-21A4-4065-949A-31E34E0E69D1}.Release|x86.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8AF3826E-406A-4F1C-BA80-B4D7FD4B52E1}
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,19 +0,0 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "stdafx.h"
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
LONG __cdecl
|
||||
_tmain(
|
||||
LONG Argc,
|
||||
LPTSTR * Argv
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine description:
|
||||
|
||||
Sample program that communicates with a USB device using WinUSB
|
||||
|
||||
--*/
|
||||
{
|
||||
DEVICE_DATA deviceData;
|
||||
HRESULT hr;
|
||||
USB_DEVICE_DESCRIPTOR deviceDesc;
|
||||
BOOL bResult;
|
||||
BOOL noDevice;
|
||||
ULONG lengthReceived;
|
||||
|
||||
UNREFERENCED_PARAMETER(Argc);
|
||||
UNREFERENCED_PARAMETER(Argv);
|
||||
|
||||
//
|
||||
// Find a device connected to the system that has WinUSB installed using our
|
||||
// INF
|
||||
//
|
||||
hr = OpenDevice(&deviceData, &noDevice);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
|
||||
if (noDevice) {
|
||||
|
||||
printf(_T("Device not connected or driver not installed\n"));
|
||||
|
||||
} else {
|
||||
|
||||
printf(_T("Failed looking for device, HRESULT 0x%x\n"), hr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Get device descriptor
|
||||
//
|
||||
bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle,
|
||||
USB_DEVICE_DESCRIPTOR_TYPE,
|
||||
0,
|
||||
0,
|
||||
(PBYTE) &deviceDesc,
|
||||
sizeof(deviceDesc),
|
||||
&lengthReceived);
|
||||
|
||||
if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {
|
||||
|
||||
printf(_T("Error among LastError %d or lengthReceived %d\n"),
|
||||
FALSE == bResult ? GetLastError() : 0,
|
||||
lengthReceived);
|
||||
CloseDevice(&deviceData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Print a few parts of the device descriptor
|
||||
//
|
||||
printf(_T("Device found: VID_%04X&PID_%04X; bcdUsb %04X; path: %s\n"),
|
||||
deviceDesc.idVendor,
|
||||
deviceDesc.idProduct,
|
||||
deviceDesc.bcdUSB,
|
||||
deviceData.DevicePath);
|
||||
|
||||
CloseDevice(&deviceData);
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 95 KiB |
@@ -1,189 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5528AEFB-638D-49AF-B9D4-965154E7D531}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>panda</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
<Import Project="..\panda_shared\panda_shared.vcxitems" 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)'=='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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PANDA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</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;%(AdditionalDependencies);winusb.lib;setupapi.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;PANDA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</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;%(AdditionalDependencies);winusb.lib;setupapi.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PANDA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);winusb.lib;setupapi.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;PANDA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);winusb.lib;setupapi.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="panda.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="panda.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="panda.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="panda.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// panda.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -1,19 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#endif
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <strsafe.h>
|
||||
#include <winusb.h>
|
||||
#include <usb.h>
|
||||
@@ -1,87 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "Loader4.h"
|
||||
#include "pandaJ2534DLL/J2534_v0404.h"
|
||||
#include "panda_shared/panda.h"
|
||||
#include "Timer.h"
|
||||
#include "ECUsim DLL\ECUsim.h"
|
||||
#include "TestHelpers.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace pandaWCUsimTest
|
||||
{
|
||||
|
||||
TEST_CLASS(ECUsimTests)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(ECUsim_ISO15765_SingleFrameTx_29bStandardAddrPad500k)
|
||||
{
|
||||
ECUsim sim("", 500000);
|
||||
auto p = getPanda(500);
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x02\x01\x00", 3, panda::PANDA_CAN1);
|
||||
auto msg_recv = panda_recv_loop(p, 2);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x02\x01\x00", 3), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x06\x41\x00\xff\xff\xff\xfe\x00", 8), LINE_INFO());
|
||||
}
|
||||
|
||||
TEST_METHOD(ECUsim_ISO15765_SingleFrameTx_29bStandardAddrPad250k)
|
||||
{
|
||||
ECUsim sim("", 250000);
|
||||
auto p = getPanda(250);
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x02\x01\x00", 3, panda::PANDA_CAN1);
|
||||
auto msg_recv = panda_recv_loop(p, 2);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x02\x01\x00", 3), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x06""\x41\x00""\xff\xff\xff\xfe""\x00", 8), LINE_INFO());
|
||||
}
|
||||
|
||||
TEST_METHOD(ECUsim_ISO15765_SingleFrameTx_29bExtAddrPad500k)
|
||||
{
|
||||
ECUsim sim("", 500000, TRUE);
|
||||
auto p = getPanda(500);
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x13""\x02\x01\x00", 4, panda::PANDA_CAN1);
|
||||
auto msg_recv = panda_recv_loop(p, 2);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x13""\x02\x01\x00", 4), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x13""\x06""\x41\x00""\xff\xff\xff\xfe", 8), LINE_INFO());
|
||||
}
|
||||
|
||||
TEST_METHOD(ECUsim_ISO15765_MultiFrameTx_29bStandardAddrPad500k)
|
||||
{
|
||||
ECUsim sim("", 500000);
|
||||
auto p = getPanda(500);
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x02\x09\x02", 3, panda::PANDA_CAN1);
|
||||
auto msg_recv = panda_recv_loop(p, 2);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x02\x09\x02", 3), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x10\x14""\x49\x02\x01""1D4", 8), LINE_INFO());
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x30\x00\x00", 3, panda::PANDA_CAN1);
|
||||
msg_recv = panda_recv_loop(p, 3);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x30\x0\x0", 3), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x21""GP00R55", 8), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[2], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x22""B123456", 8), LINE_INFO());
|
||||
}
|
||||
|
||||
TEST_METHOD(ECUsim_ISO15765_MultiFrameTx_29bExtAddrPad500k)
|
||||
{
|
||||
ECUsim sim("", 500000, TRUE);
|
||||
auto p = getPanda(500);
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x13""\x02\x09\x02", 4, panda::PANDA_CAN1);
|
||||
auto msg_recv = panda_recv_loop(p, 2);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x13""\x02\x09\x02", 4), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x13""\x10\x14""\x49\x02\x01""1D", 8), LINE_INFO());
|
||||
|
||||
p->can_send(0x18daeff1, TRUE, (const uint8_t*)"\x13""\x30\x00\x00", 4, panda::PANDA_CAN1);
|
||||
msg_recv = panda_recv_loop(p, 4);
|
||||
check_panda_can_msg(msg_recv[0], 0, 0x18daeff1, TRUE, TRUE, std::string("\x13""\x30\x0\x0", 4), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[1], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x13""\x21""4GP00R", 8), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[2], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x13""\x22""55B123", 8), LINE_INFO());
|
||||
check_panda_can_msg(msg_recv[3], 0, 0x18daf1ef, TRUE, FALSE, std::string("\x13""\x23""456", 5), LINE_INFO());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
// Loader4.cpp
|
||||
// (c) 2005 National Control Systems, Inc.
|
||||
// Portions (c) 2004 Drew Technologies, Inc.
|
||||
// Dynamic J2534 v04.04 dll loader for VB
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to:
|
||||
// the Free Software Foundation, Inc.
|
||||
// 51 Franklin Street, Fifth Floor
|
||||
// Boston, MA 02110-1301, USA
|
||||
|
||||
// National Control Systems, Inc.
|
||||
// 10737 Hamburg Rd
|
||||
// Hamburg, MI 48139
|
||||
// 810-231-2901
|
||||
|
||||
// Drew Technologies, Inc.
|
||||
// 7012 E.M -36, Suite 3B
|
||||
// Whitmore Lake, MI 48189
|
||||
// 810-231-3171
|
||||
|
||||
#define STRICT
|
||||
#include "stdafx.h"
|
||||
#include <windows.h>
|
||||
#include "Loader4.h"
|
||||
|
||||
PTOPEN LocalOpen;
|
||||
PTCLOSE LocalClose;
|
||||
PTCONNECT LocalConnect;
|
||||
PTDISCONNECT LocalDisconnect;
|
||||
PTREADMSGS LocalReadMsgs;
|
||||
PTWRITEMSGS LocalWriteMsgs;
|
||||
PTSTARTPERIODICMSG LocalStartPeriodicMsg;
|
||||
PTSTOPPERIODICMSG LocalStopPeriodicMsg;
|
||||
PTSTARTMSGFILTER LocalStartMsgFilter;
|
||||
PTSTOPMSGFILTER LocalStopMsgFilter;
|
||||
PTSETPROGRAMMINGVOLTAGE LocalSetProgrammingVoltage;
|
||||
PTREADVERSION LocalReadVersion;
|
||||
PTGETLASTERROR LocalGetLastError;
|
||||
PTIOCTL LocalIoctl;
|
||||
|
||||
HINSTANCE hDLL = NULL;
|
||||
//BOOL bIsCorrectVersion = FALSE;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstA, DWORD dwReason, LPVOID lpvReserved)
|
||||
{
|
||||
switch (dwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
// The DLL is being mapped into the process's address space
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
// A thread is being created
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
// A thread is exiting cleanly
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
// The DLL is being unmapped from the process's address space
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
long WINAPI LoadJ2534Dll(char *sLib)
|
||||
{
|
||||
long lFuncList = 0;
|
||||
|
||||
if (hDLL != NULL) UnloadJ2534Dll();
|
||||
hDLL = LoadLibraryA (sLib);
|
||||
if (hDLL == NULL) return ERR_NO_DLL;
|
||||
|
||||
LocalOpen = (PTOPEN)(GetProcAddress(hDLL, "PassThruOpen"));
|
||||
if (LocalOpen == NULL) lFuncList = lFuncList | ERR_NO_PTOPEN;
|
||||
|
||||
LocalClose = (PTCLOSE)(GetProcAddress(hDLL, "PassThruClose"));
|
||||
if (LocalClose == NULL) lFuncList = lFuncList | ERR_NO_PTCLOSE;
|
||||
|
||||
LocalConnect = (PTCONNECT)(GetProcAddress(hDLL,"PassThruConnect"));
|
||||
if (LocalConnect == NULL) lFuncList = lFuncList | ERR_NO_PTCONNECT;
|
||||
|
||||
LocalDisconnect = (PTDISCONNECT)(GetProcAddress(hDLL,"PassThruDisconnect"));
|
||||
if (LocalDisconnect == NULL) lFuncList = lFuncList | ERR_NO_PTDISCONNECT;
|
||||
|
||||
LocalReadMsgs = (PTREADMSGS)(GetProcAddress(hDLL,"PassThruReadMsgs"));
|
||||
if (LocalReadMsgs == NULL) lFuncList = lFuncList | ERR_NO_PTREADMSGS;
|
||||
|
||||
LocalWriteMsgs = (PTWRITEMSGS)(GetProcAddress(hDLL,"PassThruWriteMsgs"));
|
||||
if (LocalWriteMsgs == NULL) lFuncList = lFuncList | ERR_NO_PTWRITEMSGS;
|
||||
|
||||
LocalStartPeriodicMsg = (PTSTARTPERIODICMSG)(GetProcAddress(hDLL,"PassThruStartPeriodicMsg"));
|
||||
if (LocalStartPeriodicMsg == NULL) lFuncList = lFuncList | ERR_NO_PTSTARTPERIODICMSG;
|
||||
|
||||
LocalStopPeriodicMsg = (PTSTOPPERIODICMSG)(GetProcAddress(hDLL,"PassThruStopPeriodicMsg"));
|
||||
if (LocalStopPeriodicMsg == NULL) lFuncList = lFuncList | ERR_NO_PTSTOPPERIODICMSG;
|
||||
|
||||
LocalStartMsgFilter = (PTSTARTMSGFILTER)(GetProcAddress(hDLL,"PassThruStartMsgFilter"));
|
||||
if (LocalStartPeriodicMsg == NULL) lFuncList = lFuncList | ERR_NO_PTSTARTMSGFILTER;
|
||||
|
||||
LocalStopMsgFilter = (PTSTOPMSGFILTER)(GetProcAddress(hDLL,"PassThruStopMsgFilter"));
|
||||
if (LocalStopMsgFilter == NULL) lFuncList = lFuncList | ERR_NO_PTSTOPMSGFILTER;
|
||||
|
||||
LocalSetProgrammingVoltage = (PTSETPROGRAMMINGVOLTAGE)(GetProcAddress(hDLL,"PassThruSetProgrammingVoltage"));
|
||||
if (LocalSetProgrammingVoltage == NULL) lFuncList = lFuncList | ERR_NO_PTSETPROGRAMMINGVOLTAGE;
|
||||
|
||||
LocalReadVersion = (PTREADVERSION)(GetProcAddress(hDLL,"PassThruReadVersion"));
|
||||
if (LocalReadVersion == NULL) lFuncList = lFuncList | ERR_NO_PTREADVERSION;
|
||||
|
||||
LocalGetLastError = (PTGETLASTERROR)(GetProcAddress(hDLL,"PassThruGetLastError"));
|
||||
if (LocalGetLastError == NULL) lFuncList = lFuncList | ERR_NO_PTGETLASTERROR;
|
||||
|
||||
LocalIoctl = (PTIOCTL)(GetProcAddress(hDLL,"PassThruIoctl"));
|
||||
if (LocalIoctl == NULL) lFuncList = lFuncList | ERR_NO_PTIOCTL;
|
||||
|
||||
if (lFuncList == ERR_NO_FUNCTIONS) return ERR_WRONG_DLL_VER;
|
||||
|
||||
return lFuncList;
|
||||
}
|
||||
|
||||
long WINAPI UnloadJ2534Dll()
|
||||
{
|
||||
if (FreeLibrary(hDLL))
|
||||
{
|
||||
hDLL = NULL;
|
||||
LocalOpen = NULL;
|
||||
LocalClose = NULL;
|
||||
LocalConnect = NULL;
|
||||
LocalDisconnect = NULL;
|
||||
LocalReadMsgs = NULL;
|
||||
LocalWriteMsgs = NULL;
|
||||
LocalStartPeriodicMsg = NULL;
|
||||
LocalStopPeriodicMsg = NULL;
|
||||
LocalStartMsgFilter = NULL;
|
||||
LocalStopMsgFilter = NULL;
|
||||
LocalSetProgrammingVoltage = NULL;
|
||||
LocalReadVersion = NULL;
|
||||
LocalGetLastError = NULL;
|
||||
LocalIoctl = NULL;
|
||||
return 0;
|
||||
}
|
||||
return ERR_NO_DLL;
|
||||
}
|
||||
|
||||
long WINAPI PassThruOpen(void *pName, unsigned long *pDeviceID)
|
||||
{
|
||||
if (LocalOpen == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalOpen(pName, pDeviceID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruClose(unsigned long DeviceID)
|
||||
{
|
||||
if (LocalOpen == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalClose(DeviceID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruConnect(unsigned long DeviceID, unsigned long ProtocolID, unsigned long Flags, unsigned long Baudrate, unsigned long *pChannelID)
|
||||
{
|
||||
if (LocalConnect == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalConnect(DeviceID, ProtocolID, Flags, Baudrate, pChannelID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruDisconnect(unsigned long ChannelID)
|
||||
{
|
||||
if (LocalDisconnect == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalDisconnect(ChannelID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout)
|
||||
{
|
||||
if (LocalReadMsgs == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalReadMsgs(ChannelID, pMsg, pNumMsgs, Timeout);
|
||||
}
|
||||
|
||||
long WINAPI PassThruWriteMsgs(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout)
|
||||
{
|
||||
if (LocalWriteMsgs == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalWriteMsgs(ChannelID, pMsg, pNumMsgs, Timeout);
|
||||
}
|
||||
|
||||
long WINAPI PassThruStartPeriodicMsg(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pMsgID, unsigned long TimeInterval)
|
||||
{
|
||||
if (LocalStartPeriodicMsg == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalStartPeriodicMsg(ChannelID, pMsg, pMsgID, TimeInterval);
|
||||
}
|
||||
|
||||
long WINAPI PassThruStopPeriodicMsg(unsigned long ChannelID, unsigned long MsgID)
|
||||
{
|
||||
if (LocalStopPeriodicMsg == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalStopPeriodicMsg(ChannelID, MsgID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruStartMsgFilter(unsigned long ChannelID, unsigned long FilterType,
|
||||
PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg, PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID)
|
||||
{
|
||||
if (LocalStartMsgFilter == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalStartMsgFilter(ChannelID, FilterType, pMaskMsg, pPatternMsg, pFlowControlMsg, pFilterID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruStopMsgFilter(unsigned long ChannelID, unsigned long FilterID)
|
||||
{
|
||||
if (LocalStopMsgFilter == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalStopMsgFilter(ChannelID, FilterID);
|
||||
}
|
||||
|
||||
long WINAPI PassThruSetProgrammingVoltage(unsigned long DeviceID, unsigned long PinNumber, unsigned long Voltage)
|
||||
{
|
||||
if (LocalSetProgrammingVoltage == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalSetProgrammingVoltage(DeviceID, PinNumber, Voltage);
|
||||
}
|
||||
|
||||
long WINAPI PassThruReadVersion(unsigned long DeviceID, char *pFirmwareVersion, char *pDllVersion, char *pApiVersion)
|
||||
{
|
||||
if (LocalReadVersion == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalReadVersion(DeviceID, pFirmwareVersion, pDllVersion, pApiVersion);
|
||||
}
|
||||
|
||||
long WINAPI PassThruGetLastError(char *pErrorDescription)
|
||||
{
|
||||
if (LocalGetLastError == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalGetLastError(pErrorDescription);
|
||||
}
|
||||
|
||||
long WINAPI PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput)
|
||||
{
|
||||
if (LocalIoctl == NULL) return ERR_FUNC_MISSING;
|
||||
return LocalIoctl(ChannelID, IoctlID, pInput, pOutput);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Loader4.h
|
||||
// (c) 2005 National Control Systems, Inc.
|
||||
// Portions (c) 2004 Drew Technologies, Inc.
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to:
|
||||
// the Free Software Foundation, Inc.
|
||||
// 51 Franklin Street, Fifth Floor
|
||||
// Boston, MA 02110-1301, USA
|
||||
|
||||
// National Control Systems, Inc.
|
||||
// 10737 Hamburg Rd
|
||||
// Hamburg, MI 48139
|
||||
// 810-231-2901
|
||||
|
||||
// Drew Technologies, Inc.
|
||||
// 7012 E.M -36, Suite 3B
|
||||
// Whitmore Lake, MI 48189
|
||||
// 810-231-3171
|
||||
|
||||
#include "pandaJ2534DLL/J2534_v0404.h"
|
||||
|
||||
//Other Functions
|
||||
long WINAPI LoadJ2534Dll(char *);
|
||||
long WINAPI UnloadJ2534Dll();
|
||||
|
||||
// NCS Returns of any functions not found
|
||||
#define ERR_NO_PTOPEN 0x0001
|
||||
#define ERR_NO_PTCLOSE 0x0002
|
||||
#define ERR_NO_PTCONNECT 0x0004
|
||||
#define ERR_NO_PTDISCONNECT 0x0008
|
||||
#define ERR_NO_PTREADMSGS 0x0010
|
||||
#define ERR_NO_PTWRITEMSGS 0x0020
|
||||
#define ERR_NO_PTSTARTPERIODICMSG 0x0040
|
||||
#define ERR_NO_PTSTOPPERIODICMSG 0x0080
|
||||
#define ERR_NO_PTSTARTMSGFILTER 0x0100
|
||||
#define ERR_NO_PTSTOPMSGFILTER 0x0200
|
||||
#define ERR_NO_PTSETPROGRAMMINGVOLTAGE 0x0400
|
||||
#define ERR_NO_PTREADVERSION 0x0800
|
||||
#define ERR_NO_PTGETLASTERROR 0x1000
|
||||
#define ERR_NO_PTIOCTL 0x2000
|
||||
#define ERR_NO_FUNCTIONS 0x3fff
|
||||
#define ERR_NO_DLL -1
|
||||
#define ERR_WRONG_DLL_VER -2
|
||||
#define ERR_FUNC_MISSING -3
|
||||
@@ -1,254 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "TestHelpers.h"
|
||||
#include "Loader4.h"
|
||||
#include "pandaJ2534DLL/J2534_v0404.h"
|
||||
#include "panda_shared/panda.h"
|
||||
#include "Timer.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
void write_ioctl(unsigned int chanid, unsigned int param, unsigned int val, const __LineInfo* pLineInfo) {
|
||||
SCONFIG config = { param, val };
|
||||
SCONFIG_LIST inconfig = { 1, &config };
|
||||
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, PassThruIoctl(chanid, SET_CONFIG, &inconfig, NULL), _T("Failed to set IOCTL."), pLineInfo);
|
||||
}
|
||||
|
||||
std::vector<panda::PANDA_CAN_MSG> panda_recv_loop_loose(std::unique_ptr<panda::Panda>& p, unsigned int min_num, unsigned long timeout_ms) {
|
||||
std::vector<panda::PANDA_CAN_MSG> ret_messages;
|
||||
Timer t = Timer();
|
||||
|
||||
while (t.getTimePassed() < timeout_ms) {
|
||||
Sleep(10);
|
||||
std::vector<panda::PANDA_CAN_MSG>msg_recv = p->can_recv();
|
||||
if (msg_recv.size() > 0) {
|
||||
ret_messages.insert(std::end(ret_messages), std::begin(msg_recv), std::end(msg_recv));
|
||||
}
|
||||
}
|
||||
|
||||
Assert::IsTrue(min_num <= ret_messages.size(), _T("Received too few messages."));
|
||||
return ret_messages;
|
||||
}
|
||||
|
||||
std::vector<panda::PANDA_CAN_MSG> panda_recv_loop(std::unique_ptr<panda::Panda>& p, unsigned int num_expected, unsigned long timeout_ms) {
|
||||
std::vector<panda::PANDA_CAN_MSG> ret_messages;
|
||||
Timer t = Timer();
|
||||
|
||||
while (t.getTimePassed() < timeout_ms) {
|
||||
Sleep(10);
|
||||
std::vector<panda::PANDA_CAN_MSG>msg_recv = p->can_recv();
|
||||
if (msg_recv.size() > 0) {
|
||||
ret_messages.insert(std::end(ret_messages), std::begin(msg_recv), std::end(msg_recv));
|
||||
}
|
||||
if (ret_messages.size() >= num_expected) break;
|
||||
}
|
||||
|
||||
std::ostringstream stringStream;
|
||||
|
||||
stringStream << "j2534_recv_loop Broke at " << t.getTimePassed() << " ms size is " << ret_messages.size() << std::endl;
|
||||
|
||||
if (num_expected != ret_messages.size()) {
|
||||
stringStream << "Incorrect number of messages received. Displaying the messages:" << std::endl;
|
||||
for (auto msg : ret_messages) {
|
||||
stringStream << " TS: " << msg.recv_time << "; Dat: ";
|
||||
for (int i = 0; i < msg.len; i++) stringStream << std::hex << std::setw(2) << std::setfill('0') << int(msg.dat[i] & 0xFF) << " ";
|
||||
stringStream << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::WriteMessage(stringStream.str().c_str());
|
||||
|
||||
Assert::AreEqual<unsigned long>(num_expected, ret_messages.size(), _T("Received wrong number of messages."));
|
||||
return ret_messages;
|
||||
}
|
||||
|
||||
void check_panda_can_msg(panda::PANDA_CAN_MSG& msgin, uint8_t bus, unsigned long addr, bool addr_29b,
|
||||
bool is_receipt, std::string dat, const __LineInfo* pLineInfo) {
|
||||
Assert::AreEqual<uint8_t>(bus, msgin.bus, _T("Wrong msg bus"), pLineInfo);
|
||||
Assert::AreEqual<unsigned long>(addr, msgin.addr, _T("Wrong msg addr"), pLineInfo);
|
||||
Assert::AreEqual<bool>(addr_29b, msgin.addr_29b, _T("Wrong msg 29b flag"), pLineInfo);
|
||||
Assert::AreEqual<bool>(is_receipt, msgin.is_receipt, _T("Wrong msg receipt flag"), pLineInfo);
|
||||
|
||||
std::ostringstream logmsg;
|
||||
logmsg << "Expected Hex (";
|
||||
for (int i = 0; i < dat.size(); i++) logmsg << std::hex << std::setw(2) << std::setfill('0') << int(dat[i] & 0xFF) << " ";
|
||||
logmsg << "); Actual Hex (";
|
||||
for (int i = 0; i < msgin.len; i++) logmsg << std::hex << std::setw(2) << std::setfill('0') << int(((char*)msgin.dat)[i] & 0xFF) << " ";
|
||||
logmsg << ")";
|
||||
Logger::WriteMessage(logmsg.str().c_str());
|
||||
|
||||
Assert::AreEqual<size_t>(dat.size(), msgin.len, _T("Wrong msg len"), pLineInfo);
|
||||
Assert::AreEqual<std::string>(dat, std::string((char*)msgin.dat, msgin.len), _T("Wrong msg payload"), pLineInfo);
|
||||
}
|
||||
|
||||
unsigned long J2534_start_periodic_msg_checked(unsigned long chanid, unsigned long ProtocolID, unsigned long TxFlags, unsigned long DataSize,
|
||||
unsigned long ExtraDataIndex, const char * Data, unsigned long TimeInterval, const __LineInfo * pLineInfo) {
|
||||
PASSTHRU_MSG msg = { ProtocolID, 0, TxFlags, 0, DataSize, ExtraDataIndex };
|
||||
memcpy_s(msg.Data, 4128, Data, DataSize);
|
||||
unsigned long msgID;
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, J2534_start_periodic_msg(chanid, ProtocolID, TxFlags, DataSize,
|
||||
ExtraDataIndex, Data, TimeInterval, &msgID, pLineInfo), _T("Failed to start Periodic Message."), pLineInfo);
|
||||
return msgID;
|
||||
}
|
||||
|
||||
unsigned long J2534_start_periodic_msg(unsigned long chanid, unsigned long ProtocolID, unsigned long TxFlags, unsigned long DataSize,
|
||||
unsigned long ExtraDataIndex, const char * Data, unsigned long TimeInterval, unsigned long* msgID, const __LineInfo * pLineInfo) {
|
||||
PASSTHRU_MSG msg = { ProtocolID, 0, TxFlags, 0, DataSize, ExtraDataIndex };
|
||||
memcpy_s(msg.Data, 4128, Data, DataSize);
|
||||
return PassThruStartPeriodicMsg(chanid, &msg, msgID, TimeInterval);
|
||||
}
|
||||
|
||||
void J2534_send_msg_checked(unsigned long chanid, unsigned long ProtocolID, unsigned long RxStatus, unsigned long TxFlags,
|
||||
unsigned long Timestamp, unsigned long DataSize, unsigned long ExtraDataIndex, const char* Data, const __LineInfo* pLineInfo) {
|
||||
|
||||
PASSTHRU_MSG msg = { ProtocolID, RxStatus, TxFlags, Timestamp, DataSize, ExtraDataIndex };
|
||||
memcpy_s(msg.Data, 4128, Data, DataSize);
|
||||
unsigned long msgcount = 1;
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, PassThruWriteMsgs(chanid, &msg, &msgcount, 0), _T("Failed to write message."), pLineInfo);
|
||||
Assert::AreEqual<unsigned long>(1, msgcount, _T("Wrong message count after tx."), pLineInfo);
|
||||
}
|
||||
|
||||
long J2534_send_msg(unsigned long chanid, unsigned long ProtocolID, unsigned long RxStatus, unsigned long TxFlags,
|
||||
unsigned long Timestamp, unsigned long DataSize, unsigned long ExtraDataIndex, const char* Data) {
|
||||
|
||||
PASSTHRU_MSG msg = { ProtocolID, RxStatus, TxFlags, Timestamp, DataSize, ExtraDataIndex };
|
||||
memcpy_s(msg.Data, 4128, Data, DataSize);
|
||||
unsigned long msgcount = 1;
|
||||
return PassThruWriteMsgs(chanid, &msg, &msgcount, 0);
|
||||
}
|
||||
|
||||
//Allow more messages to come in than the min.
|
||||
std::vector<PASSTHRU_MSG> j2534_recv_loop_loose(unsigned int chanid, unsigned int min_num, unsigned long timeout_ms) {
|
||||
std::vector<PASSTHRU_MSG> ret_messages;
|
||||
PASSTHRU_MSG recvbuff[4] = {};
|
||||
Timer t = Timer();
|
||||
|
||||
while (t.getTimePassed() < timeout_ms) {
|
||||
unsigned long msgcount = 4;
|
||||
unsigned int res = PassThruReadMsgs(chanid, recvbuff, &msgcount, 0);
|
||||
if (res == ERR_BUFFER_EMPTY) continue;
|
||||
Assert::IsFalse(msgcount > 4, _T("PassThruReadMsgs returned more data than the buffer could hold."));
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, res, _T("Failed to read message."));
|
||||
if (msgcount > 0) {
|
||||
for (unsigned int i = 0; i < msgcount; i++) {
|
||||
ret_messages.push_back(recvbuff[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert::IsTrue(min_num <= ret_messages.size(), _T("Received too few messages."));
|
||||
return ret_messages;
|
||||
}
|
||||
|
||||
std::vector<PASSTHRU_MSG> j2534_recv_loop(unsigned int chanid, unsigned int num_expected, unsigned long timeout_ms) {
|
||||
std::vector<PASSTHRU_MSG> ret_messages;
|
||||
PASSTHRU_MSG recvbuff[4] = {};
|
||||
Timer t = Timer();
|
||||
|
||||
while (t.getTimePassed() < timeout_ms) {
|
||||
unsigned long msgcount = 4;
|
||||
unsigned int res = PassThruReadMsgs(chanid, recvbuff, &msgcount, 0);
|
||||
if (res == ERR_BUFFER_EMPTY) continue;
|
||||
Assert::IsFalse(msgcount > 4, _T("PassThruReadMsgs returned more data than the buffer could hold."));
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, res, _T("Failed to read message."));
|
||||
if (msgcount > 0) {
|
||||
for (unsigned int i = 0; i < msgcount; i++) {
|
||||
ret_messages.push_back(recvbuff[i]);
|
||||
}
|
||||
}
|
||||
if (ret_messages.size() >= num_expected) break;
|
||||
}
|
||||
|
||||
std::ostringstream stringStream;
|
||||
stringStream << "j2534_recv_loop Broke at " << t.getTimePassed() << " ms size is " << ret_messages.size() << std::endl;
|
||||
|
||||
if (num_expected != ret_messages.size()) {
|
||||
stringStream << "Incorrect number of messages received. Displaying the messages:" << std::endl;
|
||||
for (auto msg : ret_messages) {
|
||||
stringStream << " TS: " << msg.Timestamp << "; Dat: ";
|
||||
for (int i = 0; i < msg.DataSize; i++) stringStream << std::hex << std::setw(2) << std::setfill('0') << int(msg.Data[i] & 0xFF) << " ";
|
||||
stringStream << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::WriteMessage(stringStream.str().c_str());
|
||||
|
||||
Assert::AreEqual<unsigned long>(num_expected, ret_messages.size(), _T("Received wrong number of messages."));
|
||||
return ret_messages;
|
||||
}
|
||||
|
||||
void check_J2534_can_msg(PASSTHRU_MSG& msgin, unsigned long ProtocolID, unsigned long RxStatus, unsigned long TxFlags,
|
||||
unsigned long DataSize, unsigned long ExtraDataIndex, const char* Data, const __LineInfo* pLineInfo) {
|
||||
Assert::AreEqual<size_t>(DataSize, msgin.DataSize, _T("Wrong msg len"), pLineInfo);
|
||||
|
||||
std::ostringstream logmsg;
|
||||
logmsg << "Expected Hex (";
|
||||
for (int i = 0; i < DataSize; i++) logmsg << std::hex << std::setw(2) << std::setfill('0') << int(Data[i] & 0xFF) << " ";
|
||||
logmsg << "); Actual Hex (";
|
||||
for (int i = 0; i < msgin.DataSize; i++) logmsg << std::hex << std::setw(2) << std::setfill('0') << int(((char*)msgin.Data)[i] & 0xFF) << " ";
|
||||
logmsg << ")";
|
||||
Logger::WriteMessage(logmsg.str().c_str());
|
||||
Assert::AreEqual<std::string>(std::string(Data, DataSize), std::string((char*)msgin.Data, msgin.DataSize), _T("Wrong msg payload"), pLineInfo);
|
||||
|
||||
Assert::AreEqual<unsigned long>(ProtocolID, msgin.ProtocolID, _T("Wrong msg protocol"), pLineInfo);
|
||||
Assert::AreEqual<unsigned long>(RxStatus, msgin.RxStatus, _T("Wrong msg receipt rxstatus"), pLineInfo);
|
||||
Assert::AreEqual<unsigned long>(TxFlags, msgin.TxFlags, _T("Wrong msg receipt txflag"), pLineInfo);
|
||||
Assert::AreEqual<unsigned long>(ExtraDataIndex, msgin.ExtraDataIndex, _T("Wrong msg ExtraDataIndex"), pLineInfo);
|
||||
}
|
||||
|
||||
unsigned long J2534_set_PASS_filter(unsigned long chanid, unsigned long ProtocolID, unsigned long tx,
|
||||
unsigned long len, char* mask, char* pattern, const __LineInfo* pLineInfo) {
|
||||
unsigned long filterid;
|
||||
PASSTHRU_MSG mask_msg = { ProtocolID, 0, tx, 0, len, 0, 0 };
|
||||
PASSTHRU_MSG pattern_msg = { ProtocolID, 0, tx, 0, len, 0, 0 };
|
||||
memcpy(mask_msg.Data, mask, len);
|
||||
memcpy(pattern_msg.Data, pattern, len);
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, PassThruStartMsgFilter(chanid, PASS_FILTER, &mask_msg, &pattern_msg, NULL, &filterid),
|
||||
_T("Failed to create filter."), pLineInfo);
|
||||
return filterid;
|
||||
}
|
||||
|
||||
unsigned long J2534_set_BLOCK_filter(unsigned long chanid, unsigned long ProtocolID, unsigned long tx,
|
||||
unsigned long len, char* mask, char* pattern, const __LineInfo* pLineInfo) {
|
||||
unsigned long filterid;
|
||||
PASSTHRU_MSG mask_msg = { ProtocolID, 0, tx, 0, len, 0, 0 };
|
||||
PASSTHRU_MSG pattern_msg = { ProtocolID, 0, tx, 0, len, 0, 0 };
|
||||
memcpy(mask_msg.Data, mask, len);
|
||||
memcpy(pattern_msg.Data, pattern, len);
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, PassThruStartMsgFilter(chanid, BLOCK_FILTER, &mask_msg, &pattern_msg, NULL, &filterid),
|
||||
_T("Failed to create filter."), pLineInfo);
|
||||
return filterid;
|
||||
}
|
||||
|
||||
unsigned long J2534_set_flowctrl_filter(unsigned long chanid, unsigned long tx,
|
||||
unsigned long len, char* mask, char* pattern, char* flow, const __LineInfo* pLineInfo) {
|
||||
unsigned long filterid;
|
||||
PASSTHRU_MSG mask_msg = { ISO15765, 0, tx, 0, len, 0, 0 };
|
||||
PASSTHRU_MSG pattern_msg = { ISO15765, 0, tx, 0, len, 0, 0 };
|
||||
PASSTHRU_MSG flow_msg = { ISO15765, 0, tx, 0, len, 0, 0 };
|
||||
memcpy(mask_msg.Data, mask, len);
|
||||
memcpy(pattern_msg.Data, pattern, len);
|
||||
memcpy(flow_msg.Data, flow, len);
|
||||
Assert::AreEqual<long>(STATUS_NOERROR, PassThruStartMsgFilter(chanid, FLOW_CONTROL_FILTER, &mask_msg, &pattern_msg, &flow_msg, &filterid),
|
||||
_T("Failed to create filter."), pLineInfo);
|
||||
return filterid;
|
||||
}
|
||||
|
||||
std::unique_ptr<panda::Panda> getPanda(unsigned long kbaud, BOOL loopback) {
|
||||
auto p = panda::Panda::openPanda("");
|
||||
Assert::IsTrue(p != nullptr, _T("Could not open raw panda device to test communication."));
|
||||
p->set_can_speed_kbps(panda::PANDA_CAN1, kbaud);
|
||||
p->set_safety_mode(panda::SAFETY_ALLOUTPUT);
|
||||
p->set_can_loopback(loopback);
|
||||
p->can_clear(panda::PANDA_CAN_RX);
|
||||
return p;
|
||||
}
|
||||
|
||||
std::vector<panda::PANDA_CAN_MSG> checked_panda_send(std::unique_ptr<panda::Panda>& p, uint32_t addr, bool is_29b,
|
||||
char* msg, uint8_t len, unsigned int num_expected, const __LineInfo* pLineInfo, unsigned long timeout_ms) {
|
||||
Assert::IsTrue(p->can_send(addr, is_29b, (const uint8_t*)msg, len, panda::PANDA_CAN1), _T("Panda send says it failed."), pLineInfo);
|
||||
auto panda_msg_recv = panda_recv_loop(p, 1 + num_expected, timeout_ms);
|
||||
check_panda_can_msg(panda_msg_recv[0], 0, addr, is_29b, TRUE, std::string(msg, len), pLineInfo);
|
||||
panda_msg_recv.erase(panda_msg_recv.begin());
|
||||
return panda_msg_recv;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "pandaJ2534DLL/J2534_v0404.h"
|
||||
#include "panda_shared/panda.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
extern void write_ioctl(unsigned int chanid, unsigned int param, unsigned int val, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern std::vector<panda::PANDA_CAN_MSG> panda_recv_loop_loose(std::unique_ptr<panda::Panda>& p, unsigned int min_num, unsigned long timeout_ms = 100);
|
||||
|
||||
extern std::vector<panda::PANDA_CAN_MSG> panda_recv_loop(std::unique_ptr<panda::Panda>& p, unsigned int num_expected, unsigned long timeout_ms = 100);
|
||||
|
||||
extern void check_panda_can_msg(panda::PANDA_CAN_MSG& msgin, uint8_t bus, unsigned long addr, bool addr_29b,
|
||||
bool is_receipt, std::string dat, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern unsigned long J2534_start_periodic_msg_checked(unsigned long chanid, unsigned long ProtocolID, unsigned long TxFlags, unsigned long DataSize,
|
||||
unsigned long ExtraDataIndex, const char * Data, unsigned long TimeInterval, const __LineInfo * pLineInfo);
|
||||
|
||||
extern unsigned long J2534_start_periodic_msg(unsigned long chanid, unsigned long ProtocolID, unsigned long TxFlags, unsigned long DataSize,
|
||||
unsigned long ExtraDataIndex, const char* Data, unsigned long TimeInterval, unsigned long* msgID, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern void J2534_send_msg_checked(unsigned long chanid, unsigned long ProtocolID, unsigned long RxStatus, unsigned long TxFlags,
|
||||
unsigned long Timestamp, unsigned long DataSize, unsigned long ExtraDataIndex, const char* Data, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern long J2534_send_msg(unsigned long chanid, unsigned long ProtocolID, unsigned long RxStatus, unsigned long TxFlags,
|
||||
unsigned long Timestamp, unsigned long DataSize, unsigned long ExtraDataIndex, const char* Data);
|
||||
|
||||
extern std::vector<PASSTHRU_MSG> j2534_recv_loop_loose(unsigned int chanid, unsigned int min_num, unsigned long timeout_ms = 100);
|
||||
|
||||
extern std::vector<PASSTHRU_MSG> j2534_recv_loop(unsigned int chanid, unsigned int num_expected, unsigned long timeout_ms = 100);
|
||||
|
||||
extern void check_J2534_can_msg(PASSTHRU_MSG& msgin, unsigned long ProtocolID, unsigned long RxStatus, unsigned long TxFlags,
|
||||
unsigned long DataSize, unsigned long ExtraDataIndex, const char* Data, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern unsigned long J2534_set_PASS_filter(unsigned long chanid, unsigned long ProtocolID, unsigned long tx,
|
||||
unsigned long len, char* mask, char* pattern, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern unsigned long J2534_set_BLOCK_filter(unsigned long chanid, unsigned long ProtocolID, unsigned long tx,
|
||||
unsigned long len, char* mask, char* pattern, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern unsigned long J2534_set_flowctrl_filter(unsigned long chanid, unsigned long tx,
|
||||
unsigned long len, char* mask, char* pattern, char* flow, const __LineInfo* pLineInfo = NULL);
|
||||
|
||||
extern std::unique_ptr<panda::Panda> getPanda(unsigned long kbaud = 500, BOOL loopback = FALSE);
|
||||
|
||||
extern std::vector<panda::PANDA_CAN_MSG> checked_panda_send(std::unique_ptr<panda::Panda>& p, uint32_t addr, bool is_29b,
|
||||
char* msg, uint8_t len, unsigned int num_expected=0, const __LineInfo* pLineInfo = NULL, unsigned long timeout_ms = 100);
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// gets the time elapsed from construction.
|
||||
unsigned long long /*milliseconds*/ Timer::getTimePassed(){
|
||||
// get the new time
|
||||
auto end = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
|
||||
|
||||
// return the difference of the times
|
||||
return (end - start).count();
|
||||
}
|
||||
|
||||
void Timer::reset() {
|
||||
start = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
#include <chrono>
|
||||
|
||||
//Copied from https://stackoverflow.com/a/31488113
|
||||
|
||||
class Timer
|
||||
{
|
||||
using clock = std::chrono::steady_clock;
|
||||
using time_point_type = std::chrono::time_point < clock, std::chrono::milliseconds >;
|
||||
public:
|
||||
Timer();
|
||||
|
||||
// gets the time elapsed from construction.
|
||||
unsigned long long /*milliseconds*/ getTimePassed();
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
time_point_type start;
|
||||
};
|
||||
@@ -1,122 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{7912F978-B48C-4C5D-8BFD-5D1E22158E47}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>pandaJ2534DLLTest</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Tests</ProjectName>
|
||||
</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>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<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;%(AdditionalDependencies);$(OutDir)panda.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(SolutionDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<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;%(AdditionalDependencies);$(OutDir)panda.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\pandaJ2534DLL\J2534_v0404.h" />
|
||||
<ClInclude Include="..\panda\panda.h" />
|
||||
<ClInclude Include="Loader4.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="TestHelpers.h" />
|
||||
<ClInclude Include="Timer.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ECUsim_tests.cpp" />
|
||||
<ClCompile Include="Loader4.cpp" />
|
||||
<ClCompile Include="panda_tests.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="j2534_tests.cpp" />
|
||||
<ClCompile Include="TestHelpers.cpp" />
|
||||
<ClCompile Include="Timer.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ECUsim DLL\ECUsim DLL.vcxproj">
|
||||
<Project>{96e0e646-ee76-444d-9a77-a0cd7f781deb}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\pandaJ2534DLL\pandaJ2534DLL.vcxproj">
|
||||
<Project>{a2bb18a5-f26b-48d6-bbb5-b83d64473c77}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Loader4.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\pandaJ2534DLL\J2534_v0404.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Timer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\panda\panda.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TestHelpers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="j2534_tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Loader4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestHelpers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ECUsim_tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="panda_tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,187 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "panda_shared/panda.h"
|
||||
#include "TestHelpers.h"
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace panda;
|
||||
|
||||
namespace pandaTestNative
|
||||
{
|
||||
TEST_CLASS(DeviceDiscovery)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(Panda_DevDiscover_ListDevices)
|
||||
{
|
||||
auto pandas_available = Panda::listAvailablePandas();
|
||||
Assert::IsTrue(pandas_available.size() > 0, _T("No pandas were found."));
|
||||
for (auto sn : pandas_available) {
|
||||
Assert::IsTrue(sn.size() == 24, _T("panda Serial Number not 24 characters long."));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_DevDiscover_OpenFirstDevice)
|
||||
{
|
||||
auto pandas_available = Panda::listAvailablePandas();
|
||||
Assert::IsTrue(pandas_available.size() > 0, _T("No pandas were found."));
|
||||
|
||||
auto p1 = Panda::openPanda(pandas_available[0]);
|
||||
Assert::IsFalse(p1 == nullptr, _T("Could not open panda."));
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_DevDiscover_OpenDeviceNoName)
|
||||
{
|
||||
auto pandas_available = Panda::listAvailablePandas();
|
||||
Assert::IsTrue(pandas_available.size() > 0, _T("No pandas were found."));
|
||||
|
||||
auto p1 = Panda::openPanda("");
|
||||
Assert::IsFalse(p1 == nullptr, _T("Could not open panda."));
|
||||
Assert::IsTrue(p1->get_usb_sn() == pandas_available[0], _T("Could not open panda."));
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_DevDiscover_OpenDeviceUnavailable)
|
||||
{
|
||||
auto p1 = Panda::openPanda("ZZZZZZZZZZZZZZZZZZZZZZZZ");
|
||||
Assert::IsTrue(p1 == nullptr, _T("Invalid sn still worked."));
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_DevDiscover_WillNotOpenAlreadyOpenedDevice)
|
||||
{
|
||||
auto pandas_available = Panda::listAvailablePandas();
|
||||
Assert::IsTrue(pandas_available.size() > 0, _T("No pandas were found."));
|
||||
|
||||
auto p1 = Panda::openPanda(pandas_available[0]);
|
||||
Assert::IsFalse(p1 == nullptr, _T("Could not open panda."));
|
||||
|
||||
auto p2 = Panda::openPanda(pandas_available[0]);
|
||||
Assert::IsTrue(p2 == nullptr, _T("Opened an already open panda."));
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_DevDiscover_OpenedDeviceNotListed)
|
||||
{
|
||||
auto pandas_available = Panda::listAvailablePandas();
|
||||
Assert::IsTrue(pandas_available.size() > 0, _T("No pandas were found."));
|
||||
|
||||
auto p1 = Panda::openPanda(pandas_available[0]);
|
||||
Assert::IsFalse(p1 == nullptr, _T("Could not open panda."));
|
||||
|
||||
auto pandas_available2 = Panda::listAvailablePandas();
|
||||
for (auto sn : pandas_available2) {
|
||||
Assert::IsFalse(p1->get_usb_sn() == sn, _T("Opened panda appears in list of available pandas."));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS(CANOperations)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(Panda_CAN_Echo)
|
||||
{
|
||||
auto p0 = getPanda(500, TRUE);
|
||||
|
||||
uint32_t addr = 0xAA;
|
||||
bool is_29b = FALSE;
|
||||
uint8_t candata[8];
|
||||
|
||||
for (auto canbus : { PANDA_CAN1, PANDA_CAN2, PANDA_CAN3 }) {
|
||||
uint8_t len = (rand() % 8) + 1;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
candata[i] = rand() % 256;
|
||||
|
||||
p0->can_send(addr, is_29b, candata, len, canbus);
|
||||
Sleep(10);
|
||||
|
||||
auto can_msgs = p0->can_recv();
|
||||
|
||||
Assert::AreEqual<size_t>(2, can_msgs.size(), _T("Received the wrong number of CAN messages."), LINE_INFO());
|
||||
|
||||
for (auto msg : can_msgs) {
|
||||
Assert::IsTrue(msg.addr == addr, _T("Wrong addr."));
|
||||
Assert::IsTrue(msg.bus == canbus, _T("Wrong bus."));
|
||||
Assert::IsTrue(msg.len == len, _T("Wrong len."));
|
||||
Assert::AreEqual(memcmp(msg.dat, candata, msg.len), 0, _T("Received CAN data not equal"));
|
||||
for (int i = msg.len; i < 8; i++)
|
||||
Assert::IsTrue(msg.dat[i] == 0, _T("Received CAN data not trailed by 0s"));
|
||||
}
|
||||
|
||||
Assert::IsTrue(can_msgs[0].is_receipt, _T("Didn't get receipt."));
|
||||
Assert::IsFalse(can_msgs[1].is_receipt, _T("Didn't get echo."));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_CAN_ChangeBaud)
|
||||
{
|
||||
auto p0 = getPanda(250);
|
||||
auto p1 = getPanda(500);
|
||||
|
||||
p0->can_send(0xAA, FALSE, (const uint8_t*)"\x1\x2\x3\x4\x5\x6\x7\x8", 8, panda::PANDA_CAN1);
|
||||
panda_recv_loop(p0, 0);
|
||||
panda_recv_loop(p1, 0);
|
||||
|
||||
p0->set_can_speed_kbps(panda::PANDA_CAN1, 500);
|
||||
|
||||
auto panda_msg_recv = panda_recv_loop(p0, 1);
|
||||
check_panda_can_msg(panda_msg_recv[0], 0, 0xAA, FALSE, TRUE, "\x1\x2\x3\x4\x5\x6\x7\x8", LINE_INFO());
|
||||
panda_msg_recv = panda_recv_loop(p1, 1);
|
||||
check_panda_can_msg(panda_msg_recv[0], 0, 0xAA, FALSE, FALSE, "\x1\x2\x3\x4\x5\x6\x7\x8", LINE_INFO());
|
||||
|
||||
//////////////////
|
||||
|
||||
p0->set_can_speed_kbps(panda::PANDA_CAN1, 250);
|
||||
p0->can_send(0xC4, FALSE, (const uint8_t*)"\xA\B\xC\xD\xE\xF\x10\x11", 8, panda::PANDA_CAN1);
|
||||
panda_recv_loop(p0, 0);
|
||||
panda_recv_loop(p1, 0);
|
||||
|
||||
p1->set_can_speed_kbps(panda::PANDA_CAN1, 250);
|
||||
|
||||
panda_msg_recv = panda_recv_loop(p0, 1);
|
||||
check_panda_can_msg(panda_msg_recv[0], 0, 0xC4, FALSE, TRUE, "\xA\B\xC\xD\xE\xF\x10\x11", LINE_INFO());
|
||||
panda_msg_recv = panda_recv_loop(p1, 1);
|
||||
check_panda_can_msg(panda_msg_recv[0], 0, 0xC4, FALSE, FALSE, "\xA\B\xC\xD\xE\xF\x10\x11", LINE_INFO());
|
||||
}
|
||||
|
||||
TEST_METHOD(Panda_CAN_ClearClears)
|
||||
{
|
||||
auto p0 = getPanda(500, TRUE);
|
||||
p0->can_send(0xAA, FALSE, (const uint8_t*)"\x0\x1\x2\x3\x4\x5\x6\x7", 8, panda::PANDA_CAN1);
|
||||
Sleep(100);
|
||||
p0->can_clear(PANDA_CAN_RX);
|
||||
|
||||
auto can_msgs = p0->can_recv();
|
||||
Assert::IsTrue(can_msgs.size() == 0, _T("Received messages after a clear."));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS(SerialOperations)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(Panda_LIN_Echo)
|
||||
{
|
||||
auto p0 = getPanda(500);
|
||||
|
||||
for (auto lin_port : { SERIAL_LIN1, SERIAL_LIN2 }) {
|
||||
p0->serial_clear(lin_port);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
uint8_t len = (rand() % LIN_MSG_MAX_LEN) + 1;
|
||||
std::string lindata;
|
||||
lindata.reserve(len);
|
||||
|
||||
for (size_t j = 0; j < len; j++)
|
||||
lindata += (const char)(rand() % 256);
|
||||
|
||||
p0->serial_write(lin_port, lindata.c_str(), len);
|
||||
Sleep(10);
|
||||
|
||||
auto retdata = p0->serial_read(lin_port);
|
||||
Assert::AreEqual(retdata, lindata);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// pandaJ2534DLL Test.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// Headers for CppUnitTest
|
||||
#include "CppUnitTest.h"
|
||||
#include <iomanip> //Used for formatting in TestHelpers.cpp
|
||||
#include <string>
|
||||
#include <array>
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
@@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
#include "J2534Frame.h"
|
||||
|
||||
class J2534Connection;
|
||||
|
||||
/**
|
||||
An Action represents a unit of work that can be scheduled for execution at a later time.
|
||||
Actions are not guaranteed to be run at their specified time, but a best effort is made.
|
||||
An Action will never execute early, but can execute later depending on what is in the
|
||||
queus.
|
||||
Many different operations are based on this base class. Instead of making a thread,
|
||||
consider if the work can be offloaded to the Task Queue.
|
||||
*/
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
Action(
|
||||
std::weak_ptr<J2534Connection> connection,
|
||||
std::chrono::microseconds delay
|
||||
) : connection(connection), delay(delay) { };
|
||||
|
||||
Action(
|
||||
std::weak_ptr<J2534Connection> connection
|
||||
) : connection(connection), delay(std::chrono::microseconds(0)) { };
|
||||
|
||||
//The function called by the task runner when this action is to be invoked.
|
||||
virtual void execute() = 0;
|
||||
|
||||
//Reschedule this Action for now().
|
||||
void scheduleImmediate() {
|
||||
expire = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
//Reschedule this Action relative to its last expiration time.
|
||||
void scheduleDelay() {
|
||||
expire += this->delay;
|
||||
}
|
||||
|
||||
//Reschedule this action {delay} after now().
|
||||
void scheduleImmediateDelay() {
|
||||
expire = std::chrono::steady_clock::now() + this->delay;
|
||||
}
|
||||
|
||||
//Reschedule this Action based on a specific base time.
|
||||
void schedule(std::chrono::time_point<std::chrono::steady_clock> starttine, BOOL adddelayed) {
|
||||
this->expire = starttine;
|
||||
if (adddelayed)
|
||||
expire += this->delay;
|
||||
}
|
||||
|
||||
std::weak_ptr<J2534Connection> connection;
|
||||
std::chrono::microseconds delay;
|
||||
//The timestamp at which point this Action is ready to be executed.
|
||||
std::chrono::time_point<std::chrono::steady_clock> expire;
|
||||
};
|
||||
@@ -1,360 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "J2534Connection.h"
|
||||
#include "Timer.h"
|
||||
|
||||
J2534Connection::J2534Connection(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
) : panda_dev(panda_dev), ProtocolID(ProtocolID), Flags(Flags), BaudRate(BaudRate), Parity(0), port(0) { }
|
||||
|
||||
unsigned long J2534Connection::validateTxMsg(PASSTHRU_MSG* msg) {
|
||||
if (msg->DataSize < this->getMinMsgLen() || msg->DataSize > this->getMaxMsgLen())
|
||||
return ERR_INVALID_MSG;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
long J2534Connection::PassThruReadMsgs(PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout) {
|
||||
//Timeout of 0 means return immediately. Non zero means WAIT for that time then return. Dafuk.
|
||||
long err_code = STATUS_NOERROR;
|
||||
Timer t = Timer();
|
||||
|
||||
unsigned long msgnum = 0;
|
||||
while (msgnum < *pNumMsgs) {
|
||||
if (Timeout > 0 && t.getTimePassed() >= Timeout) {
|
||||
err_code = ERR_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
//Synchronized won't work where we have to break out of a loop
|
||||
messageRxBuff_mutex.lock();
|
||||
if (this->messageRxBuff.empty()) {
|
||||
messageRxBuff_mutex.unlock();
|
||||
if (Timeout == 0)
|
||||
break;
|
||||
Sleep(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto msg_in = this->messageRxBuff.front();
|
||||
this->messageRxBuff.pop();
|
||||
messageRxBuff_mutex.unlock();
|
||||
|
||||
PASSTHRU_MSG *msg_out = &pMsg[msgnum++];
|
||||
msg_out->ProtocolID = this->ProtocolID;
|
||||
msg_out->DataSize = msg_in.Data.size();
|
||||
memcpy(msg_out->Data, msg_in.Data.c_str(), msg_in.Data.size());
|
||||
msg_out->Timestamp = msg_in.Timestamp;
|
||||
msg_out->RxStatus = msg_in.RxStatus;
|
||||
msg_out->ExtraDataIndex = msg_in.ExtraDataIndex;
|
||||
msg_out->TxFlags = 0;
|
||||
if (msgnum == *pNumMsgs) break;
|
||||
}
|
||||
|
||||
if (msgnum == 0)
|
||||
err_code = ERR_BUFFER_EMPTY;
|
||||
*pNumMsgs = msgnum;
|
||||
return err_code;
|
||||
}
|
||||
|
||||
long J2534Connection::PassThruWriteMsgs(PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout) {
|
||||
//There doesn't seem to be much reason to implement the timeout here.
|
||||
for (unsigned int msgnum = 0; msgnum < *pNumMsgs; msgnum++) {
|
||||
PASSTHRU_MSG* msg = &pMsg[msgnum];
|
||||
if (msg->ProtocolID != this->ProtocolID) {
|
||||
*pNumMsgs = msgnum;
|
||||
return ERR_MSG_PROTOCOL_ID;
|
||||
}
|
||||
|
||||
auto retcode = this->validateTxMsg(msg);
|
||||
if (retcode != STATUS_NOERROR) {
|
||||
*pNumMsgs = msgnum;
|
||||
return retcode;
|
||||
}
|
||||
|
||||
auto msgtx = this->parseMessageTx(*pMsg);
|
||||
if (msgtx != nullptr) //Nullptr is supported for unimplemented connection types.
|
||||
this->schedultMsgTx(std::dynamic_pointer_cast<Action>(msgtx));
|
||||
}
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
//The docs say that a device has to support 10 periodic messages, though more is ok.
|
||||
//It is easier to store them on the connection, so 10 per connection it is.
|
||||
long J2534Connection::PassThruStartPeriodicMsg(PASSTHRU_MSG *pMsg, unsigned long *pMsgID, unsigned long TimeInterval) {
|
||||
if (pMsg->DataSize < getMinMsgLen() || pMsg->DataSize > getMaxMsgSingleFrameLen()) return ERR_INVALID_MSG;
|
||||
if (pMsg->ProtocolID != this->ProtocolID) return ERR_MSG_PROTOCOL_ID;
|
||||
if (TimeInterval < 5 || TimeInterval > 65535) return ERR_INVALID_TIME_INTERVAL;
|
||||
|
||||
for (unsigned int i = 0; i < this->periodicMessages.size(); i++) {
|
||||
if (periodicMessages[i] != nullptr) continue;
|
||||
|
||||
*pMsgID = i;
|
||||
auto msgtx = this->parseMessageTx(*pMsg);
|
||||
if (msgtx != nullptr) {
|
||||
periodicMessages[i] = std::make_shared<MessagePeriodic>(std::chrono::microseconds(TimeInterval*1000), msgtx);
|
||||
periodicMessages[i]->scheduleImmediate();
|
||||
if (auto panda_dev = this->getPandaDev()) {
|
||||
panda_dev->insertActionIntoTaskList(periodicMessages[i]);
|
||||
}
|
||||
}
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
return ERR_EXCEEDED_LIMIT;
|
||||
}
|
||||
|
||||
long J2534Connection::PassThruStopPeriodicMsg(unsigned long MsgID) {
|
||||
if (MsgID >= this->periodicMessages.size() || this->periodicMessages[MsgID] == nullptr)
|
||||
return ERR_INVALID_MSG_ID;
|
||||
this->periodicMessages[MsgID]->cancel();
|
||||
this->periodicMessages[MsgID] = nullptr;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
long J2534Connection::PassThruStartMsgFilter(unsigned long FilterType, PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg,
|
||||
PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID) {
|
||||
for (unsigned int i = 0; i < this->filters.size(); i++) {
|
||||
if (filters[i] == nullptr) {
|
||||
try {
|
||||
auto newfilter = std::make_shared<J2534MessageFilter>(this, FilterType, pMaskMsg, pPatternMsg, pFlowControlMsg);
|
||||
for (unsigned int check_idx = 0; check_idx < filters.size(); check_idx++) {
|
||||
if (filters[check_idx] == nullptr) continue;
|
||||
if (filters[check_idx] == newfilter) {
|
||||
filters[i] = nullptr;
|
||||
return ERR_NOT_UNIQUE;
|
||||
}
|
||||
}
|
||||
*pFilterID = i;
|
||||
filters[i] = newfilter;
|
||||
return STATUS_NOERROR;
|
||||
} catch (int e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ERR_EXCEEDED_LIMIT;
|
||||
}
|
||||
|
||||
long J2534Connection::PassThruStopMsgFilter(unsigned long FilterID) {
|
||||
if (FilterID >= this->filters.size() || this->filters[FilterID] == nullptr)
|
||||
return ERR_INVALID_FILTER_ID;
|
||||
this->filters[FilterID] = nullptr;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
long J2534Connection::PassThruIoctl(unsigned long IoctlID, void *pInput, void *pOutput) {
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
long J2534Connection::init5b(SBYTE_ARRAY* pInput, SBYTE_ARRAY* pOutput) {
|
||||
if (pInput->NumOfBytes == 1) {
|
||||
if (auto panda_ps = this->panda_dev.lock()) {
|
||||
auto resp = panda_ps->kline_five_baud_init(pInput->BytePtr[0]);
|
||||
if (resp.size() > 0) {
|
||||
auto key_bytes = resp.c_str();
|
||||
if (pOutput->NumOfBytes >= 1) {
|
||||
pOutput->BytePtr[0] = key_bytes[0];
|
||||
}
|
||||
if (pOutput->NumOfBytes >= 2) {
|
||||
pOutput->BytePtr[1] = key_bytes[1];
|
||||
}
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_FAILED;
|
||||
}
|
||||
long J2534Connection::initFast(PASSTHRU_MSG* pInput, PASSTHRU_MSG* pOutput) {
|
||||
if (auto panda_ps = this->panda_dev.lock()) {
|
||||
auto start_comm = std::string((char*)pInput->Data, pInput->DataSize);
|
||||
auto resp = panda_ps->kline_wakeup_start_comm(start_comm);
|
||||
if (resp.size() > 0) {
|
||||
pOutput->ProtocolID = pInput->ProtocolID;
|
||||
pOutput->RxStatus = 0;
|
||||
pOutput->TxFlags = 0;
|
||||
pOutput->Timestamp = pInput->Timestamp;
|
||||
pOutput->ExtraDataIndex = resp.size();
|
||||
memcpy(pOutput->Data, resp.c_str(), resp.size());
|
||||
pOutput->DataSize = resp.size();
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_FAILED;
|
||||
}
|
||||
long J2534Connection::clearTXBuff() {
|
||||
if (auto panda_ps = this->panda_dev.lock()) {
|
||||
synchronized(staged_writes_lock) {
|
||||
this->txbuff = {};
|
||||
switch (this->ProtocolID)
|
||||
{
|
||||
case CAN:
|
||||
case CAN_PS:
|
||||
case ISO15765:
|
||||
case ISO15765_PS:
|
||||
panda_ps->panda->can_clear(panda::PANDA_CAN1_TX);
|
||||
break;
|
||||
case ISO9141:
|
||||
case ISO9141_PS:
|
||||
case ISO14230:
|
||||
case ISO14230_PS:
|
||||
panda_ps->panda->serial_clear(panda::SERIAL_LIN1);
|
||||
panda_ps->panda->serial_clear(panda::SERIAL_LIN2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
return ERR_FAILED;
|
||||
}
|
||||
long J2534Connection::clearRXBuff() {
|
||||
if (auto panda_ps = this->panda_dev.lock()) {
|
||||
synchronized(messageRxBuff_mutex) {
|
||||
this->messageRxBuff = {};
|
||||
switch (this->ProtocolID)
|
||||
{
|
||||
case CAN:
|
||||
case CAN_PS:
|
||||
case ISO15765:
|
||||
case ISO15765_PS:
|
||||
panda_ps->panda->can_clear(panda::PANDA_CAN_RX);
|
||||
break;
|
||||
case ISO9141:
|
||||
case ISO9141_PS:
|
||||
case ISO14230:
|
||||
case ISO14230_PS:
|
||||
panda_ps->panda->serial_clear(panda::SERIAL_LIN1);
|
||||
panda_ps->panda->serial_clear(panda::SERIAL_LIN2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
return ERR_FAILED;
|
||||
}
|
||||
long J2534Connection::clearPeriodicMsgs() {
|
||||
for (unsigned int i = 0; i < this->periodicMessages.size(); i++) {
|
||||
if (periodicMessages[i] == nullptr) continue;
|
||||
this->periodicMessages[i]->cancel();
|
||||
this->periodicMessages[i] = nullptr;
|
||||
}
|
||||
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
long J2534Connection::clearMsgFilters() {
|
||||
for (auto& filter : this->filters) filter = nullptr;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
void J2534Connection::setBaud(unsigned long baud) {
|
||||
this->BaudRate = baud;
|
||||
}
|
||||
|
||||
void J2534Connection::setParity(unsigned long parity) {
|
||||
this->Parity = parity;
|
||||
}
|
||||
|
||||
void J2534Connection::schedultMsgTx(std::shared_ptr<Action> msgout) {
|
||||
if (auto panda_ps = this->panda_dev.lock()) {
|
||||
synchronized(staged_writes_lock) {
|
||||
this->txbuff.push(msgout);
|
||||
panda_ps->registerConnectionTx(shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void J2534Connection::rescheduleExistingTxMsgs() {
|
||||
if (auto panda_ps = this->panda_dev.lock()) {
|
||||
synchronized(staged_writes_lock) {
|
||||
panda_ps->unstallConnectionTx(shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Works well as long as the protocol doesn't support flow control.
|
||||
void J2534Connection::processMessage(const J2534Frame& msg) {
|
||||
FILTER_RESULT filter_res = FILTER_RESULT_NEUTRAL;
|
||||
|
||||
for (auto filter : this->filters) {
|
||||
if (filter == nullptr) continue;
|
||||
FILTER_RESULT current_check_res = filter->check(msg);
|
||||
if (current_check_res == FILTER_RESULT_BLOCK) return;
|
||||
if (current_check_res == FILTER_RESULT_PASS) filter_res = FILTER_RESULT_PASS;
|
||||
}
|
||||
|
||||
if (filter_res == FILTER_RESULT_PASS) {
|
||||
addMsgToRxQueue(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void J2534Connection::processIOCTLSetConfig(unsigned long Parameter, unsigned long Value) {
|
||||
switch (Parameter) {
|
||||
case DATA_RATE: // 5-500000
|
||||
this->setBaud(Value);
|
||||
break;
|
||||
case LOOPBACK: // 0 (OFF), 1 (ON) [0]
|
||||
this->loopback = (Value != 0);
|
||||
break;
|
||||
case PARITY:
|
||||
this->setParity(Value);
|
||||
break;
|
||||
case ISO15765_WFT_MAX:
|
||||
break;
|
||||
case NODE_ADDRESS: // J1850PWM Related (Not supported by panda). HDS requires these to 'work'.
|
||||
case NETWORK_LINE:
|
||||
case P1_MIN: // A bunch of stuff relating to ISO9141 and ISO14230 that the panda
|
||||
case P1_MAX: // currently doesn't support. Don't let HDS know we can't use these.
|
||||
case P2_MIN:
|
||||
case P2_MAX:
|
||||
case P3_MIN:
|
||||
case P3_MAX:
|
||||
case P4_MIN:
|
||||
case P4_MAX:
|
||||
case W0:
|
||||
case W1:
|
||||
case W2:
|
||||
case W3:
|
||||
case W4:
|
||||
case W5:
|
||||
case TIDLE:
|
||||
case TINIL:
|
||||
case TWUP:
|
||||
case T1_MAX: // SCI related options. The panda does not appear to support this
|
||||
case T2_MAX:
|
||||
case T3_MAX:
|
||||
case T4_MAX:
|
||||
case T5_MAX:
|
||||
break; // Just smile and nod.
|
||||
default:
|
||||
printf("Got unknown SET code %X\n", Parameter);
|
||||
}
|
||||
|
||||
// reserved parameters usually mean special equiptment is required
|
||||
//if (Parameter >= 0x20) {
|
||||
// throw ERR_NOT_SUPPORTED;
|
||||
//}
|
||||
}
|
||||
|
||||
unsigned long J2534Connection::processIOCTLGetConfig(unsigned long Parameter) {
|
||||
switch (Parameter) {
|
||||
case DATA_RATE:
|
||||
return this->getBaud();
|
||||
case LOOPBACK:
|
||||
return this->loopback;
|
||||
break;
|
||||
case BIT_SAMPLE_POINT:
|
||||
return 80;
|
||||
case SYNC_JUMP_WIDTH:
|
||||
return 15;
|
||||
default:
|
||||
// HDS rarely reads off values through ioctl GET_CONFIG, but it often
|
||||
// just wants the call to pass without erroring, so just don't do anything.
|
||||
printf("Got unknown code %X\n", Parameter);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
#pragma once
|
||||
#include "panda_shared/panda.h"
|
||||
#include "J2534_v0404.h"
|
||||
#include "synchronize.h"
|
||||
#include "J2534Frame.h"
|
||||
#include "PandaJ2534Device.h"
|
||||
#include "J2534MessageFilter.h"
|
||||
#include "MessagePeriodic.h"
|
||||
|
||||
class J2534Frame;
|
||||
class Action;
|
||||
class PandaJ2534Device;
|
||||
class J2534MessageFilter;
|
||||
|
||||
#define check_bmask(num, mask)(((num) & mask) == mask)
|
||||
|
||||
/**
|
||||
Class representing a generic J2534 Connection created by PassThruConnect,
|
||||
and is associated with a channelID given to the J2534 API user.
|
||||
Subclasses implement specific J2534 supported protocols.
|
||||
*/
|
||||
class J2534Connection : public std::enable_shared_from_this<J2534Connection> {
|
||||
friend class PandaJ2534Device;
|
||||
|
||||
public:
|
||||
J2534Connection(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
);
|
||||
virtual ~J2534Connection() {};
|
||||
|
||||
//J2534 API functions
|
||||
|
||||
virtual long PassThruReadMsgs(PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout);
|
||||
long PassThruWriteMsgs(PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout);
|
||||
virtual long PassThruStartPeriodicMsg(PASSTHRU_MSG *pMsg, unsigned long *pMsgID, unsigned long TimeInterval);
|
||||
virtual long PassThruStopPeriodicMsg(unsigned long MsgID);
|
||||
|
||||
virtual long PassThruStartMsgFilter(unsigned long FilterType, PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg,
|
||||
PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID);
|
||||
|
||||
virtual long PassThruStopMsgFilter(unsigned long FilterID);
|
||||
virtual long PassThruIoctl(unsigned long IoctlID, void *pInput, void *pOutput);
|
||||
|
||||
//Functions for parsing messages to be send with PassThruWriteMsgs.
|
||||
|
||||
virtual unsigned long validateTxMsg(PASSTHRU_MSG* msg);
|
||||
virtual std::shared_ptr<MessageTx> parseMessageTx(PASSTHRU_MSG& msg) { return nullptr; };
|
||||
|
||||
//IOCTL functions
|
||||
|
||||
virtual long init5b(SBYTE_ARRAY* pInput, SBYTE_ARRAY* pOutput);
|
||||
virtual long initFast(PASSTHRU_MSG* pInput, PASSTHRU_MSG* pOutput);
|
||||
long clearTXBuff();
|
||||
long clearRXBuff();
|
||||
long clearPeriodicMsgs();
|
||||
long clearMsgFilters();
|
||||
|
||||
virtual void setBaud(unsigned long baud);
|
||||
virtual void setParity(unsigned long parity);
|
||||
|
||||
unsigned long getBaud() {
|
||||
return this->BaudRate;
|
||||
}
|
||||
|
||||
unsigned long getProtocol() {
|
||||
return this->ProtocolID;
|
||||
};
|
||||
|
||||
virtual bool isProtoCan() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//Port is used in a protocol specific way to differentiate tranceivers.
|
||||
unsigned long getPort() {
|
||||
return this->port;
|
||||
}
|
||||
|
||||
virtual void processIOCTLSetConfig(unsigned long Parameter, unsigned long Value);
|
||||
|
||||
virtual unsigned long processIOCTLGetConfig(unsigned long Parameter);
|
||||
|
||||
//Called when the passthru device has received a message for this connection
|
||||
//Loopback messages are processed separately.
|
||||
virtual void processMessage(const J2534Frame& msg);
|
||||
|
||||
//Limitations on message size. Override in every subclass.
|
||||
|
||||
virtual unsigned long getMinMsgLen() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgLen() {
|
||||
return 4128;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgSingleFrameLen() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
//Add an Action to the Task Queue for future processing.
|
||||
//The task should be set its expire time before being submitted.
|
||||
void schedultMsgTx(std::shared_ptr<Action> msgout);
|
||||
|
||||
void rescheduleExistingTxMsgs();
|
||||
|
||||
std::shared_ptr<PandaJ2534Device> getPandaDev() {
|
||||
if (auto panda_dev_sp = this->panda_dev.lock())
|
||||
return panda_dev_sp;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//Add a message to the queue read by PassThruReadMsgs().
|
||||
void addMsgToRxQueue(const J2534Frame& frame) {
|
||||
synchronized(messageRxBuff_mutex) {
|
||||
messageRxBuff.push(frame);
|
||||
}
|
||||
}
|
||||
|
||||
bool loopback = FALSE;
|
||||
|
||||
protected:
|
||||
unsigned long ProtocolID;
|
||||
unsigned long Flags;
|
||||
unsigned long BaudRate;
|
||||
unsigned long Parity;
|
||||
unsigned long port;
|
||||
|
||||
std::weak_ptr<PandaJ2534Device> panda_dev;
|
||||
|
||||
Mutex messageRxBuff_mutex;
|
||||
std::queue<J2534Frame> messageRxBuff;
|
||||
|
||||
std::array<std::shared_ptr<J2534MessageFilter>, 10> filters;
|
||||
std::queue<std::shared_ptr<Action>> txbuff;
|
||||
|
||||
std::array<std::shared_ptr<MessagePeriodic>, 10> periodicMessages;
|
||||
|
||||
private:
|
||||
Mutex staged_writes_lock;
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "J2534Connection_CAN.h"
|
||||
#include "MessageTx_CAN.h"
|
||||
#include "Timer.h"
|
||||
|
||||
J2534Connection_CAN::J2534Connection_CAN(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
) : J2534Connection(panda_dev, ProtocolID, Flags, BaudRate) {
|
||||
this->port = 0;
|
||||
|
||||
if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000)
|
||||
throw ERR_INVALID_BAUDRATE;
|
||||
|
||||
panda_dev->panda->set_can_speed_cbps(panda::PANDA_CAN1, BaudRate/100);
|
||||
};
|
||||
|
||||
unsigned long J2534Connection_CAN::validateTxMsg(PASSTHRU_MSG* msg) {
|
||||
if ((msg->DataSize < this->getMinMsgLen() || msg->DataSize > this->getMaxMsgLen() ||
|
||||
(val_is_29bit(msg->TxFlags) != this->_is_29bit() && !check_bmask(this->Flags, CAN_ID_BOTH))))
|
||||
return ERR_INVALID_MSG;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
std::shared_ptr<MessageTx> J2534Connection_CAN::parseMessageTx(PASSTHRU_MSG& msg) {
|
||||
return std::dynamic_pointer_cast<MessageTx>(std::make_shared<MessageTx_CAN>(shared_from_this(), msg));
|
||||
}
|
||||
|
||||
void J2534Connection_CAN::setBaud(unsigned long BaudRate) {
|
||||
if (auto panda_dev = this->getPandaDev()) {
|
||||
if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000)
|
||||
throw ERR_NOT_SUPPORTED;
|
||||
|
||||
panda_dev->panda->set_can_speed_cbps(panda::PANDA_CAN1, (uint16_t)(BaudRate / 100));
|
||||
return J2534Connection::setBaud(BaudRate);
|
||||
} else {
|
||||
throw ERR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "J2534Connection.h"
|
||||
#include "panda_shared/panda.h"
|
||||
|
||||
#define val_is_29bit(num) check_bmask(num, CAN_29BIT_ID)
|
||||
|
||||
class J2534Connection_CAN : public J2534Connection {
|
||||
public:
|
||||
J2534Connection_CAN(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
);
|
||||
|
||||
virtual unsigned long validateTxMsg(PASSTHRU_MSG* msg);
|
||||
|
||||
virtual std::shared_ptr<MessageTx> parseMessageTx(PASSTHRU_MSG& pMsg);
|
||||
|
||||
virtual void setBaud(unsigned long baud);
|
||||
|
||||
virtual unsigned long getMinMsgLen() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgLen() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgSingleFrameLen() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
virtual bool isProtoCan() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool _is_29bit() {
|
||||
return (this->Flags & CAN_29BIT_ID) == CAN_29BIT_ID;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,83 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "J2534Connection_ISO14230.h"
|
||||
#include "MessageTx_ISO14230.h"
|
||||
#include "Timer.h"
|
||||
|
||||
J2534Connection_ISO14230::J2534Connection_ISO14230(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
) : J2534Connection(panda_dev, ProtocolID, Flags, BaudRate) {
|
||||
this->port = 0;
|
||||
|
||||
if (BaudRate % 100 || BaudRate < 2400 || BaudRate > 115200)
|
||||
throw ERR_INVALID_BAUDRATE;
|
||||
|
||||
panda_dev->panda->set_uart_baud(panda::SERIAL_LIN1, BaudRate);
|
||||
panda_dev->panda->set_uart_baud(panda::SERIAL_LIN2, BaudRate);
|
||||
};
|
||||
|
||||
unsigned long J2534Connection_ISO14230::validateTxMsg(PASSTHRU_MSG* msg) {
|
||||
if (msg->DataSize < this->getMinMsgLen() || msg->DataSize > this->getMaxMsgLen())
|
||||
return ERR_INVALID_MSG;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
std::shared_ptr<MessageTx> J2534Connection_ISO14230::parseMessageTx(PASSTHRU_MSG& msg) {
|
||||
return std::dynamic_pointer_cast<MessageTx>(std::make_shared<MessageTx_ISO14230>(shared_from_this(), msg));
|
||||
}
|
||||
|
||||
void J2534Connection_ISO14230::setBaud(unsigned long BaudRate) {
|
||||
if (auto panda_dev = this->getPandaDev()) {
|
||||
if (BaudRate % 100 || BaudRate < 2400 || BaudRate > 115200)
|
||||
throw ERR_NOT_SUPPORTED;
|
||||
|
||||
panda_dev->panda->set_uart_baud(panda::SERIAL_LIN1, BaudRate);
|
||||
panda_dev->panda->set_uart_baud(panda::SERIAL_LIN2, BaudRate);
|
||||
return J2534Connection::setBaud(BaudRate);
|
||||
} else {
|
||||
throw ERR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
void J2534Connection_ISO14230::setParity(unsigned long Parity) {
|
||||
if (auto panda_dev = this->getPandaDev()) {
|
||||
panda::PANDA_SERIAL_PORT_PARITY parity;
|
||||
switch (Parity) {
|
||||
case 0:
|
||||
parity = panda::PANDA_PARITY_OFF;
|
||||
break;
|
||||
case 1:
|
||||
parity = panda::PANDA_PARITY_ODD;
|
||||
break;
|
||||
case 2:
|
||||
parity = panda::PANDA_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
throw ERR_NOT_SUPPORTED;
|
||||
}
|
||||
panda_dev->panda->set_uart_parity(panda::SERIAL_LIN1, parity);
|
||||
panda_dev->panda->set_uart_parity(panda::SERIAL_LIN2, parity);
|
||||
return J2534Connection::setParity(Parity);
|
||||
}
|
||||
else {
|
||||
throw ERR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
void J2534Connection_ISO14230::processMessage(const J2534Frame& msg) {
|
||||
FILTER_RESULT filter_res = FILTER_RESULT_NEUTRAL;
|
||||
|
||||
for (auto filter : this->filters) {
|
||||
if (filter == nullptr) continue;
|
||||
FILTER_RESULT current_check_res = filter->check(msg);
|
||||
if (current_check_res == FILTER_RESULT_BLOCK) return;
|
||||
if (current_check_res == FILTER_RESULT_PASS) filter_res = FILTER_RESULT_PASS;
|
||||
}
|
||||
|
||||
if (filter_res == FILTER_RESULT_PASS) {
|
||||
addMsgToRxQueue(J2534Frame(msg.ProtocolID, START_OF_MESSAGE, 0, 0));
|
||||
addMsgToRxQueue(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "J2534Connection.h"
|
||||
#include "panda_shared/panda.h"
|
||||
|
||||
class J2534Connection_ISO14230 : public J2534Connection {
|
||||
public:
|
||||
J2534Connection_ISO14230(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
);
|
||||
|
||||
virtual unsigned long validateTxMsg(PASSTHRU_MSG* msg);
|
||||
|
||||
virtual std::shared_ptr<MessageTx> parseMessageTx(PASSTHRU_MSG& pMsg);
|
||||
|
||||
virtual void setBaud(unsigned long baud);
|
||||
virtual void setParity(unsigned long Parity);
|
||||
|
||||
virtual unsigned long getMinMsgLen() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgLen() {
|
||||
return KLINE_MSG_MAX_LEN;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgSingleFrameLen() {
|
||||
return KLINE_MSG_MAX_LEN;
|
||||
}
|
||||
|
||||
virtual bool isProtoCan() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
virtual void processMessage(const J2534Frame& msg);
|
||||
};
|
||||
@@ -1,232 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "J2534Connection_ISO15765.h"
|
||||
#include "Timer.h"
|
||||
#include "constants_ISO15765.h"
|
||||
#include <chrono>
|
||||
|
||||
J2534Connection_ISO15765::J2534Connection_ISO15765(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
) : J2534Connection(panda_dev, ProtocolID, Flags, BaudRate), wftMax(0) {
|
||||
this->port = 0;
|
||||
|
||||
if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000)
|
||||
throw ERR_INVALID_BAUDRATE;
|
||||
|
||||
panda_dev->panda->set_can_speed_cbps(panda::PANDA_CAN1, (uint16_t)(BaudRate / 100));
|
||||
}
|
||||
|
||||
unsigned long J2534Connection_ISO15765::validateTxMsg(PASSTHRU_MSG* msg) {
|
||||
if ((msg->DataSize < this->getMinMsgLen() + (msg_is_extaddr(msg) ? 1 : 0) ||
|
||||
msg->DataSize > this->getMaxMsgLen() + (msg_is_extaddr(msg) ? 1 : 0) ||
|
||||
(val_is_29bit(msg->TxFlags) != this->_is_29bit() && !check_bmask(this->Flags, CAN_ID_BOTH))))
|
||||
return ERR_INVALID_MSG;
|
||||
|
||||
int fid = get_matching_out_fc_filter_id(std::string((const char*)msg->Data, msg->DataSize), msg->TxFlags, 0xFFFFFFFF);
|
||||
if (msg->DataSize > getMaxMsgSingleFrameLen() && fid == -1) return ERR_NO_FLOW_CONTROL; //11 bytes (4 for CANid, 7 payload) is max length of input frame.
|
||||
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
std::shared_ptr<MessageTx> J2534Connection_ISO15765::parseMessageTx(PASSTHRU_MSG& msg) {
|
||||
int fid = get_matching_out_fc_filter_id(std::string((const char*)msg.Data, msg.DataSize), msg.TxFlags, 0xFFFFFFFF);
|
||||
if (msg.DataSize > getMaxMsgSingleFrameLen() && fid == -1) 1;
|
||||
|
||||
return std::dynamic_pointer_cast<MessageTx>(
|
||||
std::make_shared<MessageTx_ISO15765>(shared_from_this(), msg, (fid == -1) ? nullptr : this->filters[fid])
|
||||
);
|
||||
}
|
||||
|
||||
//https://happilyembedded.wordpress.com/2016/02/15/can-multiple-frame-transmission/
|
||||
void J2534Connection_ISO15765::processMessage(const J2534Frame& msg) {
|
||||
if (msg.ProtocolID != CAN) return;
|
||||
|
||||
int fid = get_matching_in_fc_filter_id(msg, this->Flags);
|
||||
if (fid == -1) return;
|
||||
|
||||
auto filter = this->filters[fid];
|
||||
bool is_ext_addr = check_bmask(filter->flags, ISO15765_ADDR_TYPE);
|
||||
uint8_t addrlen = is_ext_addr ? 5 : 4;
|
||||
|
||||
switch (msg_get_type(msg, addrlen)) {
|
||||
case FRAME_FLOWCTRL:
|
||||
{
|
||||
if (this->txbuff.size() == 0)
|
||||
return;
|
||||
if (msg.Data.size() < addrlen + 3) return;
|
||||
uint8_t flow_status = msg.Data[addrlen] & 0x0F;
|
||||
uint8_t block_size = msg.Data[addrlen + 1];
|
||||
uint8_t st_min = msg.Data[addrlen + 2];
|
||||
|
||||
auto txConvo = std::static_pointer_cast<MessageTx_ISO15765>(this->txbuff.front());
|
||||
switch (flow_status) {
|
||||
case FLOWCTRL_CONTINUE: {
|
||||
if (st_min > 0xF9) break;
|
||||
if (st_min >= 0xf1 && st_min <= 0xf9) {
|
||||
txConvo->flowControlContinue(block_size, std::chrono::microseconds((st_min & 0x0F) * 100));
|
||||
} else if(st_min <= 0x7f) {
|
||||
txConvo->flowControlContinue(block_size, std::chrono::microseconds(st_min * 1000));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
txConvo->scheduleImmediate();
|
||||
this->rescheduleExistingTxMsgs();
|
||||
break;
|
||||
}
|
||||
case FLOWCTRL_WAIT:
|
||||
txConvo->flowControlWait(this->wftMax);
|
||||
break;
|
||||
case FLOWCTRL_ABORT:
|
||||
txConvo->flowControlAbort();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FRAME_SINGLE:
|
||||
{
|
||||
this->rxConversations[fid] = nullptr; //Reset any current transaction.
|
||||
|
||||
if (is_ext_addr) {
|
||||
if ((msg.Data[5] & 0x0F) > 6) return;
|
||||
} else {
|
||||
if ((msg.Data[4] & 0x0F) > 7) return;
|
||||
}
|
||||
|
||||
J2534Frame outframe(ISO15765, msg.RxStatus, 0, msg.Timestamp);
|
||||
if (msg.Data.size() != 8 && check_bmask(this->Flags, ISO15765_FRAME_PAD))
|
||||
outframe.RxStatus |= ISO15765_PADDING_ERROR;
|
||||
if (is_ext_addr)
|
||||
outframe.RxStatus |= ISO15765_ADDR_TYPE;
|
||||
outframe.Data = msg.Data.substr(0, addrlen) + msg.Data.substr(addrlen + 1, msg.Data[addrlen]);
|
||||
outframe.ExtraDataIndex = outframe.Data.size();
|
||||
|
||||
addMsgToRxQueue(outframe);
|
||||
break;
|
||||
}
|
||||
case FRAME_FIRST:
|
||||
{
|
||||
if (msg.Data.size() < 12) {
|
||||
//A frame was received that could have held more data.
|
||||
//No examples of this protocol show that happening, so
|
||||
//it will be assumed that it is grounds to reset rx.
|
||||
this->rxConversations[fid] = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
J2534Frame outframe(ISO15765, msg.RxStatus | START_OF_MESSAGE, 0, msg.Timestamp);
|
||||
if (is_ext_addr)
|
||||
outframe.RxStatus |= ISO15765_ADDR_TYPE;
|
||||
outframe.Data = msg.Data.substr(0, addrlen);
|
||||
|
||||
addMsgToRxQueue(outframe);
|
||||
|
||||
this->rxConversations[fid] = std::make_shared<MessageRx>(
|
||||
((msg.Data[addrlen] & 0x0F) << 8) | msg.Data[addrlen + 1],
|
||||
msg.Data.substr(addrlen + 2, 12 - (addrlen + 2)),
|
||||
msg.RxStatus, filter);
|
||||
|
||||
//TODO maybe the flow control should also be scheduled in the TX list.
|
||||
//Doing it this way because the filter can be 5 bytes in ext address mode.
|
||||
std::string flowfilter = filter->get_flowctrl();
|
||||
uint32_t flow_addr = (((uint8_t)flowfilter[0]) << 24) | ((uint8_t)(flowfilter[1]) << 16) | ((uint8_t)(flowfilter[2]) << 8) | ((uint8_t)flowfilter[3]);
|
||||
|
||||
std::string flowstrlresp;
|
||||
if (flowfilter.size() > 4)
|
||||
flowstrlresp += flowfilter[4];
|
||||
flowstrlresp += std::string("\x30\x00\x00", 3);
|
||||
if (check_bmask(filter->flags, ISO15765_FRAME_PAD)) {
|
||||
flowstrlresp += std::string(8 - flowstrlresp.size(), '\x00');
|
||||
}
|
||||
|
||||
if (auto panda_dev_sp = this->panda_dev.lock()) {
|
||||
panda_dev_sp->panda->can_send(flow_addr, val_is_29bit(msg.RxStatus), (const uint8_t *)flowstrlresp.c_str(), (uint8_t)flowstrlresp.size(), panda::PANDA_CAN1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FRAME_CONSEC:
|
||||
{
|
||||
auto& convo = this->rxConversations[fid];
|
||||
if (convo == nullptr) return;
|
||||
|
||||
if (!convo->rx_add_frame(msg.Data[addrlen], (is_ext_addr ? 6 : 7), msg.Data.substr(addrlen + 1))) {
|
||||
//Delete this conversation.
|
||||
convo = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string final_msg;
|
||||
if (convo->flush_result(final_msg)) {
|
||||
convo = nullptr;
|
||||
J2534Frame outframe(ISO15765, msg.RxStatus, 0, msg.Timestamp);
|
||||
if (is_ext_addr)
|
||||
outframe.RxStatus |= ISO15765_ADDR_TYPE;
|
||||
outframe.Data = msg.Data.substr(0, addrlen) + final_msg;
|
||||
outframe.ExtraDataIndex = outframe.Data.size();
|
||||
|
||||
addMsgToRxQueue(outframe);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void J2534Connection_ISO15765::setBaud(unsigned long BaudRate) {
|
||||
if (auto panda_dev = this->getPandaDev()) {
|
||||
if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000)
|
||||
throw ERR_NOT_SUPPORTED;
|
||||
|
||||
panda_dev->panda->set_can_speed_cbps(panda::PANDA_CAN1, (uint16_t)(BaudRate / 100));
|
||||
return J2534Connection::setBaud(BaudRate);
|
||||
} else {
|
||||
throw ERR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
long J2534Connection_ISO15765::PassThruStartMsgFilter(unsigned long FilterType, PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg,
|
||||
PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID) {
|
||||
|
||||
if (FilterType != FLOW_CONTROL_FILTER) return ERR_INVALID_FILTER_ID;
|
||||
return J2534Connection::PassThruStartMsgFilter(FilterType, pMaskMsg, pPatternMsg, pFlowControlMsg, pFilterID);
|
||||
}
|
||||
|
||||
int J2534Connection_ISO15765::get_matching_out_fc_filter_id(const std::string& msgdata, unsigned long flags, unsigned long flagmask) {
|
||||
for (unsigned int i = 0; i < this->filters.size(); i++) {
|
||||
if (this->filters[i] == nullptr) continue;
|
||||
auto filter = this->filters[i]->get_flowctrl();
|
||||
if (filter == msgdata.substr(0, filter.size()) &&
|
||||
(this->filters[i]->flags & flagmask) == (flags & flagmask))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int J2534Connection_ISO15765::get_matching_in_fc_filter_id(const J2534Frame& msg, unsigned long flagmask) {
|
||||
for (unsigned int i = 0; i < this->filters.size(); i++) {
|
||||
if (this->filters[i] == nullptr) continue;
|
||||
if (this->filters[i]->check(msg) == FILTER_RESULT_MATCH &&
|
||||
(this->filters[i]->flags & flagmask) == (msg.RxStatus & flagmask))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void J2534Connection_ISO15765::processIOCTLSetConfig(unsigned long Parameter, unsigned long Value) {
|
||||
switch (Parameter) {
|
||||
case ISO15765_WFT_MAX:
|
||||
this->wftMax = Value;
|
||||
break;
|
||||
default:
|
||||
J2534Connection::processIOCTLSetConfig(Parameter, Value);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long J2534Connection_ISO15765::processIOCTLGetConfig(unsigned long Parameter) {
|
||||
switch (Parameter) {
|
||||
case ISO15765_WFT_MAX:
|
||||
return this->wftMax;
|
||||
default:
|
||||
return J2534Connection::processIOCTLGetConfig(Parameter);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "J2534Connection.h"
|
||||
#include "J2534Connection_CAN.h"
|
||||
#include "MessageTx_ISO15765.h"
|
||||
#include "MessageRx.h"
|
||||
|
||||
class MessageTx_ISO15765;
|
||||
|
||||
typedef struct {
|
||||
std::string dispatched_msg;
|
||||
std::string remaining_payload;
|
||||
} PRESTAGED_WRITE;
|
||||
|
||||
class J2534Connection_ISO15765 : public J2534Connection {
|
||||
public:
|
||||
J2534Connection_ISO15765(
|
||||
std::shared_ptr<PandaJ2534Device> panda_dev,
|
||||
unsigned long ProtocolID,
|
||||
unsigned long Flags,
|
||||
unsigned long BaudRate
|
||||
);
|
||||
|
||||
virtual long PassThruStartMsgFilter(unsigned long FilterType, PASSTHRU_MSG * pMaskMsg, PASSTHRU_MSG * pPatternMsg, PASSTHRU_MSG * pFlowControlMsg, unsigned long * pFilterID);
|
||||
|
||||
int get_matching_out_fc_filter_id(const std::string & msgdata, unsigned long flags, unsigned long flagmask);
|
||||
|
||||
int get_matching_in_fc_filter_id(const J2534Frame& msg, unsigned long flagmask);
|
||||
|
||||
virtual unsigned long validateTxMsg(PASSTHRU_MSG* msg);
|
||||
|
||||
virtual std::shared_ptr<MessageTx> parseMessageTx(PASSTHRU_MSG& msg);
|
||||
|
||||
virtual void processMessage(const J2534Frame& msg);
|
||||
|
||||
virtual void setBaud(unsigned long baud);
|
||||
|
||||
virtual void processIOCTLSetConfig(unsigned long Parameter, unsigned long Value);
|
||||
|
||||
virtual unsigned long processIOCTLGetConfig(unsigned long Parameter);
|
||||
|
||||
virtual unsigned long getMinMsgLen() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual unsigned long getMaxMsgLen() {
|
||||
return 4099;
|
||||
};
|
||||
|
||||
virtual unsigned long getMaxMsgSingleFrameLen() {
|
||||
return 11;
|
||||
}
|
||||
|
||||
virtual bool _is_29bit() {
|
||||
return (this->Flags & CAN_29BIT_ID) == CAN_29BIT_ID;
|
||||
}
|
||||
|
||||
virtual bool isProtoCan() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<std::shared_ptr<MessageRx>, 10> rxConversations;
|
||||
unsigned int wftMax;
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
#include "J2534_v0404.h"
|
||||
#include "panda_shared/panda.h"
|
||||
|
||||
/*A move convenient container for J2534 Messages than the static buffer provided by default.*/
|
||||
class J2534Frame {
|
||||
public:
|
||||
J2534Frame(unsigned long ProtocolID, unsigned long RxStatus=0, unsigned long TxFlags=0, unsigned long Timestamp=0) :
|
||||
ProtocolID(ProtocolID), RxStatus(RxStatus), TxFlags(TxFlags), Timestamp(Timestamp), ExtraDataIndex(0), Data("") { };
|
||||
|
||||
J2534Frame(const panda::PANDA_CAN_MSG& msg_in) {
|
||||
ProtocolID = CAN;
|
||||
ExtraDataIndex = msg_in.len + 4;
|
||||
Data.reserve(msg_in.len + 4);
|
||||
Data += msg_in.addr >> 24;
|
||||
Data += (msg_in.addr >> 16) & 0xFF;
|
||||
Data += (msg_in.addr >> 8) & 0xFF;
|
||||
Data += msg_in.addr & 0xFF;
|
||||
Data += std::string((char*)&msg_in.dat, msg_in.len);
|
||||
Timestamp = msg_in.recv_time;
|
||||
TxFlags = 0;
|
||||
RxStatus = (msg_in.addr_29b ? CAN_29BIT_ID : 0) |
|
||||
(msg_in.is_receipt ? TX_MSG_TYPE : 0);
|
||||
}
|
||||
|
||||
J2534Frame(unsigned long protocol, const panda::PANDA_KLINE_MSG& msg_in) {
|
||||
ProtocolID = protocol;
|
||||
ExtraDataIndex = msg_in.data.size() - (msg_in.valid ? 1 : 0);
|
||||
Data = msg_in.data;
|
||||
Timestamp = 0;
|
||||
TxFlags = 0;
|
||||
RxStatus = 0;
|
||||
}
|
||||
|
||||
J2534Frame(const PASSTHRU_MSG& msg) {
|
||||
this->ProtocolID = msg.ProtocolID;
|
||||
this->RxStatus = msg.RxStatus;
|
||||
this->TxFlags = msg.TxFlags;
|
||||
this->Timestamp = msg.Timestamp;
|
||||
this->ExtraDataIndex = msg.ExtraDataIndex;
|
||||
this->Data = std::string((const char*)msg.Data, msg.DataSize);
|
||||
}
|
||||
|
||||
J2534Frame() {
|
||||
this->ProtocolID = 0;
|
||||
this->RxStatus = 0;
|
||||
this->TxFlags = 0;
|
||||
this->Timestamp = 0;
|
||||
this->ExtraDataIndex = 0;
|
||||
}
|
||||
|
||||
unsigned long ProtocolID;
|
||||
unsigned long RxStatus;
|
||||
unsigned long TxFlags;
|
||||
unsigned long Timestamp;
|
||||
unsigned long ExtraDataIndex;
|
||||
std::string Data;
|
||||
};
|
||||
@@ -1,104 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "J2534MessageFilter.h"
|
||||
#include "J2534Frame.h"
|
||||
|
||||
J2534MessageFilter::J2534MessageFilter(
|
||||
J2534Connection *const conn,
|
||||
unsigned int filtertype,
|
||||
PASSTHRU_MSG *pMaskMsg,
|
||||
PASSTHRU_MSG *pPatternMsg,
|
||||
PASSTHRU_MSG *pFlowControlMsg
|
||||
) : filtertype(filtertype), flags(0), conn(conn) {
|
||||
switch (filtertype) {
|
||||
case PASS_FILTER:
|
||||
case BLOCK_FILTER:
|
||||
if (pMaskMsg == NULL || pPatternMsg == NULL)
|
||||
throw ERR_NULL_PARAMETER;
|
||||
if (pFlowControlMsg != NULL)
|
||||
throw ERR_INVALID_FILTER_ID;
|
||||
if (pMaskMsg->DataSize != pPatternMsg->DataSize)
|
||||
throw ERR_INVALID_MSG;
|
||||
break;
|
||||
case FLOW_CONTROL_FILTER:
|
||||
if (conn->getProtocol() != ISO15765) throw ERR_MSG_PROTOCOL_ID; //CHECK
|
||||
if (pFlowControlMsg == NULL || pMaskMsg == NULL || pPatternMsg == NULL)
|
||||
throw ERR_NULL_PARAMETER;
|
||||
break;
|
||||
default:
|
||||
throw ERR_INVALID_MSG;
|
||||
}
|
||||
|
||||
if (!(conn->getMinMsgLen() < pMaskMsg->DataSize || pMaskMsg->DataSize < conn->getMaxMsgLen()))
|
||||
throw ERR_INVALID_MSG;
|
||||
if (conn->getProtocol() != pMaskMsg->ProtocolID)
|
||||
throw ERR_MSG_PROTOCOL_ID;
|
||||
this->maskMsg = std::string((char*)pMaskMsg->Data, pMaskMsg->DataSize);
|
||||
|
||||
if (!(conn->getMinMsgLen() < pPatternMsg->DataSize || pPatternMsg->DataSize < conn->getMaxMsgLen()))
|
||||
throw ERR_INVALID_MSG;
|
||||
if (conn->getProtocol() != pPatternMsg->ProtocolID)
|
||||
throw ERR_MSG_PROTOCOL_ID;
|
||||
this->patternMsg = std::string((char*)pPatternMsg->Data, pPatternMsg->DataSize);
|
||||
if (this->maskMsg.size() != this->patternMsg.size())
|
||||
throw ERR_INVALID_MSG;
|
||||
|
||||
if (pFlowControlMsg) {
|
||||
if (!(conn->getMinMsgLen() < pFlowControlMsg->DataSize || pFlowControlMsg->DataSize < conn->getMaxMsgLen()))
|
||||
throw ERR_INVALID_MSG;
|
||||
if (conn->getProtocol() != pFlowControlMsg->ProtocolID)
|
||||
throw ERR_MSG_PROTOCOL_ID;
|
||||
if (pMaskMsg->TxFlags != pPatternMsg->TxFlags || pMaskMsg->TxFlags != pFlowControlMsg->TxFlags)
|
||||
throw ERR_INVALID_MSG;
|
||||
if(pFlowControlMsg->TxFlags & ~(ISO15765_FRAME_PAD | CAN_29BIT_ID | ISO15765_ADDR_TYPE))
|
||||
throw ERR_INVALID_MSG;
|
||||
if ((pFlowControlMsg->TxFlags & ISO15765_ADDR_TYPE) == ISO15765_ADDR_TYPE) {
|
||||
if(pFlowControlMsg->DataSize != 5)
|
||||
throw ERR_INVALID_MSG;
|
||||
} else {
|
||||
if (pFlowControlMsg->DataSize != 4)
|
||||
throw ERR_INVALID_MSG;
|
||||
}
|
||||
this->flowCtrlMsg = std::string((char*)pFlowControlMsg->Data, pFlowControlMsg->DataSize);
|
||||
if (this->flowCtrlMsg.size() != this->patternMsg.size())
|
||||
throw ERR_INVALID_MSG;
|
||||
this->flags = pFlowControlMsg->TxFlags;
|
||||
}
|
||||
}
|
||||
|
||||
bool J2534MessageFilter::operator ==(const J2534MessageFilter &b) const {
|
||||
if (this->filtertype != b.filtertype) return FALSE;
|
||||
if (this->maskMsg != b.maskMsg) return FALSE;
|
||||
if (this->patternMsg != b.patternMsg) return FALSE;
|
||||
if (this->flowCtrlMsg != b.flowCtrlMsg) return FALSE;
|
||||
if (this->flags != b.flags) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FILTER_RESULT J2534MessageFilter::check(const J2534Frame& msg) {
|
||||
bool matches = TRUE;
|
||||
if (msg.Data.size() < this->maskMsg.size()) {
|
||||
matches = FALSE;
|
||||
} else {
|
||||
for (unsigned int i = 0; i < this->maskMsg.size(); i++) {
|
||||
if (this->patternMsg[i] != (msg.Data[i] & this->maskMsg[i])) {
|
||||
matches = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (this->filtertype) {
|
||||
case PASS_FILTER:
|
||||
return matches ? FILTER_RESULT_PASS : FILTER_RESULT_NEUTRAL;
|
||||
case BLOCK_FILTER:
|
||||
return matches ? FILTER_RESULT_BLOCK: FILTER_RESULT_NEUTRAL;
|
||||
case FLOW_CONTROL_FILTER:
|
||||
return matches ? FILTER_RESULT_MATCH : FILTER_RESULT_NOMATCH;
|
||||
default:
|
||||
throw std::out_of_range("Filtertype should not be able to be anything but PASS, BLOCK, or FLOW_CONTROL");
|
||||
}
|
||||
}
|
||||
|
||||
std::string J2534MessageFilter::get_flowctrl() {
|
||||
return std::string(this->flowCtrlMsg);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#pragma once
|
||||
#include "J2534_v0404.h"
|
||||
#include "J2534Connection.h"
|
||||
#include "J2534Frame.h"
|
||||
|
||||
typedef enum {
|
||||
FILTER_RESULT_BLOCK,
|
||||
FILTER_RESULT_NEUTRAL,
|
||||
FILTER_RESULT_PASS,
|
||||
FILTER_RESULT_NOMATCH = FILTER_RESULT_BLOCK,
|
||||
FILTER_RESULT_MATCH = FILTER_RESULT_PASS,
|
||||
} FILTER_RESULT;
|
||||
|
||||
//Forward declare
|
||||
class J2534Connection;
|
||||
|
||||
/* Represents a J2534 Message Filter created by PassThruStartMsgFilter.
|
||||
|
||||
J2534 uses filters to sort out messages in a simple and sane way. Except for
|
||||
flow control filters. J2534 v04.04 uses filters to manage 'conversations' in
|
||||
protocols that support flow control like ISO15765. The whole solution is a
|
||||
hack, and J2534 v05.00 greatly simplifies this concept. But we are using
|
||||
v04.04 so, here we are.
|
||||
*/
|
||||
class J2534MessageFilter {
|
||||
public:
|
||||
J2534MessageFilter(
|
||||
J2534Connection *const conn,
|
||||
unsigned int filtertype,
|
||||
PASSTHRU_MSG *pMaskMsg,
|
||||
PASSTHRU_MSG *pPatternMsg,
|
||||
PASSTHRU_MSG *pFlowControlMsg
|
||||
);
|
||||
|
||||
bool J2534MessageFilter::operator ==(const J2534MessageFilter &b) const;
|
||||
|
||||
FILTER_RESULT check(const J2534Frame& msg);
|
||||
std::string get_flowctrl();
|
||||
|
||||
unsigned long flags;
|
||||
J2534Connection *const conn;
|
||||
private:
|
||||
unsigned int filtertype;
|
||||
std::string maskMsg;
|
||||
std::string patternMsg;
|
||||
std::string flowCtrlMsg;
|
||||
};
|
||||
@@ -1,428 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2015-2016 DashLogic, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// http://www.dashlogic.com
|
||||
// sales@dashlogic.com
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, including use for commercial purposes, are permitted
|
||||
// provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// 4. Redistributions of any form whatsoever must retain the following
|
||||
// acknowledgment: 'This product includes software developed by
|
||||
// "DashLogic, Inc." (http://www.dashlogic.com/).'
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Formatting:
|
||||
// Indents: Use tabs only (1 tab per indent)
|
||||
// Tab Size: 4 spaces
|
||||
//
|
||||
// File Revision:
|
||||
// $Rev: 5216 $
|
||||
// $Date: 2016-03-15 09:32:34 -0600 (Tue, 15 Mar 2016) $
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef PANDAJ2534DLL_EXPORTS
|
||||
#define PANDAJ2534DLL_API extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define PANDAJ2534DLL_API
|
||||
//__declspec(dllimport)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Platform-specific Defines:
|
||||
//
|
||||
// PTAPI: Define this yourself if you want a specific calling
|
||||
// convention or other modifiers on the Pass-Thru API
|
||||
// functions. Typically, on Windows, PTAPI will be defined
|
||||
// as WINAPI, which enables the __stdcall convention.
|
||||
//
|
||||
#define PTAPI __stdcall //WINAPI
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 ProtocolID Values
|
||||
//
|
||||
#define J1850VPW 0x01
|
||||
#define J1850PWM 0x02
|
||||
#define ISO9141 0x03
|
||||
#define ISO14230 0x04
|
||||
#define CAN 0x05
|
||||
#define ISO15765 0x06
|
||||
#define SCI_A_ENGINE 0x07
|
||||
#define SCI_A_TRANS 0x08
|
||||
#define SCI_B_ENGINE 0x09
|
||||
#define SCI_B_TRANS 0x0A
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 ProtocolID Values
|
||||
//
|
||||
#define J1850VPW_PS 0x00008000
|
||||
#define J1850PWM_PS 0x00008001
|
||||
#define ISO9141_PS 0x00008002
|
||||
#define ISO14230_PS 0x00008003
|
||||
#define CAN_PS 0x00008004
|
||||
#define ISO15765_PS 0x00008005
|
||||
#define J2610_PS 0x00008006
|
||||
#define SW_ISO15765_PS 0x00008007
|
||||
#define SW_CAN_PS 0x00008008
|
||||
#define GM_UART_PS 0x00008009
|
||||
#define CAN_CH1 0x00009000
|
||||
#define CAN_CH2 (CAN_CH1 + 1)
|
||||
#define CAN_CH128 (CAN_CH1 + 127)
|
||||
#define J1850VPW_CH1 0x00009080
|
||||
#define J1850VPW_CH2 (J1850VPW_CH1 + 1)
|
||||
#define J1850VPW_CH128 (J1850VPW_CH1 + 127)
|
||||
#define J1850PWM_CH1 0x00009160
|
||||
#define J1850PWM_CH2 (J1850PWM_CH1 + 1)
|
||||
#define J1850PWM_CH128 (J1850PWM_CH1 + 127)
|
||||
#define ISO9141_CH1 0x00009240
|
||||
#define ISO9141_CH2 (ISO9141_CH1 + 1)
|
||||
#define ISO9141_CH128 (ISO9141_CH1 + 127)
|
||||
#define ISO14230_CH1 0x00009320
|
||||
#define ISO14230_CH2 (ISO14230_CH1 + 1)
|
||||
#define ISO14230_CH128 (ISO14230_CH1 + 127)
|
||||
#define ISO15765_CH1 0x00009400
|
||||
#define ISO15765_CH2 (ISO15765_CH1 + 1)
|
||||
#define ISO15765_CH128 (ISO15765_CH1 + 127)
|
||||
#define SW_CAN_CAN_CH1 0x00009480
|
||||
#define SW_CAN_CAN_CH2 (SW_CAN_CAN_CH1 + 1)
|
||||
#define SW_CAN_CAN_CH128 (SW_CAN_CAN_CH1 + 127)
|
||||
#define SW_CAN_ISO15765_CH1 0x00009560
|
||||
#define SW_CAN_ISO15765_CH2 (SW_CAN_ISO15765_CH1 + 1)
|
||||
#define SW_CAN_ISO15765_CH128 (SW_CAN_ISO15765_CH1 + 127)
|
||||
#define J2610_CH1 0x00009640
|
||||
#define J2610_CH2 (J2610_CH1 + 1)
|
||||
#define J2610_CH128 (J2610_CH1 + 127)
|
||||
#define ANALOG_IN_CH1 0x0000C000
|
||||
#define ANALOG_IN_CH2 0x0000C001
|
||||
#define ANALOG_IN_CH32 0x0000C01F
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Error Values
|
||||
//
|
||||
#define STATUS_NOERROR 0x00 // Function call successful.
|
||||
#define ERR_NOT_SUPPORTED 0x01 // Device cannot support requested functionality mandated in J2534. Device is not fully SAE J2534 compliant.
|
||||
#define ERR_INVALID_CHANNEL_ID 0x02 // Invalid ChannelID value.
|
||||
#define ERR_INVALID_PROTOCOL_ID 0x03 // Invalid or unsupported ProtocolID, or there is a resource conflict (i.e. trying to connect to multiple mutually exclusive protocols such as J1850PWM and J1850VPW, or CAN and SCI, etc.).
|
||||
#define ERR_NULL_PARAMETER 0x04 // NULL pointer supplied where a valid pointer is required.
|
||||
#define ERR_INVALID_IOCTL_VALUE 0x05 // Invalid value for Ioctl parameter.
|
||||
#define ERR_INVALID_FLAGS 0x06 // Invalid flag values.
|
||||
#define ERR_FAILED 0x07 // Undefined error, use PassThruGetLastError() for text description.
|
||||
#define ERR_DEVICE_NOT_CONNECTED 0x08 // Unable to communicate with device.
|
||||
#define ERR_TIMEOUT 0x09 // Read or write timeout:
|
||||
// PassThruReadMsgs() - No message available to read or could not read the specified number of messages. The actual number of messages read is placed in <NumMsgs>.
|
||||
// PassThruWriteMsgs() - Device could not write the specified number of messages. The actual number of messages sent on the vehicle network is placed in <NumMsgs>.
|
||||
#define ERR_INVALID_MSG 0x0A // Invalid message structure pointed to by pMsg.
|
||||
#define ERR_INVALID_TIME_INTERVAL 0x0B // Invalid TimeInterval value.
|
||||
#define ERR_EXCEEDED_LIMIT 0x0C // Exceeded maximum number of message IDs or allocated space.
|
||||
#define ERR_INVALID_MSG_ID 0x0D // Invalid MsgID value.
|
||||
#define ERR_DEVICE_IN_USE 0x0E // Device is currently open.
|
||||
#define ERR_INVALID_IOCTL_ID 0x0F // Invalid IoctlID value.
|
||||
#define ERR_BUFFER_EMPTY 0x10 // Protocol message buffer empty, no messages available to read.
|
||||
#define ERR_BUFFER_FULL 0x11 // Protocol message buffer full. All the messages specified may not have been transmitted.
|
||||
#define ERR_BUFFER_OVERFLOW 0x12 // Indicates a buffer overflow occurred and messages were lost.
|
||||
#define ERR_PIN_INVALID 0x13 // Invalid pin number, pin number already in use, or voltage already applied to a different pin.
|
||||
#define ERR_CHANNEL_IN_USE 0x14 // Channel number is currently connected.
|
||||
#define ERR_MSG_PROTOCOL_ID 0x15 // Protocol type in the message does not match the protocol associated with the Channel ID
|
||||
#define ERR_INVALID_FILTER_ID 0x16 // Invalid Filter ID value.
|
||||
#define ERR_NO_FLOW_CONTROL 0x17 // No flow control filter set or matched (for ProtocolID ISO15765 only).
|
||||
#define ERR_NOT_UNIQUE 0x18 // A CAN ID in pPatternMsg or pFlowControlMsg matches either ID in an existing FLOW_CONTROL_FILTER
|
||||
#define ERR_INVALID_BAUDRATE 0x19 // The desired baud rate cannot be achieved within the tolerance specified in SAE J2534-1 Section 6.5
|
||||
#define ERR_INVALID_DEVICE_ID 0x1A // Device ID invalid.
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Connect Flags
|
||||
//
|
||||
#define CAN_29BIT_ID 0x0100
|
||||
#define ISO9141_NO_CHECKSUM 0x0200
|
||||
#define CAN_ID_BOTH 0x0800
|
||||
#define ISO9141_K_LINE_ONLY 0x1000
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Filter Type Values
|
||||
//
|
||||
#define PASS_FILTER 0x00000001
|
||||
#define BLOCK_FILTER 0x00000002
|
||||
#define FLOW_CONTROL_FILTER 0x00000003
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Programming Voltage Pin Numbers
|
||||
//
|
||||
#define AUXILIARY_OUTPUT_PIN 0
|
||||
#define SAE_J1962_CONNECTOR_PIN_6 6
|
||||
#define SAE_J1962_CONNECTOR_PIN_9 9
|
||||
#define SAE_J1962_CONNECTOR_PIN_11 11
|
||||
#define SAE_J1962_CONNECTOR_PIN_12 12
|
||||
#define SAE_J1962_CONNECTOR_PIN_13 13
|
||||
#define SAE_J1962_CONNECTOR_PIN_14 14
|
||||
#define SAE_J1962_CONNECTOR_PIN_15 15 // Short to ground only
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Programming Voltage Values
|
||||
//
|
||||
#define SHORT_TO_GROUND 0xFFFFFFFE
|
||||
#define VOLTAGE_OFF 0xFFFFFFFF
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 API Version Values
|
||||
//
|
||||
#define J2534_APIVER_FEBRUARY_2002 "02.02"
|
||||
#define J2534_APIVER_NOVEMBER_2004 "04.04"
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 IOCTL ID Values
|
||||
//
|
||||
#define GET_CONFIG 0x01 // pInput = SCONFIG_LIST, pOutput = NULL
|
||||
#define SET_CONFIG 0x02 // pInput = SCONFIG_LIST, pOutput = NULL
|
||||
#define READ_VBATT 0x03 // pInput = NULL, pOutput = unsigned long
|
||||
#define FIVE_BAUD_INIT 0x04 // pInput = SBYTE_ARRAY, pOutput = SBYTE_ARRAY
|
||||
#define FAST_INIT 0x05 // pInput = PASSTHRU_MSG, pOutput = PASSTHRU_MSG
|
||||
#define CLEAR_TX_BUFFER 0x07 // pInput = NULL, pOutput = NULL
|
||||
#define CLEAR_RX_BUFFER 0x08 // pInput = NULL, pOutput = NULL
|
||||
#define CLEAR_PERIODIC_MSGS 0x09 // pInput = NULL, pOutput = NULL
|
||||
#define CLEAR_MSG_FILTERS 0x0A // pInput = NULL, pOutput = NULL
|
||||
#define CLEAR_FUNCT_MSG_LOOKUP_TABLE 0x0B // pInput = NULL, pOutput = NULL
|
||||
#define ADD_TO_FUNCT_MSG_LOOKUP_TABLE 0x0C // pInput = SBYTE_ARRAY, pOutput = NULL
|
||||
#define DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE 0x0D // pInput = SBYTE_ARRAY, pOutput = NULL
|
||||
#define READ_PROG_VOLTAGE 0x0E // pInput = NULL, pOutput = unsigned long
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 IOCTL ID Values
|
||||
//
|
||||
#define SW_CAN_HS 0x00008000 // pInput = NULL, pOutput = NULL
|
||||
#define SW_CAN_NS 0x00008001 // pInput = NULL, pOutput = NULL
|
||||
#define SET_POLL_RESPONSE 0x00008002 // pInput = SBYTE_ARRAY, pOutput = NULL
|
||||
#define BECOME_MASTER 0x00008003 // pInput = unsigned char, pOutput = NULL
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Configuration Parameter Values
|
||||
// Default value is enclosed in square brackets "[" and "]"
|
||||
//
|
||||
#define DATA_RATE 0x01 // 5-500000
|
||||
#define LOOPBACK 0x03 // 0 (OFF), 1 (ON) [0]
|
||||
#define NODE_ADDRESS 0x04 // J1850PWM: 0x00-0xFF
|
||||
#define NETWORK_LINE 0x05 // J1850PWM: 0 (BUS_NORMAL), 1 (BUS_PLUS), 2 (BUS_MINUS) [0]
|
||||
#define P1_MIN 0x06 // ISO9141 or ISO14230: Not used by interface
|
||||
#define P1_MAX 0x07 // ISO9141 or ISO14230: 0x1-0xFFFF (.5 ms per bit) [40 (20ms)]
|
||||
#define P2_MIN 0x08 // ISO9141 or ISO14230: Not used by interface
|
||||
#define P2_MAX 0x09 // ISO9141 or ISO14230: Not used by interface
|
||||
#define P3_MIN 0x0A // ISO9141 or ISO14230: 0x0-0xFFFF (.5 ms per bit) [110 (55ms)]
|
||||
#define P3_MAX 0x0B // ISO9141 or ISO14230: Not used by interface
|
||||
#define P4_MIN 0x0C // ISO9141 or ISO14230: 0x0-0xFFFF (.5 ms per bit) [10 (5ms)]
|
||||
#define P4_MAX 0x0D // ISO9141 or ISO14230: Not used by interface
|
||||
#define W0 0x19 // ISO9141: 0x0-0xFFFF (1 ms per bit) [300]
|
||||
#define W1 0x0E // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [300]
|
||||
#define W2 0x0F // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [20]
|
||||
#define W3 0x10 // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [20]
|
||||
#define W4 0x11 // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [50]
|
||||
#define W5 0x12 // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [300]
|
||||
#define TIDLE 0x13 // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [300]
|
||||
#define TINIL 0x14 // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [25]
|
||||
#define TWUP 0x15 // ISO9141 or ISO14230: 0x0-0xFFFF (1 ms per bit) [50]
|
||||
#define PARITY 0x16 // ISO9141 or ISO14230: 0 (NO_PARITY), 1 (ODD_PARITY), 2 (EVEN_PARITY) [0]
|
||||
#define BIT_SAMPLE_POINT 0x17 // CAN: 0-100 (1% per bit) [80]
|
||||
#define SYNC_JUMP_WIDTH 0x18 // CAN: 0-100 (1% per bit) [15]
|
||||
#define T1_MAX 0x1A // SCI: 0x0-0xFFFF (1 ms per bit) [20]
|
||||
#define T2_MAX 0x1B // SCI: 0x0-0xFFFF (1 ms per bit) [100]
|
||||
#define T3_MAX 0x24 // SCI: 0x0-0xFFFF (1 ms per bit) [50]
|
||||
#define T4_MAX 0x1C // SCI: 0x0-0xFFFF (1 ms per bit) [20]
|
||||
#define T5_MAX 0x1D // SCI: 0x0-0xFFFF (1 ms per bit) [100]
|
||||
#define ISO15765_BS 0x1E // ISO15765: 0x0-0xFF [0]
|
||||
#define ISO15765_STMIN 0x1F // ISO15765: 0x0-0xFF [0]
|
||||
#define ISO15765_BS_TX 0x22 // ISO15765: 0x0-0xFF,0xFFFF [0xFFFF]
|
||||
#define ISO15765_STMIN_TX 0x23 // ISO15765: 0x0-0xFF,0xFFFF [0xFFFF]
|
||||
#define DATA_BITS 0x20 // ISO9141 or ISO14230: 0 (8 data bits), 1 (7 data bits) [0]
|
||||
#define FIVE_BAUD_MOD 0x21 // ISO9141 or ISO14230: 0 (ISO 9141-2/14230-4), 1 (Inv KB2), 2 (Inv Addr), 3 (ISO 9141) [0]
|
||||
#define ISO15765_WFT_MAX 0x25 // ISO15765: 0x0-0xFF [0]
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 Configuration Parameter Values
|
||||
// Default value is enclosed in square brackets "[" and "]"
|
||||
//
|
||||
#define CAN_MIXED_FORMAT 0x00008000 // See #defines below. [0]
|
||||
#define J1962_PINS 0x00008001 // 0xPPSS PP: 0x00-0x10 SS: 0x00-0x10 PP!=SS, except 0x0000. Exclude pins 4, 5, and 16. [0]
|
||||
#define SW_CAN_HS_DATA_RATE 0x00008010 // SWCAN: 5-500000 [83333]
|
||||
#define SW_CAN_SPEEDCHANGE_ENABLE 0x00008011 // SWCAN: 0 (DISABLE_SPDCHANGE), 1 (ENABLE_SPDCHANGE) [0]
|
||||
#define SW_CAN_RES_SWITCH 0x00008012 // SWCAN: 0 (DISCONNECT_RESISTOR), 1 (CONNECT_RESISTOR), 2 (AUTO_ RESISTOR) [0]
|
||||
#define ACTIVE_CHANNELS 0x00008020 // ANALOG: 0-0xFFFFFFFF
|
||||
#define SAMPLE_RATE 0x00008021 // ANALOG: 0-0xFFFFFFFF [0] (high bit changes meaning from samples/sec to seconds/sample)
|
||||
#define SAMPLES_PER_READING 0x00008022 // ANALOG: 1-0xFFFFFFFF [1]
|
||||
#define READINGS_PER_MSG 0x00008023 // ANALOG: 1-0x00000408 (1 - 1032) [1]
|
||||
#define AVERAGING_METHOD 0x00008024 // ANALOG: 0-0xFFFFFFFF [0]
|
||||
#define SAMPLE_RESOLUTION 0x00008025 // ANALOG READ-ONLY: 0x1-0x20 (1 - 32)
|
||||
#define INPUT_RANGE_LOW 0x00008026 // ANALOG READ-ONLY: 0x80000000-0x7FFFFFFF (-2147483648-2147483647)
|
||||
#define INPUT_RANGE_HIGH 0x00008027 // ANALOG READ-ONLY: 0x80000000-0x7FFFFFFF (-2147483648-2147483647)
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 Mixed-Mode/Format CAN Definitions
|
||||
//
|
||||
#define CAN_MIXED_FORMAT_OFF 0 // Messages will be treated as ISO 15765 ONLY.
|
||||
#define CAN_MIXED_FORMAT_ON 1 // Messages will be treated as either ISO 15765 or an unformatted CAN frame.
|
||||
#define CAN_MIXED_FORMAT_ALL_FRAMES 2 // Messages will be treated as ISO 15765, an unformatted CAN frame, or both.
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 Analog Channel Averaging Method Definitions
|
||||
//
|
||||
#define SIMPLE_AVERAGE 0x00000000 // Simple arithmetic mean
|
||||
#define MAX_LIMIT_AVERAGE 0x00000001 // Choose the biggest value
|
||||
#define MIN_LIMIT_AVERAGE 0x00000002 // Choose the lowest value
|
||||
#define MEDIAN_AVERAGE 0x00000003 // Choose arithmetic median
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 RxStatus Definitions
|
||||
//
|
||||
#define TX_MSG_TYPE 0x0001
|
||||
#define START_OF_MESSAGE 0x0002
|
||||
#define RX_BREAK 0x0004
|
||||
#define TX_INDICATION 0x0008
|
||||
#define ISO15765_PADDING_ERROR 0x0010
|
||||
#define ISO15765_ADDR_TYPE 0x0080
|
||||
//#define CAN_29BIT_ID 0x0100 // Defined above
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 RxStatus Definitions
|
||||
//
|
||||
#define SW_CAN_HV_RX 0x00010000 // SWCAN Channels Only
|
||||
#define SW_CAN_HS_RX 0x00020000 // SWCAN Channels Only
|
||||
#define SW_CAN_NS_RX 0x00040000 // SWCAN Channels Only
|
||||
#define OVERFLOW_ 0x00010000 // Analog Input Channels Only
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 TxFlags Definitions
|
||||
//
|
||||
#define ISO15765_FRAME_PAD 0x0040
|
||||
//#define ISO15765_ADDR_TYPE 0x0080 // Defined above
|
||||
//#define CAN_29BIT_ID 0x0100 // Defined above
|
||||
#define WAIT_P3_MIN_ONLY 0x0200
|
||||
#define SCI_MODE 0x400000
|
||||
#define SCI_TX_VOLTAGE 0x800000
|
||||
|
||||
|
||||
//
|
||||
// J2534-2 TxFlags Definitions
|
||||
//
|
||||
#define SW_CAN_HV_TX 0x00000400
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Structure Definitions
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
unsigned long Parameter; // Name of parameter
|
||||
unsigned long Value; // Value of the parameter
|
||||
} SCONFIG;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long NumOfParams; // Number of SCONFIG elements
|
||||
SCONFIG* ConfigPtr; // Array of SCONFIG
|
||||
} SCONFIG_LIST;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long NumOfBytes; // Number of bytes in the array
|
||||
unsigned char* BytePtr; // Array of bytes
|
||||
} SBYTE_ARRAY;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long ProtocolID;
|
||||
unsigned long RxStatus;
|
||||
unsigned long TxFlags;
|
||||
unsigned long Timestamp;
|
||||
unsigned long DataSize;
|
||||
unsigned long ExtraDataIndex;
|
||||
unsigned char Data[4128];
|
||||
} PASSTHRU_MSG;
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Function Prototypes
|
||||
//
|
||||
PANDAJ2534DLL_API long PTAPI PassThruOpen(void *pName, unsigned long *pDeviceID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruClose(unsigned long DeviceID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruConnect(unsigned long DeviceID, unsigned long ProtocolID, unsigned long Flags, unsigned long BaudRate, unsigned long *pChannelID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruDisconnect(unsigned long ChannelID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruWriteMsgs(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStartPeriodicMsg(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pMsgID, unsigned long TimeInterval);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStopPeriodicMsg(unsigned long ChannelID, unsigned long MsgID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStartMsgFilter(unsigned long ChannelID, unsigned long FilterType, PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg, PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStopMsgFilter(unsigned long ChannelID, unsigned long FilterID);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruSetProgrammingVoltage(unsigned long DeviceID, unsigned long PinNumber, unsigned long Voltage);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruReadVersion(unsigned long DeviceID, char *pFirmwareVersion, char *pDllVersion, char *pApiVersion);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruGetLastError(char *pErrorDescription);
|
||||
PANDAJ2534DLL_API long PTAPI PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput);
|
||||
|
||||
|
||||
//
|
||||
// J2534-1 v04.04 Function Typedefs
|
||||
// These function typedefs allow simpler use of the J2534 API by
|
||||
// allowing you to do things like this:
|
||||
// PTCONNECT pPassThruConnectFunc = GetProcAddress(hModule, "PassThruConnect");
|
||||
// if (pPassThruConnectFunc == NULL)
|
||||
// return FALSE;
|
||||
// pPassThruConnectFunc(DeviceID, CAN, CAN_29BIT_ID, 500000, &ChannelID);
|
||||
//
|
||||
typedef long (PTAPI *PTOPEN)(void *pName, unsigned long *pDeviceID);
|
||||
typedef long (PTAPI *PTCLOSE)(unsigned long DeviceID);
|
||||
typedef long (PTAPI *PTCONNECT)(unsigned long DeviceID, unsigned long ProtocolID, unsigned long Flags, unsigned long BaudRate, unsigned long *pChannelID);
|
||||
typedef long (PTAPI *PTDISCONNECT)(unsigned long ChannelID);
|
||||
typedef long (PTAPI *PTREADMSGS)(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout);
|
||||
typedef long (PTAPI *PTWRITEMSGS)(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout);
|
||||
typedef long (PTAPI *PTSTARTPERIODICMSG)(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pMsgID, unsigned long TimeInterval);
|
||||
typedef long (PTAPI *PTSTOPPERIODICMSG)(unsigned long ChannelID, unsigned long MsgID);
|
||||
typedef long (PTAPI *PTSTARTMSGFILTER)(unsigned long ChannelID, unsigned long FilterType, PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg, PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID);
|
||||
typedef long (PTAPI *PTSTOPMSGFILTER)(unsigned long ChannelID, unsigned long FilterID);
|
||||
typedef long (PTAPI *PTSETPROGRAMMINGVOLTAGE)(unsigned long DeviceID, unsigned long PinNumber, unsigned long Voltage);
|
||||
typedef long (PTAPI *PTREADVERSION)(unsigned long DeviceID, char *pFirmwareVersion, char *pDllVersion, char *pApiVersion);
|
||||
typedef long (PTAPI *PTGETLASTERROR)(char *pErrorDescription);
|
||||
typedef long (PTAPI *PTIOCTL)(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput);
|
||||
@@ -1,30 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "MessagePeriodic.h"
|
||||
#include "J2534Connection.h"
|
||||
|
||||
MessagePeriodic::MessagePeriodic(
|
||||
std::chrono::microseconds delay,
|
||||
std::shared_ptr<MessageTx> msg
|
||||
) : Action(msg->connection, delay), msg(msg), runyet(FALSE), active(TRUE) { };
|
||||
|
||||
void MessagePeriodic::execute() {
|
||||
if (!this->active) return;
|
||||
if (this->runyet) {
|
||||
if (msg->isFinished()) {
|
||||
msg->reset();
|
||||
msg->execute();
|
||||
}
|
||||
} else {
|
||||
this->runyet = TRUE;
|
||||
msg->execute();
|
||||
}
|
||||
|
||||
if (auto conn_sp = this->connection.lock()) {
|
||||
if (auto panda_dev_sp = conn_sp->getPandaDev()) {
|
||||
//Scheduling must be relative to now incase there was a long stall that
|
||||
//would case it to be super far behind and try to catch up forever.
|
||||
this->scheduleImmediateDelay();
|
||||
panda_dev_sp->insertActionIntoTaskList(shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
#include "Action.h"
|
||||
#include "MessageTx.h"
|
||||
|
||||
class J2534Connection;
|
||||
|
||||
/* A message that is resent on a given period. Created with calls to PassThruStartPeriodicMessage.
|
||||
|
||||
Instead of making each J2534 protocol implementation have to implement periodic message
|
||||
functionality, this class takes a message to be sent, and passes along the execute call
|
||||
to the message, then reschedules itself.
|
||||
*/
|
||||
class MessagePeriodic : public Action, public std::enable_shared_from_this<Action>
|
||||
{
|
||||
public:
|
||||
MessagePeriodic(
|
||||
std::chrono::microseconds delay,
|
||||
std::shared_ptr<MessageTx> msg
|
||||
);
|
||||
|
||||
virtual void execute();
|
||||
|
||||
void cancel() {
|
||||
this->active = FALSE;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<MessageTx> msg;
|
||||
|
||||
private:
|
||||
BOOL runyet;
|
||||
BOOL active;
|
||||
};
|
||||
@@ -1,61 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class MessageRx
|
||||
{
|
||||
public:
|
||||
MessageRx(
|
||||
unsigned long size,
|
||||
std::string piece,
|
||||
unsigned long rxFlags,
|
||||
std::shared_ptr<J2534MessageFilter> filter
|
||||
) : expected_size(size & 0xFFF), flags(rxFlags) {
|
||||
msg.reserve(expected_size);
|
||||
msg = piece;
|
||||
next_part = 1;
|
||||
};
|
||||
|
||||
bool rx_add_frame(uint8_t pci_byte, unsigned int max_packet_size, const std::string piece) {
|
||||
if ((pci_byte & 0x0F) != this->next_part) {
|
||||
//TODO: Maybe this should instantly fail the transaction.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
this->next_part = (this->next_part + 1) % 0x10;
|
||||
unsigned int payload_len = min(expected_size - msg.size(), max_packet_size);
|
||||
if (piece.size() < payload_len) {
|
||||
//A frame was received that could have held more data.
|
||||
//No examples of this protocol show that happening, so
|
||||
//it will be assumed that it is grounds to reset rx.
|
||||
return FALSE;
|
||||
}
|
||||
msg += piece.substr(0, payload_len);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned int bytes_remaining() {
|
||||
return this->expected_size - this->msg.size();
|
||||
}
|
||||
|
||||
bool is_ready() {
|
||||
return this->msg.size() == this->expected_size;
|
||||
}
|
||||
|
||||
bool flush_result(std::string& final_msg) {
|
||||
if (this->msg.size() == this->expected_size) {
|
||||
final_msg = this->msg;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint8_t getNextConsecutiveFrameId() {
|
||||
return this->next_part++;
|
||||
}
|
||||
|
||||
std::weak_ptr<J2534MessageFilter> filter;
|
||||
unsigned long flags;
|
||||
unsigned long expected_size;
|
||||
std::string msg;
|
||||
unsigned char next_part;
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#include "Action.h"
|
||||
#include "J2534Frame.h"
|
||||
|
||||
class J2534Connection;
|
||||
|
||||
class MessageTx : public Action, public std::enable_shared_from_this<MessageTx>
|
||||
{
|
||||
public:
|
||||
MessageTx(
|
||||
std::weak_ptr<J2534Connection> connection_in,
|
||||
PASSTHRU_MSG& to_send
|
||||
) : Action(connection_in), fullmsg(to_send) { };
|
||||
|
||||
virtual BOOL checkTxReceipt(J2534Frame frame) = 0;
|
||||
|
||||
virtual BOOL isFinished() = 0;
|
||||
|
||||
virtual BOOL txReady() = 0;
|
||||
|
||||
virtual void reset() = 0;
|
||||
|
||||
protected:
|
||||
J2534Frame fullmsg;
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "J2534Connection.h"
|
||||
#include "MessageTxTimeout.h"
|
||||
|
||||
MessageTxTimeoutable::MessageTxTimeoutable(
|
||||
std::weak_ptr<J2534Connection> connection,
|
||||
PASSTHRU_MSG& to_send
|
||||
) : MessageTx(connection, to_send), recvCount(0) { };
|
||||
|
||||
void MessageTxTimeoutable::scheduleTimeout(std::chrono::microseconds timeoutus) {
|
||||
if (auto conn_sp = this->connection.lock()) {
|
||||
if (auto panda_dev_sp = conn_sp->getPandaDev()) {
|
||||
auto timeoutobj = std::make_shared<MessageTxTimeout>(std::static_pointer_cast<MessageTxTimeoutable>(shared_from_this()), timeoutus);
|
||||
panda_dev_sp->scheduleAction(std::static_pointer_cast<Action>(timeoutobj), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageTxTimeoutable::scheduleTimeout(unsigned long timeoutus) {
|
||||
scheduleTimeout(std::chrono::microseconds(timeoutus));
|
||||
}
|
||||
|
||||
|
||||
|
||||
MessageTxTimeout::MessageTxTimeout(
|
||||
std::shared_ptr<MessageTxTimeoutable> msg,
|
||||
std::chrono::microseconds timeout
|
||||
) : Action(msg->connection), msg(msg), lastRecvCount(msg->getRecvCount()) {
|
||||
delay = timeout;
|
||||
};
|
||||
|
||||
MessageTxTimeout::MessageTxTimeout(
|
||||
std::shared_ptr<MessageTxTimeoutable> msg,
|
||||
unsigned long timeout
|
||||
) : MessageTxTimeout(msg, std::chrono::microseconds(timeout * 1000)) { };
|
||||
|
||||
void MessageTxTimeout::execute() {
|
||||
if (auto msg_sp = this->msg.lock()) {
|
||||
if (msg_sp->getRecvCount() == this->lastRecvCount) {
|
||||
msg_sp->onTimeout();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
#include "Action.h"
|
||||
#include "MessageTx.h"
|
||||
|
||||
class MessageTxTimeout;
|
||||
|
||||
/* A special type of MessageTx for multipart messages that supports being canceled with a timeout.*/
|
||||
class MessageTxTimeoutable : public MessageTx
|
||||
{
|
||||
public:
|
||||
MessageTxTimeoutable(
|
||||
std::weak_ptr<J2534Connection> connection,
|
||||
PASSTHRU_MSG& to_send
|
||||
);
|
||||
|
||||
unsigned long getRecvCount() {
|
||||
return recvCount;
|
||||
}
|
||||
|
||||
virtual void onTimeout() = 0;
|
||||
|
||||
protected:
|
||||
unsigned long recvCount;
|
||||
|
||||
void scheduleTimeout(std::chrono::microseconds timeoutus);
|
||||
|
||||
void scheduleTimeout(unsigned long timeoutus);
|
||||
};
|
||||
|
||||
|
||||
/* An Action that cancels MessageTxTimeoutableif the Timeout Actoin executes
|
||||
before the MessageTxTimeoutableif renews its timeout.
|
||||
*/
|
||||
class MessageTxTimeout : public Action
|
||||
{
|
||||
public:
|
||||
MessageTxTimeout(
|
||||
std::shared_ptr<MessageTxTimeoutable> msg,
|
||||
std::chrono::microseconds timeout
|
||||
);
|
||||
|
||||
MessageTxTimeout(
|
||||
std::shared_ptr<MessageTxTimeoutable> msg,
|
||||
unsigned long timeout
|
||||
);
|
||||
|
||||
virtual void execute();
|
||||
|
||||
private:
|
||||
std::weak_ptr<MessageTxTimeoutable> msg;
|
||||
unsigned long lastRecvCount;
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "MessageTx_CAN.h"
|
||||
#include "J2534Connection_CAN.h"
|
||||
|
||||
MessageTx_CAN::MessageTx_CAN(
|
||||
std::shared_ptr<J2534Connection> connection_in,
|
||||
PASSTHRU_MSG& to_send
|
||||
) : MessageTx(connection_in, to_send), sentyet(FALSE), txInFlight(FALSE) {};
|
||||
|
||||
void MessageTx_CAN::execute() {
|
||||
uint32_t addr = ((uint8_t)fullmsg.Data[0]) << 24 | ((uint8_t)fullmsg.Data[1]) << 16 |
|
||||
((uint8_t)fullmsg.Data[2]) << 8 | ((uint8_t)fullmsg.Data[3]);
|
||||
|
||||
if (auto conn_sp = std::static_pointer_cast<J2534Connection_CAN>(this->connection.lock())) {
|
||||
if (auto panda_dev_sp = conn_sp->getPandaDev()) {
|
||||
auto payload = fullmsg.Data.substr(4);
|
||||
if (panda_dev_sp->panda->can_send(addr, check_bmask(this->fullmsg.TxFlags, CAN_29BIT_ID),
|
||||
(const uint8_t*)payload.c_str(), (uint8_t)payload.size(), panda::PANDA_CAN1) == FALSE) {
|
||||
return;
|
||||
}
|
||||
this->txInFlight = TRUE;
|
||||
this->sentyet = TRUE;
|
||||
panda_dev_sp->txMsgsAwaitingEcho.push(shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Returns TRUE if receipt is consumed by the msg, FALSE otherwise.
|
||||
BOOL MessageTx_CAN::checkTxReceipt(J2534Frame frame) {
|
||||
if (txReady()) return FALSE;
|
||||
if (frame.Data == fullmsg.Data && ((this->fullmsg.TxFlags & CAN_29BIT_ID) == (frame.RxStatus & CAN_29BIT_ID))) {
|
||||
txInFlight = FALSE;
|
||||
if (auto conn_sp = std::static_pointer_cast<J2534Connection_CAN>(this->connection.lock()))
|
||||
if (conn_sp->loopback)
|
||||
conn_sp->addMsgToRxQueue(frame);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void MessageTx_CAN::reset() {
|
||||
sentyet = FALSE;
|
||||
txInFlight = FALSE;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "MessageTx.h"
|
||||
|
||||
class J2534Connection;
|
||||
|
||||
class MessageTx_CAN : public MessageTx
|
||||
{
|
||||
public:
|
||||
MessageTx_CAN(
|
||||
std::shared_ptr<J2534Connection> connection_in,
|
||||
PASSTHRU_MSG& to_send
|
||||
);
|
||||
|
||||
virtual void execute();
|
||||
|
||||
//Returns TRUE if receipt is consumed by the msg, FALSE otherwise.
|
||||
virtual BOOL checkTxReceipt(J2534Frame frame);
|
||||
|
||||
virtual BOOL isFinished() {
|
||||
return !txInFlight && sentyet;
|
||||
};
|
||||
|
||||
virtual BOOL txReady() {
|
||||
return !sentyet;
|
||||
};
|
||||
|
||||
virtual void reset();
|
||||
|
||||
private:
|
||||
BOOL sentyet;
|
||||
BOOL txInFlight;
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "MessageTx_ISO14230.h"
|
||||
#include "J2534Connection_ISO14230.h"
|
||||
|
||||
MessageTx_ISO14230::MessageTx_ISO14230(
|
||||
std::shared_ptr<J2534Connection> connection_in,
|
||||
PASSTHRU_MSG& to_send
|
||||
) : MessageTx(connection_in, to_send), sentyet(FALSE), txInFlight(FALSE) {};
|
||||
|
||||
void MessageTx_ISO14230::execute() {
|
||||
if (auto conn_sp = this->connection.lock()) {
|
||||
if (auto panda_dev_sp = conn_sp->getPandaDev()) {
|
||||
if (panda_dev_sp->kline_send(this->fullmsg.Data)) {
|
||||
if (auto conn_sp = this->connection.lock())
|
||||
{
|
||||
if (conn_sp->loopback) {
|
||||
auto echo = J2534Frame(conn_sp->getProtocol(), TX_MSG_TYPE, 0, this->fullmsg.Timestamp);
|
||||
echo.Data = std::string(this->fullmsg.Data);
|
||||
echo.ExtraDataIndex = this->fullmsg.Data.size();
|
||||
conn_sp->addMsgToRxQueue(J2534Frame(conn_sp->getProtocol(), START_OF_MESSAGE, 0, this->fullmsg.Timestamp));
|
||||
conn_sp->addMsgToRxQueue(echo);
|
||||
}
|
||||
}
|
||||
this->txInFlight = FALSE;
|
||||
this->sentyet = TRUE;
|
||||
}
|
||||
// remove action since echo was read back in kline_send()
|
||||
panda_dev_sp->removeConnectionTopAction(conn_sp, shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL MessageTx_ISO14230::checkTxReceipt(J2534Frame frame) {
|
||||
throw "not implemented!";
|
||||
}
|
||||
|
||||
void MessageTx_ISO14230::reset() {
|
||||
sentyet = FALSE;
|
||||
txInFlight = FALSE;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "MessageTx.h"
|
||||
|
||||
class J2534Connection;
|
||||
|
||||
class MessageTx_ISO14230 : public MessageTx
|
||||
{
|
||||
public:
|
||||
MessageTx_ISO14230(
|
||||
std::shared_ptr<J2534Connection> connection_in,
|
||||
PASSTHRU_MSG& to_send
|
||||
);
|
||||
|
||||
virtual void execute();
|
||||
|
||||
virtual BOOL checkTxReceipt(J2534Frame frame);
|
||||
|
||||
virtual BOOL isFinished() {
|
||||
return !txInFlight && sentyet;
|
||||
};
|
||||
|
||||
virtual BOOL txReady() {
|
||||
return !sentyet;
|
||||
};
|
||||
|
||||
virtual void reset();
|
||||
|
||||
private:
|
||||
BOOL sentyet;
|
||||
BOOL txInFlight;
|
||||
};
|
||||
@@ -1,180 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "MessageTx_ISO15765.h"
|
||||
#include "constants_ISO15765.h"
|
||||
|
||||
//in microseconsa
|
||||
#define TIMEOUT_FC 250000 //Flow Control
|
||||
#define TIMEOUT_CF 250000 //Consecutive Frames
|
||||
|
||||
MessageTx_ISO15765::MessageTx_ISO15765(
|
||||
std::shared_ptr<J2534Connection> connection_in,
|
||||
PASSTHRU_MSG& to_send,
|
||||
std::shared_ptr<J2534MessageFilter> filter
|
||||
) : MessageTxTimeoutable(connection_in, to_send), filter(filter), frames_sent(0),
|
||||
consumed_count(0), txInFlight(FALSE), sendAll(FALSE), block_size(0), numWaitFrames(0), didtimeout(FALSE), issuspended(FALSE){
|
||||
|
||||
CANid = ((uint8_t)fullmsg.Data[0]) << 24 | ((uint8_t)fullmsg.Data[1]) << 16 |
|
||||
((uint8_t)fullmsg.Data[2]) << 8 | ((uint8_t)fullmsg.Data[3]);
|
||||
|
||||
payload = fullmsg.Data.substr(addressLength());
|
||||
|
||||
if (check_bmask(fullmsg.TxFlags, ISO15765_ADDR_TYPE))
|
||||
data_prefix = fullmsg.Data[4];
|
||||
|
||||
if (payload.size() <= (7 - data_prefix.size())) {
|
||||
isMultipart = FALSE;
|
||||
auto framepayload = data_prefix + std::string(1, (char)payload.size()) + payload;
|
||||
if (check_bmask(this->fullmsg.TxFlags, ISO15765_FRAME_PAD))
|
||||
framepayload += std::string(8 - framepayload.size(), '\x00');
|
||||
framePayloads.push_back(framepayload);
|
||||
} else {
|
||||
isMultipart = TRUE;
|
||||
unsigned long first_payload_len = 6 - data_prefix.size(); // 5 or 6
|
||||
std::string framepayload = data_prefix +
|
||||
(char)(0x10 | ((payload.size() >> 8) & 0xF)) +
|
||||
(char)(payload.size() & 0xFF) +
|
||||
payload.substr(0, first_payload_len);
|
||||
framePayloads.push_back(framepayload);
|
||||
|
||||
unsigned int pktnum = 1;
|
||||
uint8_t CFDatSize = 7 - data_prefix.size();
|
||||
while (TRUE) {
|
||||
framepayload = data_prefix + (char)(0x20 | (pktnum % 0x10)) +
|
||||
payload.substr(first_payload_len + (CFDatSize * (pktnum-1)), CFDatSize);
|
||||
|
||||
if (check_bmask(this->fullmsg.TxFlags, ISO15765_FRAME_PAD))
|
||||
framepayload += std::string(8 - framepayload.size(), '\x00');
|
||||
framePayloads.push_back(framepayload);
|
||||
if (first_payload_len + (CFDatSize * pktnum) >= payload.size()) break;
|
||||
pktnum++;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int MessageTx_ISO15765::addressLength() {
|
||||
return check_bmask(fullmsg.TxFlags, ISO15765_ADDR_TYPE) ? 5 : 4;
|
||||
}
|
||||
|
||||
void MessageTx_ISO15765::execute() {
|
||||
if (didtimeout || issuspended) return;
|
||||
if (this->frames_sent >= this->framePayloads.size()) return;
|
||||
if (block_size == 0 && !sendAll && this->frames_sent > 0) return;
|
||||
if (block_size > 0 && !sendAll) block_size--;
|
||||
|
||||
if (auto conn_sp = this->connection.lock()) {
|
||||
if (auto panda_dev_sp = conn_sp->getPandaDev()) {
|
||||
auto& outFramePayload = this->framePayloads[this->frames_sent];
|
||||
if (panda_dev_sp->panda->can_send(this->CANid, check_bmask(this->fullmsg.TxFlags, CAN_29BIT_ID),
|
||||
(const uint8_t*)outFramePayload.c_str(), (uint8_t)outFramePayload.size(), panda::PANDA_CAN1) == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->txInFlight = TRUE;
|
||||
this->frames_sent++;
|
||||
panda_dev_sp->txMsgsAwaitingEcho.push(shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Returns TRUE if receipt is consumed by the msg, FALSE otherwise.
|
||||
BOOL MessageTx_ISO15765::checkTxReceipt(J2534Frame frame) {
|
||||
if (!txInFlight) return FALSE;
|
||||
if (frame.Data.size() >= addressLength() + 1 && (frame.Data[addressLength()] & 0xF0) == FRAME_FLOWCTRL) return FALSE;
|
||||
|
||||
if (frame.Data == fullmsg.Data.substr(0, 4) + framePayloads[frames_sent - 1] &&
|
||||
((this->fullmsg.TxFlags & CAN_29BIT_ID) == (frame.RxStatus & CAN_29BIT_ID))) { //Check receipt is expected
|
||||
txInFlight = FALSE; //Received the expected receipt. Allow another msg to be sent.
|
||||
|
||||
if (this->recvCount == 0 && this->framePayloads.size() > 1)
|
||||
scheduleTimeout(TIMEOUT_FC);
|
||||
|
||||
if (frames_sent == framePayloads.size()) { //Check message done
|
||||
if (auto conn_sp = std::static_pointer_cast<J2534Connection_ISO15765>(this->connection.lock())) {
|
||||
unsigned long flags = (filter == nullptr) ? fullmsg.TxFlags : this->filter->flags;
|
||||
|
||||
J2534Frame outframe(ISO15765);
|
||||
outframe.Timestamp = frame.Timestamp;
|
||||
outframe.RxStatus = TX_MSG_TYPE | TX_INDICATION | (flags & (ISO15765_ADDR_TYPE | CAN_29BIT_ID));
|
||||
outframe.Data = frame.Data.substr(0, addressLength());
|
||||
conn_sp->addMsgToRxQueue(outframe);
|
||||
|
||||
if (conn_sp->loopback) {
|
||||
J2534Frame outframe(ISO15765);
|
||||
outframe.Timestamp = frame.Timestamp;
|
||||
outframe.RxStatus = TX_MSG_TYPE | (flags & (ISO15765_ADDR_TYPE | CAN_29BIT_ID));
|
||||
outframe.Data = this->fullmsg.Data;
|
||||
conn_sp->addMsgToRxQueue(outframe);
|
||||
}
|
||||
|
||||
} //TODO what if fails
|
||||
} else {
|
||||
//Restart timeout if we are waiting for a flow control frame.
|
||||
//FC frames are required when we are not sending all, the
|
||||
//current block_size batch has not been sent, a FC message has
|
||||
//already been received (differentiating from first frame), the
|
||||
//message is not finished, and there is more than one frame in
|
||||
//the message.
|
||||
if (block_size == 0 && recvCount != 0 && !sendAll && !this->isFinished() && this->framePayloads.size() > 1)
|
||||
scheduleTimeout(TIMEOUT_CF);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL MessageTx_ISO15765::isFinished() {
|
||||
return this->frames_sent == this->framePayloads.size() && !txInFlight;
|
||||
}
|
||||
|
||||
BOOL MessageTx_ISO15765::txReady() {
|
||||
return block_size > 0 || sendAll || this->frames_sent == 0;
|
||||
}
|
||||
|
||||
void MessageTx_ISO15765::reset() {
|
||||
frames_sent = 0;
|
||||
consumed_count = 0;
|
||||
block_size = 0;
|
||||
txInFlight = FALSE;
|
||||
sendAll = FALSE;
|
||||
numWaitFrames = 0;
|
||||
didtimeout = FALSE;
|
||||
}
|
||||
|
||||
void MessageTx_ISO15765::onTimeout() {
|
||||
didtimeout = TRUE;
|
||||
if (auto conn_sp = std::static_pointer_cast<J2534Connection_ISO15765>(this->connection.lock())) {
|
||||
if (auto panda_dev_sp = conn_sp->getPandaDev()) {
|
||||
panda_dev_sp->removeConnectionTopAction(conn_sp, shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageTx_ISO15765::flowControlContinue(uint8_t block_size, std::chrono::microseconds separation_time) {
|
||||
this->issuspended = FALSE;
|
||||
this->block_size = block_size;
|
||||
this->delay = separation_time;
|
||||
this->sendAll = block_size == 0;
|
||||
this->recvCount++;
|
||||
}
|
||||
|
||||
void MessageTx_ISO15765::flowControlWait(unsigned long N_WFTmax) {
|
||||
this->issuspended = TRUE;
|
||||
this->recvCount++;
|
||||
this->numWaitFrames++;
|
||||
this->sendAll = FALSE;
|
||||
this->block_size = block_size;
|
||||
this->delay = std::chrono::microseconds(0);
|
||||
//Docs are vague on if 0 means NO WAITS ALLOWED or NO LIMIT TO WAITS.
|
||||
//It is less likely to cause issue if NO LIMIT is assumed.
|
||||
if (N_WFTmax > 0 && this->numWaitFrames > N_WFTmax) {
|
||||
this->onTimeout(); //Trigger self destruction of message.
|
||||
} else {
|
||||
scheduleTimeout(TIMEOUT_FC);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageTx_ISO15765::flowControlAbort() {
|
||||
this->recvCount++; //Invalidate future timeout actions.
|
||||
this->onTimeout(); //Trigger self destruction of message.
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
#include "MessageTxTimeout.h"
|
||||
#include "J2534Connection_ISO15765.h"
|
||||
|
||||
class J2534Connection_ISO15765;
|
||||
|
||||
/**
|
||||
A specialized message type that can handle J2534 single and multi
|
||||
frame (with flow control) writes.
|
||||
*/
|
||||
class MessageTx_ISO15765 : public MessageTxTimeoutable
|
||||
{
|
||||
public:
|
||||
MessageTx_ISO15765(
|
||||
std::shared_ptr<J2534Connection> connection,
|
||||
PASSTHRU_MSG& to_send,
|
||||
std::shared_ptr<J2534MessageFilter> filter
|
||||
);
|
||||
|
||||
unsigned int addressLength();
|
||||
|
||||
virtual void execute();
|
||||
|
||||
virtual BOOL checkTxReceipt(J2534Frame frame);
|
||||
|
||||
virtual BOOL isFinished();
|
||||
|
||||
virtual BOOL txReady();
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void onTimeout();
|
||||
|
||||
//Functions for ISO15765 flow control
|
||||
|
||||
void MessageTx_ISO15765::flowControlContinue(uint8_t block_size, std::chrono::microseconds separation_time);
|
||||
void MessageTx_ISO15765::flowControlWait(unsigned long N_WFTmax);
|
||||
void MessageTx_ISO15765::flowControlAbort();
|
||||
|
||||
std::shared_ptr<J2534MessageFilter> filter;
|
||||
unsigned long frames_sent;
|
||||
unsigned long consumed_count;
|
||||
uint8_t block_size;
|
||||
unsigned long CANid;
|
||||
std::string data_prefix;
|
||||
std::string payload;
|
||||
BOOL isMultipart;
|
||||
std::vector<std::string> framePayloads;
|
||||
BOOL txInFlight;
|
||||
BOOL sendAll;
|
||||
unsigned int numWaitFrames;
|
||||
BOOL didtimeout;
|
||||
BOOL issuspended;
|
||||
};
|
||||
@@ -1,328 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "PandaJ2534Device.h"
|
||||
#include "J2534Frame.h"
|
||||
|
||||
PandaJ2534Device::PandaJ2534Device(std::unique_ptr<panda::Panda> new_panda) : txInProgress(FALSE) {
|
||||
this->panda = std::move(new_panda);
|
||||
|
||||
this->panda->set_esp_power(FALSE);
|
||||
this->panda->set_safety_mode(panda::SAFETY_ALLOUTPUT);
|
||||
this->panda->set_can_loopback(FALSE);
|
||||
this->panda->set_alt_setting(0);
|
||||
|
||||
this->thread_kill_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
DWORD klineListenThreadID;
|
||||
this->kline_recv_handle = CreateThread(NULL, 0, _kline_recv_threadBootstrap, (LPVOID)this, 0, &klineListenThreadID);
|
||||
|
||||
DWORD canListenThreadID;
|
||||
this->can_recv_handle = CreateThread(NULL, 0, _can_recv_threadBootstrap, (LPVOID)this, 0, &canListenThreadID);
|
||||
|
||||
DWORD canProcessThreadID;
|
||||
this->can_process_handle = CreateThread(NULL, 0, _can_process_threadBootstrap, (LPVOID)this, 0, &canProcessThreadID);
|
||||
|
||||
DWORD flowControlSendThreadID;
|
||||
this->flow_control_wakeup_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
this->flow_control_thread_handle = CreateThread(NULL, 0, _msg_tx_threadBootstrap, (LPVOID)this, 0, &flowControlSendThreadID);
|
||||
};
|
||||
|
||||
PandaJ2534Device::~PandaJ2534Device() {
|
||||
SetEvent(this->thread_kill_event);
|
||||
|
||||
DWORD res = WaitForSingleObject(this->kline_recv_handle, INFINITE);
|
||||
CloseHandle(this->kline_recv_handle);
|
||||
|
||||
res = WaitForSingleObject(this->can_recv_handle, INFINITE);
|
||||
CloseHandle(this->can_recv_handle);
|
||||
|
||||
res = WaitForSingleObject(this->can_process_handle, INFINITE);
|
||||
CloseHandle(this->can_process_handle);
|
||||
|
||||
res = WaitForSingleObject(this->flow_control_thread_handle, INFINITE);
|
||||
CloseHandle(this->flow_control_thread_handle);
|
||||
|
||||
CloseHandle(this->flow_control_wakeup_event);
|
||||
CloseHandle(this->thread_kill_event);
|
||||
}
|
||||
|
||||
std::shared_ptr<PandaJ2534Device> PandaJ2534Device::openByName(std::string sn) {
|
||||
auto p = panda::Panda::openPanda("");
|
||||
if (p == nullptr)
|
||||
return nullptr;
|
||||
return std::unique_ptr<PandaJ2534Device>(new PandaJ2534Device(std::move(p)));
|
||||
}
|
||||
|
||||
DWORD PandaJ2534Device::closeChannel(unsigned long ChannelID) {
|
||||
if (this->connections.size() <= ChannelID) return ERR_INVALID_CHANNEL_ID;
|
||||
if (this->connections[ChannelID] == nullptr) return ERR_INVALID_CHANNEL_ID;
|
||||
this->connections[ChannelID] = nullptr;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
DWORD PandaJ2534Device::addChannel(std::shared_ptr<J2534Connection>& conn, unsigned long* channel_id) {
|
||||
int channel_index = -1;
|
||||
for (unsigned int i = 0; i < this->connections.size(); i++)
|
||||
if (this->connections[i] == nullptr) {
|
||||
channel_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (channel_index == -1) {
|
||||
if (this->connections.size() == 0xFFFF) //channelid max 16 bits
|
||||
return ERR_FAILED; //Too many channels
|
||||
this->connections.push_back(nullptr);
|
||||
channel_index = this->connections.size() - 1;
|
||||
}
|
||||
|
||||
this->connections[channel_index] = conn;
|
||||
|
||||
*channel_id = channel_index;
|
||||
return STATUS_NOERROR;
|
||||
}
|
||||
|
||||
std::string PandaJ2534Device::kline_five_baud_init(uint8_t addr) {
|
||||
synchronized(kline_rx_mutex) {
|
||||
Sleep(300); // W1
|
||||
this->panda->kline_slow_init(true, true, addr);
|
||||
// wakeup sometimes adds a leading null char
|
||||
this->panda->serial_clear(panda::SERIAL_LIN1);
|
||||
this->panda->serial_clear(panda::SERIAL_LIN2);
|
||||
// read 0x55 KB1 KB2
|
||||
auto key_bytes = this->panda->serial_read(panda::SERIAL_LIN1, 3, 300);
|
||||
auto bytes = key_bytes.c_str();
|
||||
if (key_bytes.size() == 3 && bytes[0] == 0x55) {
|
||||
Sleep(25); // W4
|
||||
// send inverted KB2
|
||||
auto kb2_inv = std::string(1, ~bytes[2]);
|
||||
if (this->panda->serial_write(panda::SERIAL_LIN1, kb2_inv)) {
|
||||
// read addr inverted
|
||||
auto addr_inv = this->panda->serial_read(panda::SERIAL_LIN1, 1, 50);
|
||||
if (addr_inv.size() == 1 && addr_inv.c_str()[0] == ~addr) {
|
||||
// return only KB1 KB2
|
||||
return key_bytes.substr(1, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string PandaJ2534Device::kline_wakeup_start_comm(std::string& start_comm) {
|
||||
synchronized(kline_rx_mutex) {
|
||||
Sleep(25);
|
||||
this->panda->kline_fast_init(true, true);
|
||||
// wakeup sometimes adds a leading null char
|
||||
this->panda->serial_clear(panda::SERIAL_LIN1);
|
||||
this->panda->serial_clear(panda::SERIAL_LIN2);
|
||||
// send start communication message
|
||||
if (this->panda->kline_send(panda::SERIAL_LIN1, start_comm)) {
|
||||
Sleep(25);
|
||||
// read start communication response
|
||||
return this->panda->serial_read(panda::SERIAL_LIN1, KLINE_MSG_MAX_LEN, 20);
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
BOOL PandaJ2534Device::kline_send(std::string& data) {
|
||||
// since send reads echo, block rx thread
|
||||
synchronized(kline_rx_mutex) {
|
||||
return this->panda->kline_send(panda::SERIAL_LIN1, data) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD PandaJ2534Device::kline_recv_thread() {
|
||||
this->panda->serial_clear(panda::SERIAL_LIN1);
|
||||
while (true) {
|
||||
if (!WaitForSingleObject(this->thread_kill_event, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<panda::PANDA_KLINE_MSG> msg_recv;
|
||||
synchronized(kline_rx_mutex) {
|
||||
msg_recv = this->panda->kline_recv(panda::SERIAL_LIN1);
|
||||
}
|
||||
if (msg_recv.empty()) {
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &msg : msg_recv) {
|
||||
for (auto& conn : this->connections) {
|
||||
if (conn != nullptr && !conn->isProtoCan()) {
|
||||
J2534Frame msg_out(conn->getProtocol(), msg);
|
||||
conn->processMessage(msg_out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD PandaJ2534Device::can_recv_thread() {
|
||||
this->panda->can_clear(panda::PANDA_CAN_RX);
|
||||
this->panda->can_rx_q_push(this->thread_kill_event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD PandaJ2534Device::can_process_thread() {
|
||||
panda::PANDA_CAN_MSG msg_recv[CAN_RX_MSG_LEN];
|
||||
|
||||
while (true) {
|
||||
if (!WaitForSingleObject(this->thread_kill_event, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
this->panda->can_rx_q_pop(msg_recv, count);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto msg_in = msg_recv[i];
|
||||
J2534Frame msg_out(msg_in);
|
||||
|
||||
if (msg_in.is_receipt) {
|
||||
synchronized(task_queue_mutex) {
|
||||
if (txMsgsAwaitingEcho.size() > 0) {
|
||||
auto msgtx = txMsgsAwaitingEcho.front();
|
||||
if (auto conn = msgtx->connection.lock()) {
|
||||
if (conn->isProtoCan() && conn->getPort() == msg_in.bus) {
|
||||
if (msgtx->checkTxReceipt(msg_out)) {
|
||||
//Things to check:
|
||||
// Frame not for this msg: Drop frame and alert. Error?
|
||||
// Frame is for this msg, more tx frames required after a FC frame: Wait for FC frame to come and trigger next tx.
|
||||
// Frame is for this msg, more tx frames required: Schedule next tx frame.
|
||||
// Frame is for this msg, and is the final frame of the msg: Let conn process full msg, If another msg from this conn is available, register it.
|
||||
txMsgsAwaitingEcho.pop(); //Remove the TX object and schedule record.
|
||||
|
||||
if (msgtx->isFinished()) {
|
||||
this->removeConnectionTopAction(conn, msgtx);
|
||||
} else {
|
||||
if (msgtx->txReady()) { //Not finished, ready to send next frame.
|
||||
msgtx->schedule(msg_in.recv_time_point, TRUE);
|
||||
this->insertActionIntoTaskList(msgtx);
|
||||
} else {
|
||||
//Not finished, but next frame not ready (maybe waiting for flow control).
|
||||
//Do not schedule more messages from this connection.
|
||||
//this->ConnTxSet.erase(conn);
|
||||
//Removing this means new messages queued can kickstart the queue and overstep the current message.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Connection has died. Clear out the tx entry from device records.
|
||||
txMsgsAwaitingEcho.pop();
|
||||
this->ConnTxSet.erase(conn); //connection is already dead, no need to schedule future tx msgs.
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto& conn : this->connections)
|
||||
if (conn != nullptr && conn->isProtoCan() && conn->getPort() == msg_in.bus)
|
||||
conn->processMessage(msg_out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD PandaJ2534Device::msg_tx_thread() {
|
||||
const HANDLE subscriptions[] = { this->flow_control_wakeup_event, this->thread_kill_event };
|
||||
DWORD sleepDuration = INFINITE;
|
||||
while (TRUE) {
|
||||
DWORD res = WaitForMultipleObjects(2, subscriptions, FALSE, sleepDuration);
|
||||
if (res == WAIT_OBJECT_0 + 1) return 0;
|
||||
if (res != WAIT_OBJECT_0 && res != WAIT_TIMEOUT) {
|
||||
printf("Got an unexpected wait result in flow_control_write_thread. Res: %d; GetLastError: %d\n. Terminating thread.", res, GetLastError());
|
||||
return 0;
|
||||
}
|
||||
ResetEvent(this->flow_control_wakeup_event);
|
||||
|
||||
while (TRUE) {
|
||||
synchronized(task_queue_mutex) { //implemented with for loop. Consumes breaks.
|
||||
if (this->task_queue.size() == 0) {
|
||||
sleepDuration = INFINITE;
|
||||
goto break_flow_ctrl_loop;
|
||||
}
|
||||
if (std::chrono::steady_clock::now() >= this->task_queue.front()->expire) {
|
||||
auto task = this->task_queue.front(); //Get the scheduled tx record.
|
||||
this->task_queue.pop_front();
|
||||
task->execute();
|
||||
} else { //Ran out of things that need to be sent now. Sleep!
|
||||
auto time_diff = std::chrono::duration_cast<std::chrono::milliseconds>
|
||||
(this->task_queue.front()->expire - std::chrono::steady_clock::now());
|
||||
sleepDuration = max(1, time_diff.count());
|
||||
goto break_flow_ctrl_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
break_flow_ctrl_loop:
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Place the Action in the task queue based on the Action's expiration time,
|
||||
//then signal the thread that processes actions.
|
||||
void PandaJ2534Device::insertActionIntoTaskList(std::shared_ptr<Action> action) {
|
||||
synchronized(task_queue_mutex) {
|
||||
auto iter = this->task_queue.begin();
|
||||
for (; iter != this->task_queue.end(); iter++) {
|
||||
if (action->expire < (*iter)->expire) break;
|
||||
}
|
||||
this->task_queue.insert(iter, action);
|
||||
}
|
||||
SetEvent(this->flow_control_wakeup_event);
|
||||
}
|
||||
|
||||
void PandaJ2534Device::scheduleAction(std::shared_ptr<Action> msg, BOOL startdelayed) {
|
||||
if(startdelayed)
|
||||
msg->scheduleImmediateDelay();
|
||||
else
|
||||
msg->scheduleImmediate();
|
||||
this->insertActionIntoTaskList(msg);
|
||||
}
|
||||
|
||||
void PandaJ2534Device::registerConnectionTx(std::shared_ptr<J2534Connection> conn) {
|
||||
synchronized(connTXSet_mutex) {
|
||||
auto ret = this->ConnTxSet.insert(conn);
|
||||
if (ret.second == FALSE) return; //Conn already exists.
|
||||
this->scheduleAction(conn->txbuff.front());
|
||||
}
|
||||
}
|
||||
|
||||
void PandaJ2534Device::unstallConnectionTx(std::shared_ptr<J2534Connection> conn) {
|
||||
synchronized(connTXSet_mutex) {
|
||||
auto ret = this->ConnTxSet.insert(conn);
|
||||
if (ret.second == TRUE) return; //Conn already exists.
|
||||
this->insertActionIntoTaskList(conn->txbuff.front());
|
||||
}
|
||||
}
|
||||
|
||||
void PandaJ2534Device::removeConnectionTopAction(std::shared_ptr<J2534Connection> conn, std::shared_ptr<MessageTx> msg) {
|
||||
synchronized(task_queue_mutex) {
|
||||
if (conn->txbuff.size() == 0)
|
||||
return;
|
||||
if (conn->txbuff.front() != msg)
|
||||
return;
|
||||
conn->txbuff.pop(); //Remove the top TX message from the connection tx queue.
|
||||
|
||||
//Remove the connection from the active connection list if no more messages are scheduled with this connection.
|
||||
if (conn->txbuff.size() == 0) {
|
||||
//Update records showing the connection no longer has a tx record scheduled.
|
||||
this->ConnTxSet.erase(conn);
|
||||
} else {
|
||||
//Add the next scheduled tx from this conn
|
||||
this->scheduleAction(conn->txbuff.front());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <chrono>
|
||||
#include "J2534_v0404.h"
|
||||
#include "panda_shared/panda.h"
|
||||
#include "synchronize.h"
|
||||
#include "Action.h"
|
||||
#include "MessageTx.h"
|
||||
#include "J2534Connection.h"
|
||||
|
||||
class J2534Connection;
|
||||
class Action;
|
||||
class MessageTx;
|
||||
|
||||
/**
|
||||
Class representing a physical panda adapter. Instances are created by
|
||||
PassThruOpen in the J2534 API. A Device can create one or more
|
||||
J2534Connections.
|
||||
*/
|
||||
class PandaJ2534Device {
|
||||
public:
|
||||
PandaJ2534Device(std::unique_ptr<panda::Panda> new_panda);
|
||||
|
||||
~PandaJ2534Device();
|
||||
|
||||
static std::shared_ptr<PandaJ2534Device> openByName(std::string sn);
|
||||
|
||||
DWORD closeChannel(unsigned long ChannelID);
|
||||
DWORD addChannel(std::shared_ptr<J2534Connection>& conn, unsigned long* channel_id);
|
||||
|
||||
std::unique_ptr<panda::Panda> panda;
|
||||
std::vector<std::shared_ptr<J2534Connection>> connections;
|
||||
|
||||
//Place the Action in the task queue based on the Action's expiration time,
|
||||
//then signal the thread that processes actions.
|
||||
void insertActionIntoTaskList(std::shared_ptr<Action> action);
|
||||
|
||||
void scheduleAction(std::shared_ptr<Action> msg, BOOL startdelayed=FALSE);
|
||||
|
||||
void registerConnectionTx(std::shared_ptr<J2534Connection> conn);
|
||||
|
||||
//Resume sending messages from the provided Connection's TX queue.
|
||||
void unstallConnectionTx(std::shared_ptr<J2534Connection> conn);
|
||||
|
||||
//Cleans up several queues after a message completes, is canceled, or otherwise goes away.
|
||||
void removeConnectionTopAction(std::shared_ptr<J2534Connection> conn, std::shared_ptr<MessageTx> msg);
|
||||
|
||||
//Messages that have been sent on the wire will be echoed by the panda when
|
||||
//transmission is complete. This tracks what is still waiting to hear an echo.
|
||||
std::queue<std::shared_ptr<MessageTx>> txMsgsAwaitingEcho;
|
||||
|
||||
std::string kline_five_baud_init(uint8_t addr);
|
||||
std::string kline_wakeup_start_comm(std::string& start_comm);
|
||||
BOOL kline_send(std::string& data);
|
||||
|
||||
private:
|
||||
HANDLE thread_kill_event;
|
||||
|
||||
HANDLE kline_recv_handle;
|
||||
static DWORD WINAPI _kline_recv_threadBootstrap(LPVOID This) {
|
||||
return ((PandaJ2534Device*)This)->kline_recv_thread();
|
||||
}
|
||||
DWORD kline_recv_thread();
|
||||
|
||||
HANDLE can_recv_handle;
|
||||
static DWORD WINAPI _can_recv_threadBootstrap(LPVOID This) {
|
||||
return ((PandaJ2534Device*)This)->can_recv_thread();
|
||||
}
|
||||
DWORD can_recv_thread();
|
||||
|
||||
HANDLE can_process_handle;
|
||||
static DWORD WINAPI _can_process_threadBootstrap(LPVOID This) {
|
||||
return ((PandaJ2534Device*)This)->can_process_thread();
|
||||
}
|
||||
DWORD can_process_thread();
|
||||
|
||||
HANDLE flow_control_wakeup_event;
|
||||
HANDLE flow_control_thread_handle;
|
||||
static DWORD WINAPI _msg_tx_threadBootstrap(LPVOID This) {
|
||||
return ((PandaJ2534Device*)This)->msg_tx_thread();
|
||||
}
|
||||
DWORD msg_tx_thread();
|
||||
std::list<std::shared_ptr<Action>> task_queue;
|
||||
Mutex task_queue_mutex;
|
||||
|
||||
std::queue<std::shared_ptr<J2534Connection>> ConnTxQueue;
|
||||
std::set<std::shared_ptr<J2534Connection>> ConnTxSet;
|
||||
Mutex connTXSet_mutex;
|
||||
BOOL txInProgress;
|
||||
|
||||
Mutex kline_rx_mutex;
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
start = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
|
||||
}
|
||||
|
||||
// gets the time elapsed from construction.
|
||||
unsigned long long /*milliseconds*/ Timer::getTimePassed(){
|
||||
// get the new time
|
||||
auto end = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
|
||||
|
||||
// return the difference of the times
|
||||
return (end - start).count();
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
#include <chrono>
|
||||
|
||||
//Copied from https://stackoverflow.com/a/31488113
|
||||
|
||||
class Timer
|
||||
{
|
||||
using clock = std::chrono::steady_clock;
|
||||
using time_point_type = std::chrono::time_point < clock, std::chrono::milliseconds >;
|
||||
public:
|
||||
Timer();
|
||||
|
||||
// gets the time elapsed from construction.
|
||||
unsigned long long /*milliseconds*/ getTimePassed();
|
||||
|
||||
private:
|
||||
time_point_type start;
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define msg_is_extaddr(msg) check_bmask(msg->TxFlags, ISO15765_ADDR_TYPE)
|
||||
#define msg_is_padded(msg) check_bmask(msg->TxFlags, ISO15765_FRAME_PAD)
|
||||
|
||||
#define FRAME_SINGLE 0x00
|
||||
#define FRAME_FIRST 0x10
|
||||
#define FRAME_CONSEC 0x20
|
||||
#define FRAME_FLOWCTRL 0x30
|
||||
|
||||
#define FLOWCTRL_CONTINUE 0
|
||||
#define FLOWCTRL_WAIT 1
|
||||
#define FLOWCTRL_ABORT 2
|
||||
|
||||
#define msg_get_type(msg, addrlen) ((msg).Data[addrlen] & 0xF0)
|
||||
|
||||
#define is_single(msg, addrlen) (msg_get_type(msg, addrlen) == FRAME_SINGLE)
|
||||
#define is_first(msg, addrlen) (msg_get_type(msg, addrlen) == FRAME_FIRST)
|
||||
#define is_consecutive(msg, addrlen) (msg_get_type(msg, addrlen) == FRAME_CONSEC)
|
||||
#define is_flowctrl(msg, addrlen) (msg_get_type(msg, addrlen) == FRAME_FLOWCTRL)
|
||||
@@ -1,22 +0,0 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "dllmain.h"
|
||||
|
||||
HMODULE thisdll;
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
thisdll = hModule;
|
||||
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
extern HMODULE thisdll;
|
||||
@@ -1,432 +0,0 @@
|
||||
// pandaJ2534DLL.cpp : Defines the exported functions for the DLL application.
|
||||
// Protocol derived from the following sites (which shall be referred to as The Protocol Reference #).
|
||||
// https://web.archive.org/web/20130805013326/https://tunertools.com/prodimages/DrewTech/Manuals/PassThru_API-1.pdf
|
||||
// http://web.archive.org/web/20170910063536/http://www.tiecar.net/downloads/SAE_J2534_2002.pdf
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "J2534_v0404.h"
|
||||
#include "panda_shared/panda.h"
|
||||
#include "J2534Connection.h"
|
||||
#include "J2534Connection_ISO14230.h"
|
||||
#include "J2534Connection_CAN.h"
|
||||
#include "J2534Connection_ISO15765.h"
|
||||
#include "PandaJ2534Device.h"
|
||||
#include "dllmain.h"
|
||||
|
||||
// A quick way to avoid the name mangling that __stdcall liked to do
|
||||
#define EXPORT comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
|
||||
|
||||
std::vector<std::shared_ptr<PandaJ2534Device>> pandas;
|
||||
|
||||
int J25334LastError = 0;
|
||||
|
||||
std::string GetProductAndVersion(TCHAR* szFilename)//std::string & strProductName, std::string & strProductVersion)
|
||||
{
|
||||
// allocate a block of memory for the version info
|
||||
DWORD dummy;
|
||||
DWORD dwSize = GetFileVersionInfoSize(szFilename, &dummy);
|
||||
if (dwSize == 0) {
|
||||
return "error";
|
||||
}
|
||||
std::vector<BYTE> data(dwSize);
|
||||
|
||||
// load the version info
|
||||
if (!GetFileVersionInfo(szFilename, NULL, dwSize, &data[0])) {
|
||||
return "error";
|
||||
}
|
||||
|
||||
// get the name and version strings
|
||||
LPVOID pvProductName = NULL;
|
||||
unsigned int iProductNameLen = 0;
|
||||
LPVOID pvProductVersion = NULL;
|
||||
unsigned int iProductVersionLen = 0;
|
||||
|
||||
// 040904b0 is a language id.
|
||||
if (!VerQueryValueA(&data[0], "\\StringFileInfo\\040904b0\\ProductName", &pvProductName, &iProductNameLen) ||
|
||||
!VerQueryValueA(&data[0], "\\StringFileInfo\\040904b0\\ProductVersion", &pvProductVersion, &iProductVersionLen)) {
|
||||
return "error";
|
||||
}
|
||||
|
||||
std::string ver_str = std::string((char*)pvProductVersion, iProductVersionLen-1);
|
||||
std::string prod_str = std::string((char*)pvProductName, iProductNameLen-1);
|
||||
std::string full_ver = prod_str + std::string(": ") + ver_str;
|
||||
return full_ver;
|
||||
}
|
||||
|
||||
long ret_code(long code) {
|
||||
J25334LastError = code;
|
||||
return code;
|
||||
}
|
||||
|
||||
#define EXTRACT_DID(CID) ((CID & 0xFFFF) - 1)
|
||||
#define EXTRACT_CID(CID) ((CID >> 16) & 0xFFFF)
|
||||
|
||||
long check_valid_DeviceID(unsigned long DeviceID) {
|
||||
uint16_t dev_id = EXTRACT_DID(DeviceID);
|
||||
if (pandas.size() <= dev_id || pandas[dev_id] == nullptr)
|
||||
return ret_code(ERR_INVALID_DEVICE_ID);
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
|
||||
long check_valid_ChannelID(unsigned long ChannelID) {
|
||||
uint16_t dev_id = EXTRACT_DID(ChannelID);
|
||||
uint16_t con_id = EXTRACT_CID(ChannelID);
|
||||
|
||||
if (pandas.size() <= dev_id || pandas[dev_id] == nullptr)
|
||||
return ret_code(ERR_INVALID_CHANNEL_ID);
|
||||
|
||||
if (pandas[dev_id]->connections.size() <= con_id) return ret_code(ERR_INVALID_CHANNEL_ID);
|
||||
if (pandas[dev_id]->connections[con_id] == nullptr) return ret_code(ERR_DEVICE_NOT_CONNECTED);
|
||||
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
|
||||
//Do not call without checking if the device/channel id exists first.
|
||||
#define get_device(DeviceID) (pandas[EXTRACT_DID(DeviceID)])
|
||||
#define get_channel(ChannelID) (get_device(ChannelID)->connections[EXTRACT_CID(ChannelID)])
|
||||
|
||||
PANDAJ2534DLL_API long PTAPI PassThruOpen(void *pName, unsigned long *pDeviceID) {
|
||||
#pragma EXPORT
|
||||
if (pDeviceID == NULL) return ret_code(ERR_NULL_PARAMETER);
|
||||
std::string sn = (pName == NULL) ? "" : std::string((char*)pName);
|
||||
if (sn == "J2534-2:")
|
||||
sn = "";
|
||||
|
||||
auto new_panda = PandaJ2534Device::openByName(sn);
|
||||
if (new_panda == nullptr) {
|
||||
if(sn == "" && pandas.size() == 1)
|
||||
return ret_code(ERR_DEVICE_IN_USE);
|
||||
//for (auto& pn : pandas) {
|
||||
// if (pn->panda->get_usb_sn() == sn)
|
||||
// return ret_code(ERR_DEVICE_IN_USE);
|
||||
//}
|
||||
return ret_code(ERR_DEVICE_NOT_CONNECTED);
|
||||
}
|
||||
|
||||
int panda_index = -1;
|
||||
for (unsigned int i = 0; i < pandas.size(); i++)
|
||||
if (pandas[i] == nullptr) {
|
||||
panda_index = i;
|
||||
pandas[panda_index] = std::move(new_panda);
|
||||
break;
|
||||
}
|
||||
|
||||
if (panda_index == -1) {
|
||||
if(pandas.size() == 0xFFFF) //device id will be 16 bit to fit channel next to it.
|
||||
return ret_code(ERR_FAILED); //Too many pandas. Off the endangered species list.
|
||||
pandas.push_back(std::move(new_panda));
|
||||
panda_index = pandas.size()-1;
|
||||
}
|
||||
|
||||
*pDeviceID = panda_index + 1; // TIS doesn't like it when ID == 0
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruClose(unsigned long DeviceID) {
|
||||
#pragma EXPORT
|
||||
if (check_valid_DeviceID(DeviceID) != STATUS_NOERROR) return J25334LastError;
|
||||
get_device(DeviceID) = nullptr;
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruConnect(unsigned long DeviceID, unsigned long ProtocolID,
|
||||
unsigned long Flags, unsigned long BaudRate, unsigned long *pChannelID) {
|
||||
#pragma EXPORT
|
||||
if (pChannelID == NULL) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (check_valid_DeviceID(DeviceID) != STATUS_NOERROR) return J25334LastError;
|
||||
auto& panda = get_device(DeviceID);
|
||||
|
||||
std::shared_ptr<J2534Connection> conn;
|
||||
|
||||
//TODO check if channel can be made
|
||||
try {
|
||||
switch (ProtocolID) {
|
||||
//SW seems to refer to Single Wire. https://www.nxp.com/files-static/training_pdf/20451_BUS_COMM_WBT.pdf
|
||||
//SW_ protocols may be touched on here: https://www.iso.org/obp/ui/#iso:std:iso:22900:-2:ed-1:v1:en
|
||||
//case J1850VPW: // These protocols are outdated and will not be supported. HDS wants them to not fail to open.
|
||||
//case J1850PWM: // ^-- it appears HDS no longer needs this, and TIS needs it disabled --^
|
||||
//case J1850VPW_PS:
|
||||
//case J1850PWM_PS:
|
||||
case ISO9141:
|
||||
//case ISO9141_PS:
|
||||
case ISO14230:
|
||||
//case ISO14230_PS:
|
||||
conn = std::make_shared<J2534Connection_ISO14230>(panda, ProtocolID, Flags, BaudRate);
|
||||
break;
|
||||
case CAN:
|
||||
//case CAN_PS:
|
||||
//case SW_CAN_PS:
|
||||
conn = std::make_shared<J2534Connection_CAN>(panda, ProtocolID, Flags, BaudRate);
|
||||
break;
|
||||
case ISO15765:
|
||||
//case ISO15765_PS:
|
||||
conn = std::make_shared<J2534Connection_ISO15765>(panda, ProtocolID, Flags, BaudRate);
|
||||
break;
|
||||
//case SW_ISO15765_PS: // SW = Single Wire. GMLAN is a SW CAN protocol
|
||||
//case GM_UART_PS: // PS = Pin Select. Handles different ports.
|
||||
//Looks like SCI based protocols may not be compatible with the panda:
|
||||
//http://mdhmotors.com/can-communications-vehicle-network-protocols/3/
|
||||
//case SCI_A_ENGINE:
|
||||
//case SCI_A_TRANS:
|
||||
//case SCI_B_ENGINE:
|
||||
//case SCI_B_TRANS:
|
||||
//case J2610_PS:
|
||||
default:
|
||||
return ret_code(ERR_INVALID_PROTOCOL_ID);
|
||||
}
|
||||
} catch (int e) {
|
||||
return ret_code(e);
|
||||
}
|
||||
|
||||
unsigned long channel_index;
|
||||
unsigned long err = panda->addChannel(conn, &channel_index);
|
||||
if (err == STATUS_NOERROR)
|
||||
*pChannelID = (channel_index << 16) | DeviceID;
|
||||
|
||||
return ret_code(err);
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruDisconnect(unsigned long ChannelID) {
|
||||
#pragma EXPORT
|
||||
unsigned long res = check_valid_DeviceID(ChannelID);
|
||||
if (res == ERR_INVALID_DEVICE_ID) return ret_code(ERR_INVALID_CHANNEL_ID);
|
||||
if (res != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_device(ChannelID)->closeChannel(EXTRACT_CID(ChannelID)));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG *pMsg,
|
||||
unsigned long *pNumMsgs, unsigned long Timeout) {
|
||||
#pragma EXPORT
|
||||
if (pMsg == NULL || pNumMsgs == NULL) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_channel(ChannelID)->PassThruReadMsgs(pMsg, pNumMsgs, Timeout));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruWriteMsgs(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout) {
|
||||
#pragma EXPORT
|
||||
if (pMsg == NULL || pNumMsgs == NULL) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_channel(ChannelID)->PassThruWriteMsgs(pMsg, pNumMsgs, Timeout));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStartPeriodicMsg(unsigned long ChannelID, PASSTHRU_MSG *pMsg, unsigned long *pMsgID, unsigned long TimeInterval) {
|
||||
#pragma EXPORT
|
||||
if (pMsg == NULL || pMsgID == NULL) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_channel(ChannelID)->PassThruStartPeriodicMsg(pMsg, pMsgID, TimeInterval));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStopPeriodicMsg(unsigned long ChannelID, unsigned long MsgID) {
|
||||
#pragma EXPORT
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_channel(ChannelID)->PassThruStopPeriodicMsg(MsgID));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStartMsgFilter(unsigned long ChannelID, unsigned long FilterType, PASSTHRU_MSG *pMaskMsg,
|
||||
PASSTHRU_MSG *pPatternMsg, PASSTHRU_MSG *pFlowControlMsg, unsigned long *pFilterID) {
|
||||
#pragma EXPORT
|
||||
if (FilterType != PASS_FILTER && FilterType != BLOCK_FILTER && FilterType != FLOW_CONTROL_FILTER) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (!pFilterID || (!pMaskMsg && !pPatternMsg && !pFlowControlMsg)) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_channel(ChannelID)->PassThruStartMsgFilter(FilterType, pMaskMsg, pPatternMsg, pFlowControlMsg, pFilterID));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruStopMsgFilter(unsigned long ChannelID, unsigned long FilterID) {
|
||||
#pragma EXPORT
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
return ret_code(get_channel(ChannelID)->PassThruStopMsgFilter(FilterID));
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruSetProgrammingVoltage(unsigned long DeviceID, unsigned long PinNumber, unsigned long Voltage) {
|
||||
#pragma EXPORT
|
||||
//Unused
|
||||
if (check_valid_DeviceID(DeviceID) != STATUS_NOERROR) return J25334LastError;
|
||||
auto& panda = get_device(DeviceID);
|
||||
|
||||
switch (Voltage) {
|
||||
case SHORT_TO_GROUND:
|
||||
break;
|
||||
case VOLTAGE_OFF:
|
||||
break;
|
||||
default:
|
||||
if (!(5000 <= Voltage && Voltage <= 20000))
|
||||
return ret_code(ERR_NOT_SUPPORTED);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruReadVersion(unsigned long DeviceID, char *pFirmwareVersion, char *pDllVersion, char *pApiVersion) {
|
||||
#pragma EXPORT
|
||||
if (!pFirmwareVersion || !pDllVersion || !pApiVersion) return ret_code(ERR_NULL_PARAMETER);
|
||||
if (check_valid_DeviceID(DeviceID) != STATUS_NOERROR) return J25334LastError;
|
||||
|
||||
auto& panda = get_device(DeviceID);
|
||||
auto fw_version = panda->panda->get_version();
|
||||
strcpy_s(pFirmwareVersion, 80, fw_version.c_str());
|
||||
|
||||
std::string j2534dll_ver;
|
||||
TCHAR pandalib_filename[MAX_PATH + 1] = { 0 };
|
||||
if (GetModuleFileName(thisdll, pandalib_filename, MAX_PATH) == 0) {
|
||||
j2534dll_ver = "error";
|
||||
} else {
|
||||
j2534dll_ver = GetProductAndVersion(pandalib_filename);
|
||||
}
|
||||
std::string fullver = "(" + j2534dll_ver + ")";
|
||||
strcpy_s(pDllVersion, 80, fullver.c_str());
|
||||
|
||||
strcpy_s(pApiVersion, 80, J2534_APIVER_NOVEMBER_2004);
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruGetLastError(char *pErrorDescription) {
|
||||
#pragma EXPORT
|
||||
if (pErrorDescription == NULL) return ret_code(ERR_NULL_PARAMETER);
|
||||
switch (J25334LastError) {
|
||||
case STATUS_NOERROR:
|
||||
strcpy_s(pErrorDescription, 80, "Function call successful.");
|
||||
break;
|
||||
case ERR_NOT_SUPPORTED:
|
||||
strcpy_s(pErrorDescription, 80, "Device cannot support requested functionality mandated in J2534.");
|
||||
break;
|
||||
case ERR_INVALID_CHANNEL_ID:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid ChannelID value.");
|
||||
break;
|
||||
case ERR_INVALID_PROTOCOL_ID:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid or unsupported ProtocolID, or resource conflict.");
|
||||
break;
|
||||
case ERR_NULL_PARAMETER:
|
||||
strcpy_s(pErrorDescription, 80, "NULL pointer supplied where a valid pointer is required.");
|
||||
break;
|
||||
case ERR_INVALID_IOCTL_VALUE:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid value for Ioctl parameter.");
|
||||
break;
|
||||
case ERR_INVALID_FLAGS:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid flag values.");
|
||||
break;
|
||||
case ERR_FAILED:
|
||||
strcpy_s(pErrorDescription, 80, "Undefined error.");
|
||||
break;
|
||||
case ERR_DEVICE_NOT_CONNECTED:
|
||||
strcpy_s(pErrorDescription, 80, "Unable to communicate with device.");
|
||||
break;
|
||||
case ERR_TIMEOUT:
|
||||
strcpy_s(pErrorDescription, 80, "Read or write timeout:");
|
||||
// PassThruReadMsgs() - No message available to read or could not read the specified number of messages. The actual number of messages read is placed in <NumMsgs>.
|
||||
// PassThruWriteMsgs() - Device could not write the specified number of messages. The actual number of messages sent on the vehicle network is placed in <NumMsgs>.
|
||||
break;
|
||||
case ERR_INVALID_MSG:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid message structure pointed to by pMsg.");
|
||||
break;
|
||||
case ERR_INVALID_TIME_INTERVAL:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid TimeInterval value.");
|
||||
break;
|
||||
case ERR_EXCEEDED_LIMIT:
|
||||
strcpy_s(pErrorDescription, 80, "Exceeded maximum number of message IDs or allocated space.");
|
||||
break;
|
||||
case ERR_INVALID_MSG_ID:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid MsgID value.");
|
||||
break;
|
||||
case ERR_DEVICE_IN_USE:
|
||||
strcpy_s(pErrorDescription, 80, "Device is currently open.");
|
||||
break;
|
||||
case ERR_INVALID_IOCTL_ID:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid IoctlID value.");
|
||||
break;
|
||||
case ERR_BUFFER_EMPTY:
|
||||
strcpy_s(pErrorDescription, 80, "Protocol message buffer empty.");
|
||||
break;
|
||||
case ERR_BUFFER_FULL:
|
||||
strcpy_s(pErrorDescription, 80, "Protocol message buffer full. Messages may have been lost.");
|
||||
break;
|
||||
case ERR_BUFFER_OVERFLOW:
|
||||
strcpy_s(pErrorDescription, 80, "A buffer overflow occurred and messages were lost.");
|
||||
break;
|
||||
case ERR_PIN_INVALID:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid pin number, or pin number already in use.");
|
||||
break;
|
||||
case ERR_CHANNEL_IN_USE:
|
||||
strcpy_s(pErrorDescription, 80, "Channel number is currently connected.");
|
||||
break;
|
||||
case ERR_MSG_PROTOCOL_ID:
|
||||
strcpy_s(pErrorDescription, 80, "The Message's Protocol does not match the Channel's protocol.");
|
||||
break;
|
||||
case ERR_INVALID_FILTER_ID:
|
||||
strcpy_s(pErrorDescription, 80, "Invalid Filter ID value.");
|
||||
break;
|
||||
case ERR_NO_FLOW_CONTROL:
|
||||
strcpy_s(pErrorDescription, 80, "No flow control filter set or matched.");
|
||||
break;
|
||||
case ERR_NOT_UNIQUE:
|
||||
strcpy_s(pErrorDescription, 80, "This filter already exists.");
|
||||
break;
|
||||
case ERR_INVALID_BAUDRATE:
|
||||
strcpy_s(pErrorDescription, 80, "The desired baud rate cannot be achieved within SAE tolerance.");
|
||||
break;
|
||||
case ERR_INVALID_DEVICE_ID:
|
||||
strcpy_s(pErrorDescription, 80, "Device ID invalid.");
|
||||
break;
|
||||
}
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
PANDAJ2534DLL_API long PTAPI PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID,
|
||||
void *pInput, void *pOutput) {
|
||||
#pragma EXPORT
|
||||
if (check_valid_ChannelID(ChannelID) != STATUS_NOERROR) return J25334LastError;
|
||||
auto& dev_entry = get_device(ChannelID);
|
||||
//get_channel(ChannelID)
|
||||
|
||||
switch (IoctlID) {
|
||||
case GET_CONFIG:
|
||||
{
|
||||
SCONFIG_LIST *inconfig = (SCONFIG_LIST*)pInput;
|
||||
if (inconfig == NULL)
|
||||
return ret_code(ERR_NULL_PARAMETER);
|
||||
for (unsigned int i = 0; i < inconfig->NumOfParams; i++) {
|
||||
try {
|
||||
inconfig->ConfigPtr[i].Value = get_channel(ChannelID)->processIOCTLGetConfig(inconfig->ConfigPtr[i].Parameter);
|
||||
} catch (int e) {
|
||||
return ret_code(e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SET_CONFIG:
|
||||
{
|
||||
SCONFIG_LIST *inconfig = (SCONFIG_LIST*)pInput;
|
||||
if (inconfig == NULL)
|
||||
return ret_code(ERR_NULL_PARAMETER);
|
||||
for (unsigned int i = 0; i < inconfig->NumOfParams; i++) {
|
||||
try {
|
||||
get_channel(ChannelID)->processIOCTLSetConfig(inconfig->ConfigPtr[i].Parameter, inconfig->ConfigPtr[i].Value);
|
||||
} catch (int e) {
|
||||
return ret_code(e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case READ_VBATT:
|
||||
panda::PANDA_HEALTH health = dev_entry->panda->get_health();
|
||||
*(unsigned long*)pOutput = health.voltage;
|
||||
break;
|
||||
case FIVE_BAUD_INIT:
|
||||
if (!pInput || !pOutput) return ret_code(ERR_NULL_PARAMETER);
|
||||
return ret_code(get_channel(ChannelID)->init5b((SBYTE_ARRAY*)pInput, (SBYTE_ARRAY*)pOutput));
|
||||
case FAST_INIT:
|
||||
if (!pInput || !pOutput) return ret_code(ERR_NULL_PARAMETER);
|
||||
return ret_code(get_channel(ChannelID)->initFast((PASSTHRU_MSG*)pInput, (PASSTHRU_MSG*)pOutput));
|
||||
case CLEAR_TX_BUFFER:
|
||||
return ret_code(get_channel(ChannelID)->clearTXBuff());
|
||||
case CLEAR_RX_BUFFER:
|
||||
return ret_code(get_channel(ChannelID)->clearRXBuff());
|
||||
case CLEAR_PERIODIC_MSGS:
|
||||
return ret_code(get_channel(ChannelID)->clearPeriodicMsgs());
|
||||
case CLEAR_MSG_FILTERS:
|
||||
return ret_code(get_channel(ChannelID)->clearMsgFilters());
|
||||
case CLEAR_FUNCT_MSG_LOOKUP_TABLE: // LOOKUP TABLE IS RELATED TO J1850 PWM. Unsupported.
|
||||
if (!pInput) return ret_code(ERR_NULL_PARAMETER);
|
||||
return ret_code(STATUS_NOERROR);
|
||||
case ADD_TO_FUNCT_MSG_LOOKUP_TABLE: // LOOKUP TABLE IS RELATED TO J1850 PWM. Unsupported.
|
||||
if (!pInput) return ret_code(ERR_NULL_PARAMETER);
|
||||
return ret_code(STATUS_NOERROR);
|
||||
case DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE: // LOOKUP TABLE IS RELATED TO J1850 PWM. Unsupported.
|
||||
return ret_code(STATUS_NOERROR);
|
||||
case READ_PROG_VOLTAGE:
|
||||
*(unsigned long*)pOutput = 0;
|
||||
break;
|
||||
default:
|
||||
printf("Got unknown IIOCTL %X\n", IoctlID);
|
||||
return ret_code(ERR_INVALID_IOCTL_ID);
|
||||
}
|
||||
|
||||
return ret_code(STATUS_NOERROR);
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{A2BB18A5-F26B-48D6-BBB5-B83D64473C77}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>pandaJ2534DLL</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
<Import Project="..\panda_shared\panda_shared.vcxitems" 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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
<TargetName>pandaJ2534_0404_32</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_$(PlatformShortName)\</OutDir>
|
||||
<TargetName>pandaJ2534_0404_32</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PANDAJ2534DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);</AdditionalIncludeDirectories>
|
||||
</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;%(AdditionalDependencies);version.lib;winusb.lib;setupapi.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PANDAJ2534DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;%(AdditionalDependencies);version.lib;winusb.lib;setupapi.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\panda\panda.h" />
|
||||
<ClInclude Include="constants_ISO15765.h" />
|
||||
<ClInclude Include="dllmain.h" />
|
||||
<ClInclude Include="J2534Connection_ISO14230.h" />
|
||||
<ClInclude Include="MessagePeriodic.h" />
|
||||
<ClInclude Include="MessageRx.h" />
|
||||
<ClInclude Include="J2534Connection.h" />
|
||||
<ClInclude Include="J2534Connection_CAN.h" />
|
||||
<ClInclude Include="J2534Connection_ISO15765.h" />
|
||||
<ClInclude Include="J2534Frame.h" />
|
||||
<ClInclude Include="J2534MessageFilter.h" />
|
||||
<ClInclude Include="J2534_v0404.h" />
|
||||
<ClInclude Include="Action.h" />
|
||||
<ClInclude Include="MessageTx.h" />
|
||||
<ClInclude Include="MessageTxTimeout.h" />
|
||||
<ClInclude Include="MessageTx_CAN.h" />
|
||||
<ClInclude Include="MessageTx_ISO14230.h" />
|
||||
<ClInclude Include="MessageTx_ISO15765.h" />
|
||||
<ClInclude Include="PandaJ2534Device.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="synchronize.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="Timer.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="J2534Connection.cpp" />
|
||||
<ClCompile Include="J2534Connection_CAN.cpp" />
|
||||
<ClCompile Include="J2534Connection_ISO14230.cpp" />
|
||||
<ClCompile Include="J2534Connection_ISO15765.cpp" />
|
||||
<ClCompile Include="J2534MessageFilter.cpp" />
|
||||
<ClCompile Include="MessagePeriodic.cpp" />
|
||||
<ClCompile Include="MessageTxTimeout.cpp" />
|
||||
<ClCompile Include="MessageTx_CAN.cpp" />
|
||||
<ClCompile Include="MessageTx_ISO14230.cpp" />
|
||||
<ClCompile Include="MessageTx_ISO15765.cpp" />
|
||||
<ClCompile Include="PandaJ2534Device.cpp" />
|
||||
<ClCompile Include="pandaJ2534DLL.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="pandaJ2534DLL.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ClassDiagram.cd" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,173 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\depends">
|
||||
<UniqueIdentifier>{a4cd0bce-0a2a-43d9-9c9f-b21a3b607e90}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\boilerplate">
|
||||
<UniqueIdentifier>{a85ee263-380d-4d37-b167-6629cfd5177f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\boilerplate">
|
||||
<UniqueIdentifier>{010a0176-a146-4d3a-824a-fd683904774d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\J2534_CAN">
|
||||
<UniqueIdentifier>{71c9502a-ee59-4d5e-873f-c9cc792e7c76}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\J2534_ISO15765">
|
||||
<UniqueIdentifier>{4fd3183a-c457-430c-b762-f767a5788bca}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\J2534_ISO15765">
|
||||
<UniqueIdentifier>{53cd179e-22d8-43e2-bc61-516d3861fae6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\J2534_CAN">
|
||||
<UniqueIdentifier>{08d548b5-4d0b-4ce4-85e6-5ff3fc987758}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\J2534_ISO14230">
|
||||
<UniqueIdentifier>{b5c1874e-d3f8-4465-89c5-2e2b7e9f4fa4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\J2534_ISO14230">
|
||||
<UniqueIdentifier>{b5a39015-f3ca-4888-bd5f-785aeec91345}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="J2534Connection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PandaJ2534Device.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Timer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="J2534MessageFilter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="synchronize.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="J2534Connection_CAN.h">
|
||||
<Filter>Header Files\J2534_CAN</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="J2534Connection_ISO15765.h">
|
||||
<Filter>Header Files\J2534_ISO15765</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="J2534_v0404.h">
|
||||
<Filter>Header Files\depends</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\panda\panda.h">
|
||||
<Filter>Header Files\depends</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dllmain.h">
|
||||
<Filter>Header Files\boilerplate</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files\boilerplate</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files\boilerplate</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files\boilerplate</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="J2534Frame.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessageTx_ISO15765.h">
|
||||
<Filter>Header Files\J2534_ISO15765</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessageRx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="constants_ISO15765.h">
|
||||
<Filter>Header Files\J2534_ISO15765</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessageTx_CAN.h">
|
||||
<Filter>Header Files\J2534_CAN</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessageTxTimeout.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Action.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessageTx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessagePeriodic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="J2534Connection_ISO14230.h">
|
||||
<Filter>Header Files\J2534_ISO14230</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MessageTx_ISO14230.h">
|
||||
<Filter>Header Files\J2534_ISO14230</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pandaJ2534DLL.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="J2534Connection.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PandaJ2534Device.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="J2534MessageFilter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="J2534Connection_CAN.cpp">
|
||||
<Filter>Source Files\J2534_CAN</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="J2534Connection_ISO15765.cpp">
|
||||
<Filter>Source Files\J2534_ISO15765</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files\boilerplate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files\boilerplate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MessageTx_ISO15765.cpp">
|
||||
<Filter>Source Files\J2534_ISO15765</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MessageTxTimeout.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MessageTx_CAN.cpp">
|
||||
<Filter>Source Files\J2534_CAN</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MessagePeriodic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="J2534Connection_ISO14230.cpp">
|
||||
<Filter>Source Files\J2534_ISO14230</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MessageTx_ISO14230.cpp">
|
||||
<Filter>Source Files\J2534_ISO14230</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="pandaJ2534DLL.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ClassDiagram.cd" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,14 +0,0 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by pandaJ2534DLL.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// pandaJ2534DLL.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||