├── .gitignore ├── .gitmodules ├── Visual Studio ├── SimpleSerialAnalyzer.sln └── SimpleSerialAnalyzer.vcxproj ├── build_analyzer.py ├── docs ├── Analyzer SDK Setup.md ├── Saleae Analyzer SDK (older).pdf └── images │ ├── 10_-_build_settings_page.png │ ├── 11_-_header_includes_search_path.png │ ├── 11_5_-_add_library_path.png │ ├── 12_-_add_library_part_1.png │ ├── 13_-_add_library_part_2.png │ ├── 14_-_add_library_part_3.png │ ├── 15_-_edit_scheme.png │ ├── 16_-_debug_launch_app_menu.png │ ├── 17_-_select_debug_program.png │ ├── 18_-_breakpoint_set.png │ ├── 19_-_logic_software_add_analyzer_menu.png │ ├── 1_-_new_project.png │ ├── 20_-_analyzer_in_Logic.png │ ├── 21_-_logic_software_start_button.png │ ├── 22_-_breakpoint_hit.png │ ├── 2_-_empty_project.png │ ├── 2_5_analyzer_name.png │ ├── 2_75_-_project_location.png │ ├── 3_-_copy_files.png │ ├── 4_-_rename_analyzer_script.png │ ├── 5_-_add_target_button.png │ ├── 6_-_add_target_menu.png │ ├── 7_-_library_target.png │ ├── 8_-_library_settings.png │ ├── 8_5_-_add_files_menu.png │ ├── 9_-_add_files.png │ ├── 9_5_-_verify_sources_added.png │ ├── optional_-_Project_Settings.png │ └── optional_-_project_settings_-_edit_products_folder_menu.png ├── readme.md ├── screenshots ├── analyzer.png └── config.png └── source ├── ISO7816Analyzer.cpp ├── ISO7816Analyzer.h ├── ISO7816AnalyzerResults.cpp ├── ISO7816AnalyzerResults.h ├── ISO7816AnalyzerSettings.cpp ├── ISO7816AnalyzerSettings.h ├── SimpleSerialSimulationDataGenerator.cpp └── SimpleSerialSimulationDataGenerator.h /.gitignore: -------------------------------------------------------------------------------- 1 | Debug/ 2 | Release/ 3 | Debug-Legacy-1.1.14/ 4 | *.VC.db 5 | *.VC.opendb 6 | *.suo 7 | *.sln.ecd 8 | *.vcxproj.user -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "AnalyzerSDK"] 2 | path = AnalyzerSDK 3 | url = https://github.com/saleae/AnalyzerSDK.git 4 | [submodule "LegacyAnalyzerSDK"] 5 | path = LegacyAnalyzerSDK 6 | url = https://github.com/saleae/AnalyzerSDK.git 7 | -------------------------------------------------------------------------------- /Visual Studio/SimpleSerialAnalyzer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleSerialAnalyzer", "SimpleSerialAnalyzer.vcxproj", "{D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Debug-Legacy-1.1.14|Win32 = Debug-Legacy-1.1.14|Win32 13 | Debug-Legacy-1.1.14|x64 = Debug-Legacy-1.1.14|x64 14 | Release|Win32 = Release|Win32 15 | Release|x64 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug|Win32.Build.0 = Debug|Win32 20 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug|x64.ActiveCfg = Debug|x64 21 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug|x64.Build.0 = Debug|x64 22 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug-Legacy-1.1.14|Win32.ActiveCfg = Debug-Legacy-1.1.14|Win32 23 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug-Legacy-1.1.14|Win32.Build.0 = Debug-Legacy-1.1.14|Win32 24 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug-Legacy-1.1.14|x64.ActiveCfg = Debug-Legacy-1.1.14|x64 25 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Debug-Legacy-1.1.14|x64.Build.0 = Debug-Legacy-1.1.14|x64 26 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Release|Win32.ActiveCfg = Release|Win32 27 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Release|Win32.Build.0 = Release|Win32 28 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Release|x64.ActiveCfg = Release|x64 29 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}.Release|x64.Build.0 = Release|x64 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /Visual Studio/SimpleSerialAnalyzer.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug-Legacy-1.1.14 6 | Win32 7 | 8 | 9 | Debug-Legacy-1.1.14 10 | x64 11 | 12 | 13 | Debug 14 | Win32 15 | 16 | 17 | Debug 18 | x64 19 | 20 | 21 | Release 22 | Win32 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301} 31 | SimpleSerialAnalyzer 32 | Win32Proj 33 | 8.1 34 | 35 | 36 | 37 | DynamicLibrary 38 | v140 39 | Unicode 40 | true 41 | 42 | 43 | DynamicLibrary 44 | v140 45 | Unicode 46 | true 47 | 48 | 49 | DynamicLibrary 50 | v140 51 | Unicode 52 | 53 | 54 | DynamicLibrary 55 | v140 56 | Unicode 57 | 58 | 59 | DynamicLibrary 60 | v140 61 | Unicode 62 | 63 | 64 | DynamicLibrary 65 | v140 66 | Unicode 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | <_ProjectFileVersion>14.0.24720.0 92 | 93 | 94 | $(SolutionDir)$(Platform)\$(Configuration)\ 95 | $(Platform)\$(Configuration)\ 96 | true 97 | 98 | 99 | $(SolutionDir)$(Platform)\$(Configuration)\ 100 | $(Platform)\$(Configuration)\ 101 | true 102 | 103 | 104 | true 105 | 106 | 107 | true 108 | 109 | 110 | $(SolutionDir)$(Platform)\$(Configuration)\ 111 | $(Platform)\$(Configuration)\ 112 | false 113 | 114 | 115 | false 116 | 117 | 118 | 119 | Disabled 120 | $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) 121 | WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) 122 | true 123 | EnableFastChecks 124 | MultiThreadedDebugDLL 125 | 126 | Level3 127 | EditAndContinue 128 | 129 | 130 | Analyzer.lib;%(AdditionalDependencies) 131 | $(ProjectDir)..\AnalyzerSDK\lib;%(AdditionalLibraryDirectories) 132 | true 133 | Windows 134 | MachineX86 135 | 136 | 137 | 138 | 139 | Disabled 140 | $(ProjectDir)..\LegacyAnalyzerSDK\include;%(AdditionalIncludeDirectories) 141 | WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) 142 | true 143 | EnableFastChecks 144 | MultiThreadedDebug 145 | 146 | 147 | Level3 148 | EditAndContinue 149 | 150 | 151 | Analyzer.lib;%(AdditionalDependencies) 152 | $(ProjectDir)..\LegacyAnalyzerSDK\lib;%(AdditionalLibraryDirectories) 153 | true 154 | Windows 155 | MachineX86 156 | 157 | 158 | 159 | 160 | Disabled 161 | $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) 162 | WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) 163 | EnableFastChecks 164 | MultiThreadedDebugDLL 165 | 166 | 167 | Level3 168 | ProgramDatabase 169 | 170 | 171 | Analyzer64.lib;%(AdditionalDependencies) 172 | $(ProjectDir)..\AnalyzerSDK\lib;%(AdditionalLibraryDirectories) 173 | true 174 | Windows 175 | 176 | 177 | 178 | 179 | Disabled 180 | $(ProjectDir)..\LegacyAnalyzerSDK\include;%(AdditionalIncludeDirectories) 181 | WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) 182 | EnableFastChecks 183 | MultiThreadedDebug 184 | 185 | 186 | Level3 187 | ProgramDatabase 188 | 189 | 190 | Analyzer64.lib;%(AdditionalDependencies) 191 | $(ProjectDir)..\LegacyAnalyzerSDK\lib;%(AdditionalLibraryDirectories) 192 | true 193 | Windows 194 | 195 | 196 | 197 | 198 | MaxSpeed 199 | true 200 | $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) 201 | WIN32;NDEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) 202 | MultiThreadedDLL 203 | true 204 | 205 | Level3 206 | ProgramDatabase 207 | 208 | 209 | Analyzer.lib;%(AdditionalDependencies) 210 | $(ProjectDir)..\AnalyzerSDK\lib;%(AdditionalLibraryDirectories) 211 | true 212 | Windows 213 | true 214 | true 215 | MachineX86 216 | 217 | 218 | 219 | 220 | MaxSpeed 221 | true 222 | $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) 223 | WIN32;NDEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) 224 | MultiThreadedDLL 225 | true 226 | 227 | 228 | Level3 229 | ProgramDatabase 230 | 231 | 232 | Analyzer64.lib;%(AdditionalDependencies) 233 | $(ProjectDir)..\AnalyzerSDK\lib;%(AdditionalLibraryDirectories) 234 | true 235 | Windows 236 | true 237 | true 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /build_analyzer.py: -------------------------------------------------------------------------------- 1 | # Python 3 script to build the analyzer 2 | 3 | import os, glob, platform 4 | 5 | #find out if we're running on mac or linux and set the dynamic library extension 6 | if platform.system().lower() == "darwin": 7 | dylib_ext = ".dylib" 8 | else: 9 | dylib_ext = ".so" 10 | 11 | print("Running on " + platform.system()) 12 | 13 | #make sure the release folder exists, and clean out any .o/.so file if there are any 14 | if not os.path.exists( "release" ): 15 | os.makedirs( "release" ) 16 | 17 | os.chdir( "release" ) 18 | o_files = glob.glob( "*.o" ) 19 | o_files.extend( glob.glob( "*" + dylib_ext ) ) 20 | for o_file in o_files: 21 | os.remove( o_file ) 22 | os.chdir( ".." ) 23 | 24 | 25 | #make sure the debug folder exists, and clean out any .o/.so files if there are any 26 | if not os.path.exists( "debug" ): 27 | os.makedirs( "debug" ) 28 | 29 | os.chdir( "debug" ) 30 | o_files = glob.glob( "*.o" ); 31 | o_files.extend( glob.glob( "*" + dylib_ext ) ) 32 | for o_file in o_files: 33 | os.remove( o_file ) 34 | os.chdir( ".." ) 35 | 36 | #find all the cpp files in /source. We'll compile all of them 37 | os.chdir( "source" ) 38 | cpp_files = glob.glob( "*.cpp" ); 39 | os.chdir( ".." ) 40 | 41 | #specify the search paths/dependencies/options for gcc 42 | include_paths = [ "./AnalyzerSDK/include" ] 43 | link_paths = [ "./AnalyzerSDK/lib" ] 44 | link_dependencies = [ "-lAnalyzer" ] #refers to libAnalyzer.dylib or libAnalyzer.so 45 | 46 | debug_compile_flags = "-O0 -w -c -fpic -g" 47 | release_compile_flags = "-O3 -w -c -fpic" 48 | 49 | def run_command(cmd): 50 | "Display cmd, then run it in a subshell, raise if there's an error" 51 | print(cmd) 52 | if os.system(cmd): 53 | raise Exception("Shell execution returned nonzero status") 54 | 55 | #loop through all the cpp files, build up the gcc command line, and attempt to compile each cpp file 56 | for cpp_file in cpp_files: 57 | 58 | #g++ 59 | command = "g++ " 60 | 61 | #include paths 62 | for path in include_paths: 63 | command += "-I\"" + path + "\" " 64 | 65 | release_command = command 66 | release_command += release_compile_flags 67 | release_command += " -o\"release/" + cpp_file.replace( ".cpp", ".o" ) + "\" " #the output file 68 | release_command += "\"" + "source/" + cpp_file + "\"" #the cpp file to compile 69 | 70 | debug_command = command 71 | debug_command += debug_compile_flags 72 | debug_command += " -o\"debug/" + cpp_file.replace( ".cpp", ".o" ) + "\" " #the output file 73 | debug_command += "\"" + "source/" + cpp_file + "\"" #the cpp file to compile 74 | 75 | #run the commands from the command line 76 | run_command(release_command) 77 | run_command(debug_command) 78 | 79 | #lastly, link 80 | #g++ 81 | command = "g++ " 82 | 83 | #add the library search paths 84 | for link_path in link_paths: 85 | command += "-L\"" + link_path + "\" " 86 | 87 | #add libraries to link against 88 | for link_dependency in link_dependencies: 89 | command += link_dependency + " " 90 | 91 | #make a dynamic (shared) library (.so/.dylib) 92 | 93 | if dylib_ext == ".dylib": 94 | command += "-dynamiclib " 95 | else: 96 | command += "-shared " 97 | 98 | #figgure out what the name of this analyzer is 99 | analyzer_name = "" 100 | for cpp_file in cpp_files: 101 | if cpp_file.endswith( "Analyzer.cpp" ): 102 | analyzer_name = cpp_file.replace( "Analyzer.cpp", "" ) 103 | break 104 | 105 | #the files to create (.so/.dylib files) 106 | if dylib_ext == ".dylib": 107 | release_command = command + "-o release/lib" + analyzer_name + "Analyzer.dylib " 108 | debug_command = command + "-o debug/lib" + analyzer_name + "Analyzer.dylib " 109 | else: 110 | release_command = command + "-o\"release/lib" + analyzer_name + "Analyzer.so\" " 111 | debug_command = command + "-o\"debug/lib" + analyzer_name + "Analyzer.so\" " 112 | 113 | #add all the object files to link 114 | for cpp_file in cpp_files: 115 | release_command += "release/" + cpp_file.replace( ".cpp", ".o" ) + " " 116 | debug_command += "debug/" + cpp_file.replace( ".cpp", ".o" ) + " " 117 | 118 | #run the commands from the command line 119 | run_command(release_command) 120 | run_command(debug_command) 121 | -------------------------------------------------------------------------------- /docs/Analyzer SDK Setup.md: -------------------------------------------------------------------------------- 1 | # Setting up an Analyzer SDK Project 2 | 3 | This document details setting up your analyzer project for development on Windows, Mac, and Linux. 4 | 5 | Documentation for the Analyzer SDK code is still in the older Saleae Analyzer SDK.pdf. 6 | 7 | ## Initial Setup (All Platforms) 8 | 9 | Before continuing this setup guide, please follow the instructions in the readme file to download, fork or clone this repository, and then run the rename_analyzer.py script. 10 | 11 | ## Visual Studio 12 | 13 | To build on Windows, open the visual studio project in the Visual Studio folder, and build. The Visual Studio solution has configurations for 32 bit and 64 bit builds. You will likely need to switch the configuration to 64 bit and build that in order to get the analyzer to load in the Windows software. 14 | 15 | To test your analyzer, you will need to tell the Saleae Logic software where to load find your compiled analyzer dll. 16 | 17 | The four build combinations produce analyzer dll files in the following locations: 18 | ``` 19 | .\Visual Studio\Win32\Debug\Analyzer.dll 20 | .\Visual Studio\Win32\Release\Analyzer.dll 21 | .\Visual Studio\x64\Debug\Analyzer.dll 22 | .\Visual Studio\x64\Release\Analyzer.dll 23 | ``` 24 | 25 | Instructions to tell the Saleae Logic software where to find your new analyzer dll can be found here: 26 | [How to set the developer directory in the Saleae software to use third party or user created analyzers.](http://support.saleae.com/hc/en-us/articles/208667506) 27 | 28 | Once you have set that directory and restarted the software, your new custom analyzer should appear in the list of analyzers you can add. 29 | 30 | ## Debugging an Analyzer with Visual Studio 31 | 32 | Newer versions of the Saleae software cannot be used to debug custom analyzers on Windows. This means that older versions of the software and SDK must be used if you wish to attach a debugger and step through your code. This complicates debugging on Windows, unfortunately, but it can be done. 33 | 34 | *Note: it is impossible to attach a debugger to any version of the software that supports the new products. We are working on a solution to this problem, but for now that means you must rely on the simulation data generator for your analyzer to produce captures you can then debug in the older software.* 35 | 36 | To debug your custom analyzer, you will need to download the 32-bit standalone copy of our older, 1.1.18 software. 37 | 38 | http://downloads.saleae.com/betas/1.1.18/Logic1.1.18BetaWin32Standalone.zip 39 | 40 | This is a sandalone download and does not need to be installed. Just extract the zip file and run the contained Logic.exe. 41 | 42 | Please note - switching between Saleae Logic software versions has a tendency to reset the software's settings. This could cause the analyzer developer directory to get reset. If you no longer see your analyzer in the list, please verify that the analyzer developer directory is still set properly. 43 | 44 | To build and and debug your custom analyzer using the 1.1.14 software, follow these steps: 45 | 46 | - Using Visual Studio, open the solution file in the Visual Studio Folder. 47 | - Select the solution configuration "Debug-Legacy-1.1.14" 48 | - Select the platform "Win32" 49 | - Build the solution 50 | - Launch the 1.1.18 32-bit Logic software. If the analyzer directory is not already configured, set that to the `Visual Studio\Win32\Debug-Legacy-1.1.14` directory, and restart the software. 51 | - The analyzer should now be visible in the list of analyzers you can add. 52 | - In visual studio, open the Debug Menu, and select "Attach to process..." 53 | - Locate Logic.exe in the list, select it, and click the Attach button. 54 | - Add a break point on any line near the top of the WorkerThread() function, such as line 27, mSampleRateHz = GetSampleRate(); 55 | - In the Logic software, add your custom analyzer if you haven't already, and start a simulation. 56 | - The breakpoint should hit 57 | 58 | Optionally you can change the debugger command in visual studio to point to the older Logic.exe binary. Then you will be able to start debugging simply by pressing run in Visual Studio. 59 | 60 | **Common issues on Windows** 61 | 62 | - The software says "Unable to 'LoadLibrary' on dll ... is not a valid Win32 application" 63 | This is most likely because the analyzer was not built for the same platform architecture as the software running it. In almost all cases, this means the analyzer was compiled for 32 bit instead of 64 bit. Details to switch from 32 bit to 64 bit are included in the Analyzer SDK documentation on page 9. First, [add a x64 target to your project](https://msdn.microsoft.com/en-us/library/ms185328(v=vs.120).aspx). Then, edit the linker settings for the 64 bit configuration. Change the additional dependencies item from Analyzer.dll to Analyzer64.dll. 64 | Note: Only the software versions 1.1.16 and later were built for 64 bit. Previous releases, including 1.1.15, were 32 bit only, which is why no 64 bit analyzer dll was provided. 65 | - The Saleae software crashes on launch when the debugger is attached. 66 | Versions after about 1.1.18 no longer allow debuggers to attach. In these cases, we recommend building with the 32 bit version of the 1.1.18 beta and the 1.1.14 SDK, and debug there. This restriction only applies to Windows. 67 | 68 | ## Linux 69 | 70 | *Note: When using git clone, please remember to use --recursive to automatically also clone the AnalyzerSDK submodule* 71 | 72 | After you have cloned, forked, or downloaded the repository, and ran the rename_analyzer.py script, there are two additional steps required to run the analyzer. 73 | 74 | First, if you are using Linux 64 bit, you need to delete the 32 bit libAnalyzer.so file, and rename the libAnalyzer64.so file to just libAnalyzer.so. 75 | 76 | ``` 77 | mv AnalyzerSDK/lib/libAnalyzer64.so AnalyzerSDK/lib/libAnalyzer.so 78 | ``` 79 | 80 | Then run build_analyzer.py 81 | 82 | ``` 83 | python build_analyzer.py 84 | ``` 85 | 86 | That's it! To debug the analyzer, you need to first tell the Saleae Logic software where to find your newly compiled *.so file. 87 | 88 | [How to set the developer directory in the Saleae software to use third party or user created analyzers.](http://support.saleae.com/hc/en-us/articles/208667506) 89 | 90 | The two variants of the newly compiled analyzer can be found here: 91 | 92 | ``` 93 | debug/libAnalyzer.so 94 | release/libAnalyzer.so 95 | ``` 96 | 97 | ### Debugging with GDB on Linux 98 | 99 | To debug your analyzer, you will need to attach gdb to the Logic application, something like this: 100 | ``` 101 | gdb /Home/YourUserName/Desktop/Logic 1.2.14 (64-bit)/Logic 102 | ``` 103 | And then test setting a breakpoint like this: 104 | ``` 105 | break MyAnalyzer::WorkerThread 106 | ``` 107 | Because your analyzer hasn't been loaded yet, GDB will notify you that it can't find this function, and ask if you want to automatically set this breakpoint if a library with a matching function is loaded in the future. Type y 108 | 109 | Then type run to start the application. Add your custom analyzer and start a simulation. This will trigger the breakpoint. 110 | 111 | ## MacOS 112 | 113 | ### Build Script Based Project 114 | 115 | *Note: When using git clone, please remember to use --recursive to automatically also clone the AnalyzerSDK submodule* 116 | 117 | After you have cloned, forked, or downloaded the repository, and ran the rename_analyzer.py script, there is one additional step required to run the analyzer. 118 | 119 | run build_analyzer.py 120 | 121 | ``` 122 | python build_analyzer.py 123 | ``` 124 | 125 | That's it! To debug the analyzer, you need to first tell the Saleae Logic software where to find your newly compiled *.dylib file. 126 | 127 | [How to set the developer directory in the Saleae software to use third party or user created analyzers.](http://support.saleae.com/hc/en-us/articles/208667506) 128 | 129 | ``` 130 | debug/libAnalyzer.dylib 131 | release/libAnalyzer.dylib 132 | ``` 133 | 134 | ### Debugging with GDB on MacOS 135 | 136 | To debug your analyzer, you will need to attach gdb to the Logic application, something like this: 137 | ``` 138 | gdb /Applications/Logic.app/Contents/MacOS/Logic 139 | ``` 140 | And then test setting a breakpoint like this: 141 | ``` 142 | break MyAnalyzer::WorkerThread 143 | ``` 144 | Because your analyzer hasn't been loaded yet, GDB will notify you that it can't find this function, and ask if you want to automatically set this breakpoint if a library with a matching function is loaded in the future. Type y 145 | 146 | Then type run to start the application. Add your custom analyzer and start a simulation. This will trigger the breakpoint. 147 | 148 | 149 | 150 | ### XCode Based Project 151 | 152 | **Note: This section hasn't yet been updated to describe the proper setup using a fork or clone of the new Github repository for the Sample Analyzer. The instructions will still work, but need improvement to work well with the git repository.** 153 | 154 | This section was written using the 1.1.32 Analyzer SDK, Xcode version 7.2.1, and OSX 10.10.5. however it is likely to work with other versions as well. 155 | 156 | - Start Xcode 157 | - Click "Create a new Xcode project" 158 | 159 | ![1](./images/1_-_new_project.png) 160 | 161 | - select "Other" from the left column, and "Empty" from the templates list. 162 | - Click next. 163 | 164 | ![2](./images/2_-_empty_project.png) 165 | 166 | - Enter a name for your Xcode Project. 167 | 168 | ![2.5](./images/2_5_analyzer_name.png) 169 | 170 | - The location should be set to the analyzer SDK folder recently downloaded, "SaleaeAnalyzerSdk-1.1.32". Do not create a new folder, this will be done for you by Xcode. 171 | - Click "Create" 172 | 173 | ![2.75](./images/2_75_-_project_location.png) 174 | 175 | - Back in Finder, copy the file "rename_analyzer.py" and "source" from the downloaded SDK directory into the freshly created folder, which will have the same name as your new analyzer. Shown here the name is "XcodeAnalyzer" 176 | 177 | ![3](./images/3_-_copy_files.png) 178 | 179 | - Open a terminal, and browse to the new project folder in the downloaded SDK folder. 180 | - Run the python script with: 181 | 182 | python rename_analyzer.py 183 | 184 | - first, it will prompt you for the class prefix for all of the source files. All classes and files will be re-named with this prefix. If you type "I2C" the classes and files will be named with "I2CAnalyzer". Please avoid using analyzer in this name, as it will get repeated like this: "I2CAnalyzerAnalyzer" 185 | - Second, it will ask you for the name to display to the user in the "Add Analyzers" menu. This should be the user facing name, and can include spaces. 186 | 187 | ![4](./images/4_-_rename_analyzer_script.png) 188 | 189 | - Next, we need to add a target to the Xcode project. Be sure that the project is selected in the Project Navigator on the left, and then click the menu highlighted below to add a target. 190 | 191 | ![5](./images/5_-_add_target_button.png) 192 | 193 | - This is the target menu. 194 | 195 | ![6](./images/6_-_add_target_menu.png) 196 | 197 | - Select "Framework & Library" under "OS X" in the left column, and select "Library" in the main area. 198 | - Click Next. 199 | 200 | ![7](./images/7_-_library_target.png) 201 | 202 | - Enter a product name, we recommend the the same name as the project, since there will only be one product. 203 | - Under framework, select "None (Plain C/C++ Library) 204 | - For Type, select "Dynamic" 205 | 206 | ![8](./images/8_-_library_settings.png) 207 | 208 | - Next, we need to add the source files. Click File -> Add Files to ""... 209 | - Note: if this is disabled, it is because you do not have the project selected in the Project Navigator. 210 | 211 | ![8.5](./images/8_5_-_add_files_menu.png) 212 | 213 | - Browse to the source folder in the Xcode project folder, and select it. Don't select the contents, be sure to select the folder itself. 214 | - select "Create groups" in the "added folders" section. 215 | - Click Add. 216 | 217 | ![9](./images/9_-_add_files.png) 218 | 219 | - Verify that the files were automatically added to the build phases "Compile Sources" and "Headers". 220 | - Select the project from the Project Navigator if not already selected. 221 | - Click "Build Phases". 222 | - Expand "Compile Sources" and "Headers" 223 | - Under "Headers", also expand "Project". 224 | - Verify that each has 4 files. 225 | 226 | ![9.5](./images/9_5_-_verify_sources_added.png) 227 | 228 | - Click "Build Settings" 229 | - If "Levels" is selected, switch it to "Combined" 230 | 231 | ![10](./images/10_-_build_settings_page.png) 232 | 233 | - Expand the section "Search Paths" 234 | - Locate "Header Search Paths" and edit the value. 235 | - Click the "+" button and enter "../include" in the new entry. 236 | 237 | ![11](./images/11_-_header_includes_search_path.png) 238 | 239 | - Locate "Library Search Paths" in the same section, and edit its value. 240 | - Click the "+" button and enter "../lib" in the new entry. 241 | 242 | ![11.5](./images/11_5_-_add_library_path.png) 243 | 244 | - Return to "Build Phases" and expand the section "Link Binary with Libraries" 245 | - Click the "+" button 246 | 247 | ![12](./images/12_-_add_library_part_1.png) 248 | 249 | - Click "Add Other..." 250 | 251 | ![13](./images/13_-_add_library_part_2.png) 252 | 253 | - Browse to the original SDK folder which contains our Xcode folder. 254 | - Open the "lib" folder 255 | - Select "libAnalyzer.dylib" 256 | - Click Open. 257 | 258 | ![14](./images/14_-_add_library_part_3.png) 259 | 260 | 261 | - At this point, you should build the project, so that the resulting library will be created. 262 | - It's worth mentioning that new Xcode versions do not save build outputs in the project directory. Instead, the default output directory looks like this: 263 | 264 | ~/Library/Developer/Xcode/DerivedData 265 | 266 | - You may want to change it. **The following steps are optional** 267 | 268 | **Optional: change build output folder** 269 | 270 | - Optional step 1: From the file menu, select "Project Settings..." 271 | 272 | ![optional 1](./images/optional_-_project_settings_-_edit_products_folder_menu.png) 273 | 274 | - Optional step 2: in the "Derived Data" dropdown, select "Project-relative Location" 275 | - Click "Done" 276 | 277 | ![optional 2](./images/optional_-_Project_Settings.png) 278 | 279 | - That's it for the optional steps. 280 | 281 | ### Running and Debugging your Analyzer 282 | 283 | - Next we will setup debugging for the project. Be sure to have the latest Saleae Logic Software installed. 284 | - On the Product menu at the top of the screen, select "Scheme" -> "Edit Scheme..." 285 | ![15](./images/15_-_edit_scheme.png) 286 | 287 | - Make sure "Run" is selected on the left. 288 | - Under "Executable" select "Other..." 289 | ![16](./images/16_-_debug_launch_app_menu.png) 290 | 291 | - Browse to the "Applications" folder (or wherever Logic is installed) and select "Logic.app" 292 | - Click Choose. 293 | 294 | ![17](./images/17_-_select_debug_program.png) 295 | 296 | 297 | - Set a breakpoint in the software so that we can test debugging. 298 | - Open "XcodeAnalyzer.cpp" on the left. The name will reflect what you selected as the class prefix in a previous step. In this example, the class prefix was "Xcode". 299 | - In the source file, add a break point to the first line of code in the WorkerThread method. This code runs when the analyzer starts processing data. 300 | 301 | 302 | 303 | ![18](./images/18_-_breakpoint_set.png) 304 | 305 | - Before proceeding, see this article with instructions to configure the software to load your new analyzer: https://trello.com/c/LEFlqhlL 306 | - Be sure to select the folder where the debug version of the custom analyzer is is saved. 307 | 308 | - Once the Saleae logic software has been configured, and has been closed, click run from Xcode. 309 | - The Saleae software should launch a few seconds later. Click the "+" button on the analyzers panel, and then select your analyzer. In this case, the user facing name of the analyzer was set by the Python script to "Xcode Analyzer". Yours may be different. 310 | - If your analyzer is missing, it could indicate that the dylib was not created, or that the developer path was not set properly. Please review the previous steps for any possible errors. 311 | - The settings dialog for your custom analyzer will appear. Click "Save". 312 | 313 | ![19](./images/19_-_logic_software_add_analyzer_menu.png) 314 | 315 | - Here is your fresh new analyzer, now added to the software. Note that our breakpoint hasn't fired yet. If you had captured data previously, it might fire now, since analyzers will automatically start processing if they are added to an existing analyzer. 316 | 317 | ![20](./images/20_-_analyzer_in_Logic.png) 318 | 319 | - Press start to start a simulation. 320 | - Since your analyzer has already been added, the simulator will call your simulation data generator code. The analyzer also starts processing the moment data has been captured, so your breakpoint should fire immediately. 321 | 322 | ![21](./images/21_-_logic_software_start_button.png) 323 | 324 | - Here you can see that the debugger was attached and your break point has been hit. You can examine variables, set new break points, or press continue from the debug menu at the bottom. 325 | 326 | ![22](./images/22_-_breakpoint_hit.png) 327 | 328 | - Congratulations! You now have an Xcode project for which you can use to develop a custom analyzer for the Saleae software. 329 | 330 | If you have any questions, please contact support. -------------------------------------------------------------------------------- /docs/Saleae Analyzer SDK (older).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/Saleae Analyzer SDK (older).pdf -------------------------------------------------------------------------------- /docs/images/10_-_build_settings_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/10_-_build_settings_page.png -------------------------------------------------------------------------------- /docs/images/11_-_header_includes_search_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/11_-_header_includes_search_path.png -------------------------------------------------------------------------------- /docs/images/11_5_-_add_library_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/11_5_-_add_library_path.png -------------------------------------------------------------------------------- /docs/images/12_-_add_library_part_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/12_-_add_library_part_1.png -------------------------------------------------------------------------------- /docs/images/13_-_add_library_part_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/13_-_add_library_part_2.png -------------------------------------------------------------------------------- /docs/images/14_-_add_library_part_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/14_-_add_library_part_3.png -------------------------------------------------------------------------------- /docs/images/15_-_edit_scheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/15_-_edit_scheme.png -------------------------------------------------------------------------------- /docs/images/16_-_debug_launch_app_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/16_-_debug_launch_app_menu.png -------------------------------------------------------------------------------- /docs/images/17_-_select_debug_program.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/17_-_select_debug_program.png -------------------------------------------------------------------------------- /docs/images/18_-_breakpoint_set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/18_-_breakpoint_set.png -------------------------------------------------------------------------------- /docs/images/19_-_logic_software_add_analyzer_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/19_-_logic_software_add_analyzer_menu.png -------------------------------------------------------------------------------- /docs/images/1_-_new_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/1_-_new_project.png -------------------------------------------------------------------------------- /docs/images/20_-_analyzer_in_Logic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/20_-_analyzer_in_Logic.png -------------------------------------------------------------------------------- /docs/images/21_-_logic_software_start_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/21_-_logic_software_start_button.png -------------------------------------------------------------------------------- /docs/images/22_-_breakpoint_hit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/22_-_breakpoint_hit.png -------------------------------------------------------------------------------- /docs/images/2_-_empty_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/2_-_empty_project.png -------------------------------------------------------------------------------- /docs/images/2_5_analyzer_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/2_5_analyzer_name.png -------------------------------------------------------------------------------- /docs/images/2_75_-_project_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/2_75_-_project_location.png -------------------------------------------------------------------------------- /docs/images/3_-_copy_files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/3_-_copy_files.png -------------------------------------------------------------------------------- /docs/images/4_-_rename_analyzer_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/4_-_rename_analyzer_script.png -------------------------------------------------------------------------------- /docs/images/5_-_add_target_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/5_-_add_target_button.png -------------------------------------------------------------------------------- /docs/images/6_-_add_target_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/6_-_add_target_menu.png -------------------------------------------------------------------------------- /docs/images/7_-_library_target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/7_-_library_target.png -------------------------------------------------------------------------------- /docs/images/8_-_library_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/8_-_library_settings.png -------------------------------------------------------------------------------- /docs/images/8_5_-_add_files_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/8_5_-_add_files_menu.png -------------------------------------------------------------------------------- /docs/images/9_-_add_files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/9_-_add_files.png -------------------------------------------------------------------------------- /docs/images/9_5_-_verify_sources_added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/9_5_-_verify_sources_added.png -------------------------------------------------------------------------------- /docs/images/optional_-_Project_Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/optional_-_Project_Settings.png -------------------------------------------------------------------------------- /docs/images/optional_-_project_settings_-_edit_products_folder_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/docs/images/optional_-_project_settings_-_edit_products_folder_menu.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ISO7816Analyzer 2 | 3 | This is a logic analyzer plugin for ISO7816, the protocol usde by smartcards and secure elemnts. 4 | 5 | It can be used to analyze a wide variety of things, for example: 6 | - Credit card communication between a PoS-terminal and the card 7 | - Secure Element communication on Bitcoin wallets (For example on the Ledger Nano S) 8 | - etc 9 | 10 | It also supports settings the range on which it analyzes - this is useful when the card switches between different speeds. 11 | 12 | ## Screenshots 13 | 14 | Example of the analyzer in action: The ATR of a Ledger Nano S: 15 | ![Example of the analyzer in action: The ATR of a Ledger Nano S](screenshots/analyzer.png) 16 | 17 | The configuration dialog: 18 | ![The configuration dialog](screenshots/config.png) 19 | 20 | 21 | ## Building 22 | 23 | First, make sure that you cloned the repository including the submodules: 24 | 25 | ``` 26 | git clone --recursive https://github.com/nezza/ISO7816Analyzer.git 27 | ``` 28 | 29 | And then simply run: 30 | 31 | ``` 32 | python3 build_analyzer.py 33 | ``` 34 | -------------------------------------------------------------------------------- /screenshots/analyzer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/screenshots/analyzer.png -------------------------------------------------------------------------------- /screenshots/config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nezza/ISO7816Analyzer/52d7b271ab5e8daac7881defaa4e7d5b36677206/screenshots/config.png -------------------------------------------------------------------------------- /source/ISO7816Analyzer.cpp: -------------------------------------------------------------------------------- 1 | #include "ISO7816Analyzer.h" 2 | #include "ISO7816AnalyzerSettings.h" 3 | #include 4 | 5 | #include 6 | ISO7816Analyzer::ISO7816Analyzer() 7 | : Analyzer2(), 8 | mSettings( new ISO7816AnalyzerSettings() ), 9 | mSimulationInitilized( false ) 10 | { 11 | SetAnalyzerSettings( mSettings.get() ); 12 | } 13 | 14 | ISO7816Analyzer::~ISO7816Analyzer() 15 | { 16 | KillThread(); 17 | } 18 | 19 | void ISO7816Analyzer::SetupResults() 20 | { 21 | mResults.reset( new ISO7816AnalyzerResults( this, mSettings.get() ) ); 22 | SetAnalyzerResults( mResults.get() ); 23 | mResults->AddChannelBubblesWillAppearOn( mSettings->mInputChannel ); 24 | } 25 | 26 | void ISO7816Analyzer::WorkerThread() 27 | { 28 | mSampleRateHz = GetSampleRate(); 29 | U64 start_sample = (mSampleRateHz/1000) * mSettings->mStartTime; 30 | U64 end_sample = (mSampleRateHz/1000) * mSettings->mEndTime; 31 | 32 | 33 | mSerial = GetAnalyzerChannelData( mSettings->mInputChannel ); 34 | 35 | if( start_sample ) 36 | mSerial->Advance(start_sample); 37 | 38 | // Find first rising edge 39 | if( mSerial->GetBitState() == BIT_LOW ) 40 | mSerial->AdvanceToNextEdge(); 41 | 42 | 43 | double smallest_period = 1.0/mSettings->mBitRate; 44 | 45 | U32 samples_per_bit = mSampleRateHz / (1.0/smallest_period); 46 | 47 | U32 samples_half = samples_per_bit/2; 48 | 49 | 50 | for( ; ; ) 51 | { 52 | U8 data = 0; 53 | U8 mask = 1; 54 | 55 | 56 | mSerial->AdvanceToNextEdge(); //falling edge -- beginning of the start bit 57 | 58 | if(end_sample && mSerial->GetSampleNumber() > end_sample) 59 | continue; 60 | 61 | mSerial->Advance(samples_half); 62 | 63 | // add dot on start bit 64 | mResults->AddMarker( mSerial->GetSampleNumber(), AnalyzerResults::Dot, mSettings->mInputChannel ); 65 | 66 | 67 | U64 starting_sample = mSerial->GetSampleNumber(); 68 | 69 | mSerial->Advance( samples_per_bit ); 70 | 71 | for( U32 i=0; i<8; i++ ) 72 | { 73 | //let's put a dot exactly where we sample this bit: 74 | mResults->AddMarker( mSerial->GetSampleNumber(), AnalyzerResults::Dot, mSettings->mInputChannel ); 75 | 76 | if( mSerial->GetBitState() == BIT_HIGH ) 77 | data |= mask; 78 | 79 | mSerial->Advance( samples_per_bit ); 80 | 81 | mask = mask << 1; 82 | } 83 | 84 | 85 | // add dot on stop bit 86 | mResults->AddMarker( mSerial->GetSampleNumber(), AnalyzerResults::Dot, mSettings->mInputChannel ); 87 | 88 | // Advance over stopbit 89 | mSerial->Advance(samples_per_bit); 90 | 91 | 92 | 93 | //we have a byte to save. 94 | Frame frame; 95 | frame.mData1 = data; 96 | frame.mFlags = 0; 97 | frame.mStartingSampleInclusive = starting_sample; 98 | frame.mEndingSampleInclusive = mSerial->GetSampleNumber(); 99 | 100 | mResults->AddFrame( frame ); 101 | mResults->CommitResults(); 102 | ReportProgress( frame.mEndingSampleInclusive ); 103 | } 104 | } 105 | 106 | bool ISO7816Analyzer::NeedsRerun() 107 | { 108 | return false; 109 | } 110 | 111 | U32 ISO7816Analyzer::GenerateSimulationData( U64 minimum_sample_index, U32 device_sample_rate, SimulationChannelDescriptor** simulation_channels ) 112 | { 113 | if( mSimulationInitilized == false ) 114 | { 115 | mSimulationDataGenerator.Initialize( GetSimulationSampleRate(), mSettings.get() ); 116 | mSimulationInitilized = true; 117 | } 118 | 119 | return mSimulationDataGenerator.GenerateSimulationData( minimum_sample_index, device_sample_rate, simulation_channels ); 120 | } 121 | 122 | U32 ISO7816Analyzer::GetMinimumSampleRateHz() 123 | { 124 | return mSettings->mBitRate * 4; 125 | } 126 | 127 | const char* ISO7816Analyzer::GetAnalyzerName() const 128 | { 129 | return "ISO7816"; 130 | } 131 | 132 | const char* GetAnalyzerName() 133 | { 134 | return "ISO7816"; 135 | } 136 | 137 | Analyzer* CreateAnalyzer() 138 | { 139 | return new ISO7816Analyzer(); 140 | } 141 | 142 | void DestroyAnalyzer( Analyzer* analyzer ) 143 | { 144 | delete analyzer; 145 | } -------------------------------------------------------------------------------- /source/ISO7816Analyzer.h: -------------------------------------------------------------------------------- 1 | #ifndef ISO7816_ANALYZER_H 2 | #define ISO7816_ANALYZER_H 3 | 4 | #include 5 | #include "ISO7816AnalyzerResults.h" 6 | #include "SimpleSerialSimulationDataGenerator.h" 7 | 8 | class ISO7816AnalyzerSettings; 9 | class ANALYZER_EXPORT ISO7816Analyzer : public Analyzer2 10 | { 11 | public: 12 | ISO7816Analyzer(); 13 | virtual ~ISO7816Analyzer(); 14 | 15 | virtual void SetupResults(); 16 | virtual void WorkerThread(); 17 | 18 | virtual U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channels ); 19 | virtual U32 GetMinimumSampleRateHz(); 20 | 21 | virtual const char* GetAnalyzerName() const; 22 | virtual bool NeedsRerun(); 23 | 24 | protected: //vars 25 | std::auto_ptr< ISO7816AnalyzerSettings > mSettings; 26 | std::auto_ptr< ISO7816AnalyzerResults > mResults; 27 | AnalyzerChannelData* mSerial; 28 | 29 | SimpleSerialSimulationDataGenerator mSimulationDataGenerator; 30 | bool mSimulationInitilized; 31 | 32 | //Serial analysis vars: 33 | U32 mSampleRateHz; 34 | U32 mStartOfStopBitOffset; 35 | U32 mEndOfStopBitOffset; 36 | }; 37 | 38 | extern "C" ANALYZER_EXPORT const char* __cdecl GetAnalyzerName(); 39 | extern "C" ANALYZER_EXPORT Analyzer* __cdecl CreateAnalyzer( ); 40 | extern "C" ANALYZER_EXPORT void __cdecl DestroyAnalyzer( Analyzer* analyzer ); 41 | 42 | #endif //ISO7816_ANALYZER_H 43 | -------------------------------------------------------------------------------- /source/ISO7816AnalyzerResults.cpp: -------------------------------------------------------------------------------- 1 | #include "ISO7816AnalyzerResults.h" 2 | #include 3 | #include "ISO7816Analyzer.h" 4 | #include "ISO7816AnalyzerSettings.h" 5 | #include 6 | #include 7 | 8 | ISO7816AnalyzerResults::ISO7816AnalyzerResults( ISO7816Analyzer* analyzer, ISO7816AnalyzerSettings* settings ) 9 | : AnalyzerResults(), 10 | mSettings( settings ), 11 | mAnalyzer( analyzer ) 12 | { 13 | } 14 | 15 | ISO7816AnalyzerResults::~ISO7816AnalyzerResults() 16 | { 17 | } 18 | 19 | void ISO7816AnalyzerResults::GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base ) 20 | { 21 | ClearResultStrings(); 22 | Frame frame = GetFrame( frame_index ); 23 | 24 | char number_str[128]; 25 | AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 ); 26 | AddResultString( number_str ); 27 | } 28 | 29 | void ISO7816AnalyzerResults::GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id ) 30 | { 31 | std::ofstream file_stream( file, std::ios::out ); 32 | 33 | U64 trigger_sample = mAnalyzer->GetTriggerSample(); 34 | U32 sample_rate = mAnalyzer->GetSampleRate(); 35 | 36 | file_stream << "Time [s],Value" << std::endl; 37 | 38 | U64 num_frames = GetNumFrames(); 39 | for( U32 i=0; i < num_frames; i++ ) 40 | { 41 | Frame frame = GetFrame( i ); 42 | 43 | char time_str[128]; 44 | AnalyzerHelpers::GetTimeString( frame.mStartingSampleInclusive, trigger_sample, sample_rate, time_str, 128 ); 45 | 46 | char number_str[128]; 47 | AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 ); 48 | 49 | file_stream << time_str << "," << number_str << std::endl; 50 | 51 | if( UpdateExportProgressAndCheckForCancel( i, num_frames ) == true ) 52 | { 53 | file_stream.close(); 54 | return; 55 | } 56 | } 57 | 58 | file_stream.close(); 59 | } 60 | 61 | void ISO7816AnalyzerResults::GenerateFrameTabularText( U64 frame_index, DisplayBase display_base ) 62 | { 63 | #ifdef SUPPORTS_PROTOCOL_SEARCH 64 | Frame frame = GetFrame( frame_index ); 65 | ClearTabularText(); 66 | 67 | char number_str[128]; 68 | AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 ); 69 | AddTabularText( number_str ); 70 | #endif 71 | } 72 | 73 | void ISO7816AnalyzerResults::GeneratePacketTabularText( U64 packet_id, DisplayBase display_base ) 74 | { 75 | //not supported 76 | 77 | } 78 | 79 | void ISO7816AnalyzerResults::GenerateTransactionTabularText( U64 transaction_id, DisplayBase display_base ) 80 | { 81 | //not supported 82 | } -------------------------------------------------------------------------------- /source/ISO7816AnalyzerResults.h: -------------------------------------------------------------------------------- 1 | #ifndef ISO7816_ANALYZER_RESULTS 2 | #define ISO7816_ANALYZER_RESULTS 3 | 4 | #include 5 | 6 | class ISO7816Analyzer; 7 | class ISO7816AnalyzerSettings; 8 | 9 | class ISO7816AnalyzerResults : public AnalyzerResults 10 | { 11 | public: 12 | ISO7816AnalyzerResults( ISO7816Analyzer* analyzer, ISO7816AnalyzerSettings* settings ); 13 | virtual ~ISO7816AnalyzerResults(); 14 | 15 | virtual void GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base ); 16 | virtual void GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id ); 17 | 18 | virtual void GenerateFrameTabularText(U64 frame_index, DisplayBase display_base ); 19 | virtual void GeneratePacketTabularText( U64 packet_id, DisplayBase display_base ); 20 | virtual void GenerateTransactionTabularText( U64 transaction_id, DisplayBase display_base ); 21 | 22 | protected: //functions 23 | 24 | protected: //vars 25 | ISO7816AnalyzerSettings* mSettings; 26 | ISO7816Analyzer* mAnalyzer; 27 | }; 28 | 29 | #endif //ISO7816_ANALYZER_RESULTS 30 | -------------------------------------------------------------------------------- /source/ISO7816AnalyzerSettings.cpp: -------------------------------------------------------------------------------- 1 | #include "ISO7816AnalyzerSettings.h" 2 | #include 3 | 4 | 5 | ISO7816AnalyzerSettings::ISO7816AnalyzerSettings() 6 | : mInputChannel( UNDEFINED_CHANNEL ), 7 | mBitRate( 9600 ), 8 | mStartTime( 0 ), 9 | mEndTime( 0 ) 10 | { 11 | mInputChannelInterface.reset( new AnalyzerSettingInterfaceChannel() ); 12 | mInputChannelInterface->SetTitleAndTooltip( "ISO7816", "Simple ISO7816 decoder." ); 13 | mInputChannelInterface->SetChannel( mInputChannel ); 14 | 15 | mBitRateInterface.reset( new AnalyzerSettingInterfaceInteger() ); 16 | mBitRateInterface->SetTitleAndTooltip( "Bit Rate (Bits/S)", "Specify the bit rate in bits per second." ); 17 | mBitRateInterface->SetMax( 6000000 ); 18 | mBitRateInterface->SetMin( 1 ); 19 | mBitRateInterface->SetInteger( mBitRate ); 20 | 21 | 22 | mStartTimeInterface.reset(new AnalyzerSettingInterfaceInteger() ); 23 | mStartTimeInterface->SetTitleAndTooltip( "Start time (ms)", "Specify where the analyzer should start." ); 24 | mStartTimeInterface->SetMax( 10000000 ); 25 | mStartTimeInterface->SetMin( 0 ); 26 | mStartTimeInterface->SetInteger( mBitRate ); 27 | mEndTimeInterface.reset(new AnalyzerSettingInterfaceInteger() ); 28 | mEndTimeInterface->SetTitleAndTooltip( "End time (ms)", "Specify where the analyzer should stop." ); 29 | mEndTimeInterface->SetMax( 10000000 ); 30 | mEndTimeInterface->SetMin( 0 ); 31 | mEndTimeInterface->SetInteger( mBitRate ); 32 | 33 | 34 | AddInterface( mInputChannelInterface.get() ); 35 | AddInterface( mBitRateInterface.get() ); 36 | AddInterface( mStartTimeInterface.get() ); 37 | AddInterface( mEndTimeInterface.get() ); 38 | 39 | AddExportOption( 0, "Export as text/csv file" ); 40 | AddExportExtension( 0, "text", "txt" ); 41 | AddExportExtension( 0, "csv", "csv" ); 42 | 43 | ClearChannels(); 44 | AddChannel( mInputChannel, "I/O", false ); 45 | } 46 | 47 | ISO7816AnalyzerSettings::~ISO7816AnalyzerSettings() 48 | { 49 | } 50 | 51 | bool ISO7816AnalyzerSettings::SetSettingsFromInterfaces() 52 | { 53 | mInputChannel = mInputChannelInterface->GetChannel(); 54 | mBitRate = mBitRateInterface->GetInteger(); 55 | mStartTime = mStartTimeInterface->GetInteger(); 56 | mEndTime = mEndTimeInterface->GetInteger(); 57 | 58 | ClearChannels(); 59 | AddChannel( mInputChannel, "ISO7816", true ); 60 | 61 | return true; 62 | } 63 | 64 | void ISO7816AnalyzerSettings::UpdateInterfacesFromSettings() 65 | { 66 | mInputChannelInterface->SetChannel( mInputChannel ); 67 | mBitRateInterface->SetInteger( mBitRate ); 68 | mStartTimeInterface->SetInteger( mStartTime ); 69 | mEndTimeInterface->SetInteger( mEndTime ); 70 | } 71 | 72 | void ISO7816AnalyzerSettings::LoadSettings( const char* settings ) 73 | { 74 | SimpleArchive text_archive; 75 | text_archive.SetString( settings ); 76 | 77 | text_archive >> mInputChannel; 78 | text_archive >> mBitRate; 79 | text_archive >> mStartTime; 80 | text_archive >> mEndTime; 81 | 82 | ClearChannels(); 83 | AddChannel( mInputChannel, "ISO7816", true ); 84 | 85 | UpdateInterfacesFromSettings(); 86 | } 87 | 88 | const char* ISO7816AnalyzerSettings::SaveSettings() 89 | { 90 | SimpleArchive text_archive; 91 | 92 | text_archive << mInputChannel; 93 | text_archive << mBitRate; 94 | text_archive << mStartTime; 95 | text_archive << mEndTime; 96 | 97 | return SetReturnString( text_archive.GetString() ); 98 | } 99 | -------------------------------------------------------------------------------- /source/ISO7816AnalyzerSettings.h: -------------------------------------------------------------------------------- 1 | #ifndef ISO7816_ANALYZER_SETTINGS 2 | #define ISO7816_ANALYZER_SETTINGS 3 | 4 | #include 5 | #include 6 | 7 | class ISO7816AnalyzerSettings : public AnalyzerSettings 8 | { 9 | public: 10 | ISO7816AnalyzerSettings(); 11 | virtual ~ISO7816AnalyzerSettings(); 12 | 13 | virtual bool SetSettingsFromInterfaces(); 14 | void UpdateInterfacesFromSettings(); 15 | virtual void LoadSettings( const char* settings ); 16 | virtual const char* SaveSettings(); 17 | 18 | 19 | Channel mInputChannel; 20 | U32 mBitRate; 21 | U64 mStartTime; 22 | U64 mEndTime; 23 | 24 | protected: 25 | std::auto_ptr< AnalyzerSettingInterfaceChannel > mInputChannelInterface; 26 | std::auto_ptr< AnalyzerSettingInterfaceInteger > mBitRateInterface; 27 | std::auto_ptr< AnalyzerSettingInterfaceInteger > mStartTimeInterface; 28 | std::auto_ptr< AnalyzerSettingInterfaceInteger > mEndTimeInterface; 29 | }; 30 | 31 | #endif //ISO7816_ANALYZER_SETTINGS 32 | -------------------------------------------------------------------------------- /source/SimpleSerialSimulationDataGenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "SimpleSerialSimulationDataGenerator.h" 2 | #include "ISO7816AnalyzerSettings.h" 3 | 4 | #include 5 | 6 | SimpleSerialSimulationDataGenerator::SimpleSerialSimulationDataGenerator() 7 | : mSerialText( "My first analyzer, woo hoo!" ), 8 | mStringIndex( 0 ) 9 | { 10 | } 11 | 12 | SimpleSerialSimulationDataGenerator::~SimpleSerialSimulationDataGenerator() 13 | { 14 | } 15 | 16 | void SimpleSerialSimulationDataGenerator::Initialize( U32 simulation_sample_rate, ISO7816AnalyzerSettings* settings ) 17 | { 18 | mSimulationSampleRateHz = simulation_sample_rate; 19 | mSettings = settings; 20 | 21 | mSerialSimulationData.SetChannel( mSettings->mInputChannel ); 22 | mSerialSimulationData.SetSampleRate( simulation_sample_rate ); 23 | mSerialSimulationData.SetInitialBitState( BIT_HIGH ); 24 | } 25 | 26 | U32 SimpleSerialSimulationDataGenerator::GenerateSimulationData( U64 largest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel ) 27 | { 28 | U64 adjusted_largest_sample_requested = AnalyzerHelpers::AdjustSimulationTargetSample( largest_sample_requested, sample_rate, mSimulationSampleRateHz ); 29 | 30 | while( mSerialSimulationData.GetCurrentSampleNumber() < adjusted_largest_sample_requested ) 31 | { 32 | CreateSerialByte(); 33 | } 34 | 35 | *simulation_channel = &mSerialSimulationData; 36 | return 1; 37 | } 38 | 39 | void SimpleSerialSimulationDataGenerator::CreateSerialByte() 40 | { 41 | U32 samples_per_bit = mSimulationSampleRateHz / mSettings->mBitRate; 42 | 43 | U8 byte = mSerialText[ mStringIndex ]; 44 | mStringIndex++; 45 | if( mStringIndex == mSerialText.size() ) 46 | mStringIndex = 0; 47 | 48 | //we're currenty high 49 | //let's move forward a little 50 | mSerialSimulationData.Advance( samples_per_bit * 10 ); 51 | 52 | mSerialSimulationData.Transition(); //low-going edge for start bit 53 | mSerialSimulationData.Advance( samples_per_bit ); //add start bit time 54 | 55 | U8 mask = 0x1 << 7; 56 | for( U32 i=0; i<8; i++ ) 57 | { 58 | if( ( byte & mask ) != 0 ) 59 | mSerialSimulationData.TransitionIfNeeded( BIT_HIGH ); 60 | else 61 | mSerialSimulationData.TransitionIfNeeded( BIT_LOW ); 62 | 63 | mSerialSimulationData.Advance( samples_per_bit ); 64 | mask = mask >> 1; 65 | } 66 | 67 | mSerialSimulationData.TransitionIfNeeded( BIT_HIGH ); //we need to end high 68 | 69 | //lets pad the end a bit for the stop bit: 70 | mSerialSimulationData.Advance( samples_per_bit ); 71 | } 72 | -------------------------------------------------------------------------------- /source/SimpleSerialSimulationDataGenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLESERIAL_SIMULATION_DATA_GENERATOR 2 | #define SIMPLESERIAL_SIMULATION_DATA_GENERATOR 3 | 4 | #include 5 | #include 6 | class ISO7816AnalyzerSettings; 7 | 8 | class SimpleSerialSimulationDataGenerator 9 | { 10 | public: 11 | SimpleSerialSimulationDataGenerator(); 12 | ~SimpleSerialSimulationDataGenerator(); 13 | 14 | void Initialize( U32 simulation_sample_rate, ISO7816AnalyzerSettings* settings ); 15 | U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel ); 16 | 17 | protected: 18 | ISO7816AnalyzerSettings* mSettings; 19 | U32 mSimulationSampleRateHz; 20 | 21 | protected: 22 | void CreateSerialByte(); 23 | std::string mSerialText; 24 | U32 mStringIndex; 25 | 26 | SimulationChannelDescriptor mSerialSimulationData; 27 | 28 | }; 29 | #endif //SIMPLESERIAL_SIMULATION_DATA_GENERATOR --------------------------------------------------------------------------------