├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── gradle.xml ├── misc.xml ├── shelf │ ├── Uncommitted_changes_before_Update_at_10_9_2021_4_18_PM_[Default_Changelist] │ │ └── shelved.patch │ ├── Uncommitted_changes_before_Update_at_10_9_2021_4_18_PM__Default_Changelist_.xml │ ├── Uncommitted_changes_before_Update_at_12_12_2021_12_37_PM_[Default_Changelist] │ │ └── shelved.patch │ └── Uncommitted_changes_before_Update_at_12_12_2021_12_37_PM__Default_Changelist_.xml └── vcs.xml ├── LICENSE ├── PID ├── PIDList22-USA.csv └── PIDList3E-USA.csv ├── README.md ├── app ├── .gitignore ├── build.gradle ├── debug │ ├── app-debug.apk │ └── output-metadata.json ├── proguard-rules.pro ├── release │ ├── app-release.aab │ ├── app-release.apk │ └── output-metadata.json └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ └── com │ │ └── app │ │ └── simostools │ │ ├── BTService.kt │ │ ├── CockpitFragment.kt │ │ ├── ColorFragment.kt │ │ ├── ConfigFile.kt │ │ ├── Constants.kt │ │ ├── DTCs.kt │ │ ├── DebugLog.kt │ │ ├── ExpressionParsing.kt │ │ ├── FlashUtilities.kt │ │ ├── FlashingFragment.kt │ │ ├── LogFile.kt │ │ ├── LogViewerEnabledFragment.kt │ │ ├── LogViewerFragment.kt │ │ ├── LogViewerTabsFragment.kt │ │ ├── LoggingLayoutFragment.kt │ │ ├── LoggingMainFragment.kt │ │ ├── LoggingViewPager.kt │ │ ├── MainActivity.kt │ │ ├── MainFragment.kt │ │ ├── PIDCSVFile.kt │ │ ├── PIDs.kt │ │ ├── SettingsCarFragment.kt │ │ ├── SettingsGeneralFragment.kt │ │ ├── SettingsLoggingFragment.kt │ │ ├── SettingsMainFragment.kt │ │ ├── SettingsViewAdapter.kt │ │ ├── SettingsViewPager.kt │ │ ├── SwitchAdapter.kt │ │ ├── SwitchButton.kt │ │ ├── SwitchCockpit.kt │ │ ├── SwitchGauge.kt │ │ ├── SwitchGraph.kt │ │ ├── UDSdtc.kt │ │ ├── UDSflash.kt │ │ ├── UDSinfo.kt │ │ ├── UDSlog.kt │ │ └── UtilitiesFragment.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── simoslogger.png │ └── simostools.png │ ├── layout-land │ ├── fragment_color.xml │ ├── fragment_flashing.xml │ ├── fragment_log_viewer.xml │ ├── fragment_logging_main.xml │ ├── fragment_main.xml │ ├── fragment_pid.xml │ ├── fragment_settings_main.xml │ └── fragment_utilities.xml │ ├── layout-sw600dp-land │ ├── fragment_color.xml │ ├── fragment_flashing.xml │ ├── fragment_log_viewer.xml │ ├── fragment_logging_main.xml │ ├── fragment_main.xml │ ├── fragment_pid.xml │ ├── fragment_settings_main.xml │ └── fragment_utilities.xml │ ├── layout-sw600dp │ ├── fragment_color.xml │ ├── fragment_flashing.xml │ ├── fragment_log_viewer.xml │ ├── fragment_logging_main.xml │ ├── fragment_main.xml │ ├── fragment_message.xml │ ├── fragment_pid.xml │ ├── fragment_settings_main.xml │ ├── fragment_settings_pid.xml │ └── fragment_utilities.xml │ ├── layout │ ├── activity_main.xml │ ├── fragment_cockpit.xml │ ├── fragment_color.xml │ ├── fragment_flashing.xml │ ├── fragment_log_viewer.xml │ ├── fragment_log_viewer_enabled.xml │ ├── fragment_log_viewer_tabs.xml │ ├── fragment_logging_layout.xml │ ├── fragment_logging_main.xml │ ├── fragment_main.xml │ ├── fragment_message.xml │ ├── fragment_pid.xml │ ├── fragment_settings_car.xml │ ├── fragment_settings_general.xml │ ├── fragment_settings_main.xml │ ├── fragment_settings_mode22.xml │ ├── fragment_settings_mode3e.xml │ ├── fragment_settings_modedsg.xml │ ├── fragment_settings_pid.xml │ └── fragment_utilities.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── navigation │ └── nav_graph_main.xml │ ├── raw │ └── pops.mp3 │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── ic_launcher_background.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── screenshot1.jpg ├── screenshot2.jpg ├── screenshot3.jpg ├── screenshot4.jpg ├── screenshot5.jpg └── screenshot6.jpg ├── settings.gradle └── simos.jks /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Simos Tools -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/shelf/Uncommitted_changes_before_Update_at_10_9_2021_4_18_PM__Default_Changelist_.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/shelf/Uncommitted_changes_before_Update_at_12_12_2021_12_37_PM__Default_Changelist_.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PID/PIDList22-USA.csv: -------------------------------------------------------------------------------- 1 | Name,Unit,Equation,Format,Address,Length,Signed,ProgMin,ProgMax,WarnMin,WarnMax,Smoothing,Enabled,Tabs,Assign To 2 | AFR,AFR,x / 69.6598639456,%01.1f,0x10c0,2,FALSE,11.025,18.375,-1,5000,0,TRUE,Default, 3 | AFR SP,AFR,x / 2229.11564626,%01.1f,0xf444,2,FALSE,11.025,18.375,-1,5000,0,TRUE,, 4 | Airflow,kg/hr,x,%01.0f,0x2032,2,FALSE,0,2000,-100,50000,0,TRUE,,f 5 | Airmass,mg/stk,f / r * 8333.33333333,%01.0f,0xffff,1,FALSE,0,2000,-100,50000,0,TRUE,, 6 | Ambient Press,kPa,x / 120.6017666543982,%01.1f,0x13ca,2,FALSE,50,105,-1,120,0,TRUE,,a 7 | Ambient Temp,°F,x * 1.8 - 40,%01.0f,0xf446,1,FALSE,0,120,-100,200,0,TRUE,, 8 | Battery Volts,V,x * 0.1015625,%01.1f,0x14a6,1,FALSE,10,15,7,16,0,TRUE,, 9 | Boost,psi,(m - a) * 0.145077720207254,%01.1f,0xffff,1,FALSE,-14.7,35,-100,100,0,TRUE,Default, 10 | Coolant Temp,°F,x * 1.8 - 40,%01.0f,0xf405,1,FALSE,0,250,-100,300,0,TRUE,Default, 11 | Current Gear,,x + 1,%01.0f,0x210f,2,FALSE,0,6,-1,100,0,TRUE,, 12 | Engine Speed,rpm,x / 4,%01.0f,0xf40c,2,FALSE,0,7000,-1,10000,0,TRUE,,r 13 | Eth Content,%,x / 2.55,%01.1f,0xf452,1,FALSE,0,100,-100,100,0,TRUE,Default, 14 | Exhaust Cam,°,(x / 10) - 24,%01.1f,0x201a,2,TRUE,-45,45,-100,100,0,TRUE,, 15 | FP DI,psi,x * 1.45038,%01.0f,0x2027,2,FALSE,0,3500,-1,5000,0,TRUE,, 16 | FP DI SP,psi,x * 1.45038,%01.0f,0x293b,2,FALSE,0,3500,-1,5000,0,TRUE,, 17 | FP MPI,psi,x * 0.0145038,%01.2f,0x2025,2,FALSE,0,150,-1,200,0,TRUE,, 18 | FP MPI SP,psi,x * 0.0145038,%01.2f,0x2932,2,FALSE,0,150,-1,200,0,TRUE,, 19 | HPFP Eff Vol,%,x / 100,%01.1f,0x209a,2,FALSE,0,100,-1000,1000,0,TRUE,, 20 | IAT,°F,x * 1.35 - 54.4,%01.0f,0x1001,1,FALSE,0,200,-100,500,0,TRUE,Default, 21 | Ign Timing Avg,°,x / 100,%01.1f,0x2004,2,TRUE,-10,40,-100,100,0,TRUE,, 22 | Inj PW DI,ms,x / 250,%01.1f,0x13a0,2,FALSE,0,20,-1000,1000,0,TRUE,, 23 | Inj PW MPI,ms,x / 250,%01.1f,0x13ac,2,FALSE,0,20,-1000,1000,0,TRUE,, 24 | Intake Cam,°,30 - (x / 10),%01.1f,0x201e,2,TRUE,-45,45,-100,100,0,TRUE,, 25 | Knock Avg,°,(w + x + y + z) / 4,%01.2f,0xffff,1,FALSE,0,-5,-3,1,0,TRUE,Default, 26 | Knock Cyl 1,°,x / 100,%01.2f,0x200a,2,TRUE,0,-5,-5,1,0,TRUE,,w 27 | Knock Cyl 2,°,x / 100,%01.2f,0x200b,2,TRUE,0,-5,-5,1,0,TRUE,,x 28 | Knock Cyl 3,°,x / 100,%01.2f,0x200c,2,TRUE,0,-5,-5,1,0,TRUE,,y 29 | Knock Cyl 4,°,x / 100,%01.2f,0x200d,2,TRUE,0,-5,-5,1,0,TRUE,,z 30 | LPFP DC,%,x / 100,%01.1f,0x2028,2,FALSE,0,100,-1000,100,0,TRUE,, 31 | LTFT,%,x / 1.28 - 100,%01.1f,0xf407,1,FALSE,-25,25,-25,25,0,TRUE,Default, 32 | MAP,kPa,x / 10,%01.1f,0x39c0,2,FALSE,0,320,-1,350,0,TRUE,,m 33 | MAP SP,kPa,x / 10,%01.1f,0x39c1,2,FALSE,0,320,-1,350,0,TRUE,, 34 | Misfires,,x,%01.0f,0x2904,2,FALSE,0,10,-1000,50,0,TRUE,, 35 | Oil Temp,°F,x * 0.18 - 459.652,%01.0f,0x202f,2,FALSE,0,280,-1000,1000,0,TRUE,Default, 36 | Pedal Pos,%,x / 10.24,%01.1f,0x1070,2,FALSE,0,100,-1000,1000,0,TRUE,, 37 | Port Flap Pos,,x,%01.0f,0x295c,1,FALSE,0,1,-1000,1000,0,TRUE,, 38 | Press Ratio,,p / a,%01.2f,0xffff,1,FALSE,0,4,-1,10,0,TRUE,, 39 | PUT,kPa,x / 10,%01.1f,0x202a,2,FALSE,0,320,-1,350,0,TRUE,,p 40 | PUT SP,kPa,x / 10,%01.1f,0x2029,2,FALSE,0,320,-1,350,0,TRUE,, 41 | STFT,%,x / 1.28 - 100,%01.1f,0xf406,1,FALSE,-25,25,-25,25,0,TRUE,, 42 | Torque,lbft,x / 7.37562,%01.1f,0x437c,2,TRUE,0,450,-1000,1000,0,TRUE,, 43 | Torque Req,lbft,x / 7.37562,%01.1f,0x4380,2,TRUE,0,450,-1000,1000,0,TRUE,, 44 | TPS,%,x / 10,%01.1f,0x20ba,2,TRUE,0,100,-1000,1000,0,TRUE,, 45 | Turbo Speed,krpm,x / 163.8400000001536,%01.0f,0x1040,2,FALSE,0,220,-100,300,0,TRUE,, 46 | Valve Lift Pos,,x,%01.0f,0x3d6c,1,FALSE,0,1,-1000,1000,0,TRUE,, 47 | Vehicle Speed,mph,x / 160.934,%01.1f,0x2033,2,FALSE,0,150,-1000,220,0,TRUE,, 48 | Wastegate,%,100 - x / 100,%01.1f,0x39a2,2,FALSE,0,100,-1000,1000,0,TRUE,, 49 | Cruise,,x,%01.0f,0x203c,2,FALSE,0,10,-1000,1000,0,TRUE,, -------------------------------------------------------------------------------- /PID/PIDList3E-USA.csv: -------------------------------------------------------------------------------- 1 | Name,Unit,Equation,Format,Address,Length,Signed,ProgMin,ProgMax,WarnMin,WarnMax,Smoothing,Enabled,Tabs,Assign To 2 | AFR,AFR,x / 2229.1156462585,%01.1f,0xd00120e2,2,FALSE,11.025,18.375,-1,5000,0,TRUE,Default, 3 | AFR SP,AFR,x / 69.6598639455782,%01.1f,0xd00143f6,2,FALSE,11.025,18.375,-1,5000,0,TRUE,, 4 | Airmass,mg/stk,x * 1000000,%01.0f,0xd00097b4,4,FALSE,0,2000,-100,50000,0,TRUE,, 5 | Airmass SP,mg/stk,x * 1000000,%01.0f,0xd00097fc,4,FALSE,0,2000,-100,50000,0,TRUE,, 6 | Ambient Press,kPa,x / 120.6017666543982,%01.1f,0xd0013c76,2,FALSE,0,105,0,120,0,TRUE,,a 7 | Ambient Temp,°F,x * 1.35 - 54.4,%01.0f,0xd000c177,1,FALSE,0,120,-100,200,0,TRUE,, 8 | Battery Volts,V,x / 51.2,%01.1f,0xd0015172,2,TRUE,10,15,7,16,0,TRUE,, 9 | Boost,psi,(m - a) * 0.145077720207254,%01.1f,0xffffffff,1,FALSE,-14.7,35,-100,100,0,TRUE,Default, 10 | Comb Mode,,x,%01.0f,0xd000c36e,1,FALSE,0,26,-100,100,0,TRUE,, 11 | Coolant Temp,°F,x * 1.35 - 54.4,%01.0f,0xd000c6f5,1,FALSE,0,250,-100,300,0,TRUE,Default, 12 | Current Gear,,x,%01.0f,0xd000f39a,1,FALSE,0,6,-1,7,0,TRUE,, 13 | DV Position,%,x / 655.3599999999997,%01.1f,0xd0011db2,2,FALSE,0,100,-10,500,0,TRUE,, 14 | Engine Speed,rpm,x,%01.0f,0xd0012400,2,FALSE,0,7000,-1,10000,0,TRUE,, 15 | EOI Actual,°,x / 2.66666666666667,%01.0f,0xd0013982,2,FALSE,0,720,-1000,1000,0,TRUE,, 16 | EOI Limit,°,x / 2.66666666666667,%01.0f,0xd001397a,2,FALSE,0,720,-1000,1000,0,TRUE,, 17 | Eth Content,%,x / 2.55,%01.1f,0xd000c1d4,1,FALSE,0,100,-100,100,0,TRUE,Default, 18 | Exhaust Cam,°,x / 128,%01.1f,0xd001566e,2,TRUE,-45,45,-100,100,0,TRUE,, 19 | Ext Flow Fac,,x / 16384,%01.2f,0xd0011e04,2,FALSE,0,2,-1,10,0,TRUE,, 20 | Ext Press Des,kPa,x / 120.6017666543982,%01.0f,0xd0011eba,2,FALSE,0,500,-1000,10000,0,TRUE,, 21 | FP DI,psi,x / 12.9925036977825,%01.0f,0xd00136ac,2,FALSE,0,3500,-1,5000,0,TRUE,, 22 | FP DI SP,psi,x / 12.9925036977825,%01.0f,0xd0013640,2,FALSE,0,3500,-1,5000,0,TRUE,, 23 | FP MPI,psi,x / 25.985007395565,%01.1f,0xd0011b26,2,FALSE,0,150,-1,200,0,TRUE,, 24 | FP MPI SP,psi,x / 25.985007395565,%01.1f,0xd001360c,2,FALSE,0,150,-1,200,0,TRUE,, 25 | Fuel Flow,mg/stk,x / 47.18142548596112,%01.1f,0xd0013636,2,FALSE,0,200,-100,1000,0,TRUE,, 26 | Fuel Flow SP,mg/stk,x / 47.18142548596112,%01.1f,0xd00135e0,2,FALSE,0,200,-100,1000,0,TRUE,, 27 | Fuel Split MPI,,x / 128,%01.2f,0xd00192b1,1,FALSE,0,1,-100,100,0,TRUE,, 28 | HPFP Eff Vol,%,x / 655.3599999999997,%01.1f,0xd001363c,2,FALSE,0,100,-1000,1000,0,TRUE,, 29 | IAT,°F,x * 1.35 - 54.4,%01.0f,0xd000c179,1,FALSE,0,200,-100,500,0,TRUE,Default, 30 | Ign Table Value,°,(x - 95) / 2.666666666666667,%01.1f,0xd000e57e,1,FALSE,-10,40,-100,100,0,TRUE,, 31 | Ign Timing Avg,°,(x - 95) / 2.666666666666667,%01.1f,0xd000e59c,1,FALSE,-10,40,-100,100,0,TRUE,, 32 | Inj PW DI,ms,x / 250,%01.1f,0xd0013b16,2,FALSE,0,20,-1000,1000,0,TRUE,, 33 | Inj PW MPI,ms,x / 250,%01.1f,0xd0013824,2,FALSE,0,20,-1000,1000,0,TRUE,, 34 | Int Flow Fac,,x / 16384,%01.2f,0xd0011e08,2,FALSE,0,2,-1000,1000,0,TRUE,, 35 | Intake Cam,°,x / 128,%01.1f,0xd001566c,2,TRUE,-45,45,-100,100,0,TRUE,, 36 | Knock Avg,°,(x - 128) / 2.66666666666667,%01.2f,0xd001988e,1,FALSE,0,-5,-3,1,0,TRUE,Default, 37 | Knock Cyl 1,°,(x - 128) / 2.66666666666667,%01.2f,0xd000efb1,1,FALSE,0,-5,-5,1,0,TRUE,, 38 | Knock Cyl 2,°,(x - 128) / 2.66666666666667,%01.2f,0xd000efb2,1,FALSE,0,-5,-5,1,0,TRUE,, 39 | Knock Cyl 3,°,(x - 128) / 2.66666666666667,%01.2f,0xd000efb3,1,FALSE,0,-5,-5,1,0,TRUE,, 40 | Knock Cyl 4,°,(x - 128) / 2.66666666666667,%01.2f,0xd000efb4,1,FALSE,0,-5,-5,1,0,TRUE,, 41 | LPFP DC,%,x / 655.3599999999997,%01.1f,0xd0013600,2,FALSE,0,100,-1000,100,0,TRUE,, 42 | LTFT,%,x / 1.28 - 100,%01.1f,0xd000f00b,1,FALSE,-25,25,-25,25,0,TRUE,Default, 43 | MAP,kPa,x / 1000,%01.1f,0xd00098cc,4,FALSE,0,320,-1,350,0,TRUE,,m 44 | MAP SP,kPa,x / 1000,%01.1f,0xd00098f4,4,FALSE,0,320,-1,350,0,TRUE,, 45 | OF Ign Cor,°,x / 2.66666666666667,%01.1f,0xd000e578,1,TRUE,0,20,-1000,1000,0,TRUE,, 46 | OF Ign Fac,,x / 128,%01.2f,0xd001de8e,1,FALSE,0,1,-1000,1000,0,TRUE,, 47 | OF Ign Max,°,x / 2.66666666666667,%01.1f,0xd001de8d,1,TRUE,0,20,-1000,1000,0,TRUE,, 48 | OF Tq Mult,,x / 32768,%01.2f,0xd0017f52,2,FALSE,0,2,-1000,1000,0,TRUE,, 49 | Oil Temp,°F,x * 1.8 - 40,%01.0f,0xd000c5ae,1,FALSE,0,280,-1000,1000,0,TRUE,Default, 50 | Pedal Pos,%,x / 10.24,%01.1f,0xd0012028,2,FALSE,0,100,-1000,1000,0,TRUE,, 51 | Port Flap Pos,,x,%01.0f,0xd0000aa1,1,FALSE,0,1,-1000,1000,0,TRUE,, 52 | Press Ratio,,p / a,%01.2f,0xffffffff,1,FALSE,0,4,-1,10,0,TRUE,, 53 | PUT,kPa,x / 1000,%01.1f,0xd00098fc,4,FALSE,0,320,-1,350,0,TRUE,,p 54 | PUT SP,kPa,x / 120.60176665,%01.1f,0xd0011eee,2,FALSE,0,320,-1,350,0,TRUE,, 55 | SOI Actual,°,x / 2.66666666666667,%01.0f,0xd0013a44,2,FALSE,0,720,-1000,1000,0,TRUE,, 56 | SOI Limit,°,x / 2.66666666666667,%01.0f,0xd0013a42,2,FALSE,0,720,-1000,1000,0,TRUE,, 57 | Steering Angle,°,x / 22.85714285714286,%01.0f,0xd001521a,2,TRUE,-720,720,-2000,2000,0,TRUE,, 58 | STFT,%,x / 1.28 - 100.0,%01.1f,0xd000f00c,1,FALSE,-25,25,-25,25,0,TRUE,, 59 | Torque,lbft,x / 43.38624,%01.1f,0xd0015344,2,TRUE,0,450,-1000,1000,0,TRUE,, 60 | Torque Req,lbft,x / 43.38624,%01.1f,0xd0012048,2,TRUE,0,450,-1000,1000,0,TRUE,, 61 | Torque Lim,,x,%01.0f,0xd0011f0c,2,FALSE,0,28640,-1000,65535,0,TRUE,, 62 | TPS,%,x / 2.142128661087866,%01.1f,0xd000f377,1,FALSE,0,100,-1000,1000,0,TRUE,, 63 | Trans Temp,°F,x * 1.8 - 40,%01.0f,0xd000f3c1,1,FALSE,0,250,-1000,150,0,TRUE,, 64 | Turbo Speed,krpm,x / 163.8400000001536,%01.0f,0xd0011e76,2,FALSE,0,220,-100,300,0,TRUE,, 65 | Valve Lift Pos,,x,%01.0f,0xd0019b75,1,FALSE,0,1,-1000,1000,0,TRUE,, 66 | Vehicle Speed,mph,x / 160.934,%01.1f,0xd00155b6,2,FALSE,0,150,-1000,220,0,TRUE,, 67 | WG Flow Des,kg/hr,x / 32,%01.0f,0xd0015c5e,2,FALSE,0,1024,-1000,10000,0,TRUE,, 68 | WG Pos Base,%,x / 655.3599999999997,%01.1f,0xd0015c2c,2,FALSE,0,100,-1000,1000,0,TRUE,, 69 | WG Pos Final,%,x / 655.3599999999997,%01.1f,0xd0011e10,2,FALSE,0,100,-1000,1000,0,TRUE,, 70 | WG I Value,%,x / 327.68,%01.1f,0xd0015c26,2,TRUE,-100,100,-1000,1000,0,TRUE,, 71 | WG P-D Value,%,x / 327.68,%01.1f,0xd0015c2e,2,TRUE,-100,100,-1000,1000,0,TRUE,, 72 | Accel Lat,g,(x - 127) / 98.1,%01.2f,0xd000ee2a,1,FALSE,-20,20,-1000,1000,0,TRUE,, 73 | Accel Long,g,(x - 512) / 313.92,%01.2f,0xd00141ba,2,FALSE,-20,20,-1000,1000,0,TRUE,, 74 | Cruise,,x,%01.0f,0xd001b6cd,1,FALSE,0,10,-1000,1000,0,TRUE,, -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simos Tools 2 | 3 | This project has moved and all new builds are now available at:
4 | https://play.google.com/store/apps/details?id=com.app.simostools 5 | 6 | This requires the Macchina-A0 BLEISOTP bridge firmware originally developed by bri3d to log Simos ECUs: 7 | https://github.com/Switchleg1/esp32-isotp-ble-bridge/tree/BridgeLEG 8 | 9 | Simple example of logging capability:
10 | https://datazap.me/u/switchleg/log-1632161044?log=0&data=2-3
11 | https://datazap.me/u/switchleg/log-1632680629?log=0&data=2-3
12 | 13 | Imperial PID Files:
14 | https://github.com/Switchleg1/SimosTools/blob/master/PID/PIDList22-USA.csv
15 | https://github.com/Switchleg1/SimosTools/blob/master/PID/PIDList3E-USA.csv
16 | 17 |

18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 |

26 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdk 31 8 | 9 | defaultConfig { 10 | applicationId "com.app.simostools" 11 | minSdk 28 12 | targetSdk 31 13 | versionCode 16 14 | versionName "0.16" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_11 27 | targetCompatibility JavaVersion.VERSION_11 28 | } 29 | kotlinOptions { 30 | jvmTarget = '11' 31 | } 32 | 33 | buildFeatures{ 34 | viewBinding true 35 | } 36 | } 37 | 38 | dependencies { 39 | implementation 'androidx.core:core-ktx:1.7.0' 40 | implementation 'androidx.appcompat:appcompat:1.3.1' 41 | implementation 'com.google.android.material:material:1.4.0' 42 | implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' 43 | implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' 44 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 45 | implementation "androidx.recyclerview:recyclerview:1.2.1" 46 | testImplementation 'junit:junit:4.13.2' 47 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 48 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 49 | } -------------------------------------------------------------------------------- /app/debug/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/debug/app-debug.apk -------------------------------------------------------------------------------- /app/debug/output-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "com.app.simostools", 8 | "variantName": "debug", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "attributes": [], 14 | "versionCode": 9, 15 | "versionName": "0.09", 16 | "outputFile": "app-debug.apk" 17 | } 18 | ], 19 | "elementType": "File" 20 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/release/app-release.aab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/release/app-release.aab -------------------------------------------------------------------------------- /app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "com.app.simostools", 8 | "variantName": "release", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "attributes": [], 14 | "versionCode": 16, 15 | "versionName": "0.16", 16 | "outputFile": "app-release.apk" 17 | } 18 | ], 19 | "elementType": "File" 20 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/ConfigFile.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import java.io.File 5 | import java.io.FileInputStream 6 | import java.io.FileOutputStream 7 | import java.lang.Long.parseLong 8 | import java.util.* 9 | import java.util.TreeSet 10 | import java.util.Collections 11 | import java.util.Enumeration 12 | 13 | class SProperties: Properties() { 14 | @Synchronized 15 | override fun keys(): Enumeration? { 16 | return Collections.enumeration(TreeSet(super.keys)) 17 | } 18 | } 19 | 20 | object ConfigFile { 21 | private val TAG = "Config" 22 | private val mProperties = SProperties() 23 | 24 | fun write(fileName: String?, context: Context?) { 25 | DebugLog.i(TAG, "Writing config file.") 26 | try { 27 | 28 | val path = context?.getExternalFilesDir("") 29 | val propertiesFile = File(path, "/$fileName") 30 | if (!propertiesFile.exists()) { 31 | propertiesFile.createNewFile() 32 | } 33 | 34 | val propertiesOutputStream = FileOutputStream(propertiesFile) 35 | mProperties.store(propertiesOutputStream, "save to properties file") 36 | propertiesOutputStream.close() 37 | DebugLog.i(TAG, "successful.") 38 | } catch(e: Exception) { 39 | DebugLog.e(TAG, "unable to write config file.", e) 40 | DebugLog.i(TAG, "failed.") 41 | } 42 | } 43 | 44 | fun read(fileName: String?, context: Context?) { 45 | DebugLog.i(TAG, "Reading config file.") 46 | 47 | try { 48 | val path = context?.getExternalFilesDir("") 49 | val propertiesFile = File(path, "/$fileName") 50 | if (!propertiesFile.exists()) { 51 | propertiesFile.createNewFile() 52 | writeDefaultConfig(fileName, context) 53 | } 54 | 55 | val inputStream = FileInputStream(propertiesFile) 56 | mProperties.load(inputStream) 57 | 58 | mProperties.forEach { (k, v) -> 59 | processKey(k.toString(), v.toString()) 60 | } 61 | inputStream.close() 62 | DebugLog.i(TAG, "successful.") 63 | } catch(e: Exception) { 64 | DebugLog.e(TAG, "unable to read config file.", e) 65 | DebugLog.i(TAG, "failed.") 66 | } 67 | } 68 | 69 | fun set(key: String, value: String) { 70 | mProperties[key] = value 71 | } 72 | 73 | fun get(key: String): String { 74 | return mProperties[key].toString() 75 | } 76 | 77 | private fun processKey(key: String, value: String) { 78 | DebugLog.d(TAG, "Found $key=$value") 79 | 80 | try { 81 | when(val subKey = key.substringBefore(".")) { 82 | UDSLoggingMode.values()[0].key -> { 83 | val mode = UDSLoggingMode.values().find {it.cfgName == value} 84 | mode?.let { 85 | UDSLogger.setMode(it) 86 | } 87 | } 88 | GearRatios.values()[0].key -> { 89 | val f = value.toFloat() 90 | val gearString = key.substringAfter(".") 91 | val gear = GearRatios.values().find {it.gear == gearString} 92 | gear?.let { 93 | it.ratio = f 94 | } 95 | } 96 | ColorList.values()[0].key -> { 97 | val name = key.substringAfter(".") 98 | val l = parseLong(value, 16) 99 | val color = ColorList.values().find {it.cfgName == name} 100 | color?.let { 101 | it.value = l.toColorInt() 102 | } 103 | } 104 | else -> { 105 | if(subKey == ConfigSettings.DEBUG_LOG.cfgName) { 106 | DebugLog.setFlags(value.toInt()) 107 | } else { 108 | val cfg = ConfigSettings.values().find { it.cfgName == subKey } 109 | cfg?.set(value) 110 | } 111 | } 112 | } 113 | } catch (e: Exception) { 114 | DebugLog.e(TAG, "Exception parsing $key=$value: ", e) 115 | } 116 | } 117 | 118 | private fun writeDefaultConfig(filename: String?, context: Context?) { 119 | DebugLog.i(TAG, "Writing default config file.") 120 | 121 | mProperties[UDSLoggingMode.values()[0].key] = UDSLoggingMode.MODE_22.cfgName 122 | GearRatios.values().forEach { 123 | mProperties["${it.key}.${it.gear}"] = it.ratio.toString() 124 | } 125 | ColorList.values().forEach { 126 | mProperties["${it.key}.${it.cfgName}"] = it.value.toColorHex() 127 | } 128 | ConfigSettings.values().forEach { 129 | mProperties[it.cfgName] = it.toString() 130 | } 131 | 132 | write(filename, context) 133 | } 134 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/DebugLog.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import android.util.Log 5 | import java.io.* 6 | import java.lang.Exception 7 | import java.time.Instant 8 | import java.time.ZoneOffset 9 | import java.time.format.DateTimeFormatter 10 | 11 | object DebugLog { 12 | private val TAG = "DebugLog" 13 | private var mBufferedWriter: BufferedWriter? = null 14 | private var mFlags: Int = ConfigSettings.DEBUG_LOG.toInt() 15 | 16 | fun setFlags(flags: Int) { 17 | if(flags in 0 .. 32) { 18 | mFlags = flags 19 | d(TAG,"Set debug flags to: $flags") 20 | } 21 | } 22 | 23 | fun getFlags(): Int { 24 | return mFlags 25 | } 26 | 27 | fun create(fileName: String?, context: Context?) { 28 | context?.let { 29 | close() 30 | 31 | try { 32 | val path = it.getExternalFilesDir("") 33 | val logFile = File(path, "/$fileName") 34 | if (!logFile.exists()) { 35 | logFile.createNewFile() 36 | } 37 | mBufferedWriter = BufferedWriter(FileWriter(logFile, true)) 38 | i(TAG, "Log open.") 39 | } catch(e: Exception) { 40 | Log.e(TAG, "Error opening debug log", e) 41 | } 42 | } 43 | } 44 | 45 | fun close() { 46 | try { 47 | i(TAG, "Closing log.") 48 | mBufferedWriter?.close() 49 | mBufferedWriter = null 50 | } catch (e: Exception) { 51 | Log.e(TAG, "File already closed", e) 52 | } 53 | } 54 | 55 | fun i(tag: String, text: String) { 56 | Log.i(tag, text) 57 | 58 | if((mFlags and DEBUG_LOG_INFO) == 0) 59 | return 60 | 61 | add("${timeStamp()} [I] $tag: $text") 62 | newLine() 63 | } 64 | 65 | fun w(tag: String, text: String) { 66 | Log.w(tag, text) 67 | 68 | if((mFlags and DEBUG_LOG_WARNING) == 0) 69 | return 70 | 71 | add("${timeStamp()} [W] $tag: $text") 72 | newLine() 73 | } 74 | 75 | fun d(tag: String, text: String) { 76 | Log.d(tag, text) 77 | 78 | if((mFlags and DEBUG_LOG_DEBUG) == 0) 79 | return 80 | 81 | add("${timeStamp()} [D] $tag: $text") 82 | newLine() 83 | } 84 | 85 | fun e(tag: String, text: String, e: Exception) { 86 | Log.e(tag, text, e) 87 | 88 | if((mFlags and DEBUG_LOG_EXCEPTION) == 0) 89 | return 90 | 91 | add("${timeStamp()} [E] $tag: $text") 92 | newLine() 93 | } 94 | 95 | fun c(tag: String, buff: ByteArray?, from: Boolean) { 96 | buff?.let { 97 | if ((mFlags and DEBUG_LOG_COMMUNICATIONS) == 0) 98 | return 99 | 100 | val dirString = if (from) "${it.count()} ->" 101 | else "${it.count()} <-" 102 | 103 | add("${timeStamp()} [C] $tag: [$dirString] ${it.toHex()}") 104 | newLine() 105 | } 106 | } 107 | 108 | private fun newLine() { 109 | try { 110 | mBufferedWriter?.let { 111 | it.newLine() 112 | it.flush() 113 | } 114 | } catch (e: Exception) { 115 | Log.e(TAG, "Error starting new debug line", e) 116 | } 117 | } 118 | 119 | private fun add(text: String) { 120 | if(mFlags == DEBUG_LOG_NONE) 121 | return 122 | 123 | try { 124 | mBufferedWriter?.append(text) 125 | } catch (e: Exception) { 126 | Log.e(TAG, "Error appending debug log", e) 127 | } 128 | } 129 | 130 | private fun timeStamp(): String { 131 | return DateTimeFormatter 132 | .ofPattern("yyyy-MM-dd HH:mm:ss.SSS") 133 | .withZone(ZoneOffset.systemDefault()) 134 | .format(Instant.now()) 135 | } 136 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/ExpressionParsing.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import kotlin.math.* 4 | 5 | fun eval(str: String): Float { 6 | return object : Any() { 7 | var pos = -1 8 | var ch = 0 9 | 10 | fun nextChar() { 11 | ch = if (++pos < str.length) str[pos].code 12 | else -1 13 | } 14 | 15 | fun eat(charToEat: Int): Boolean { 16 | while (ch == ' '.code) 17 | nextChar() 18 | 19 | if (ch == charToEat) { 20 | nextChar() 21 | return true 22 | } 23 | return false 24 | } 25 | 26 | fun parse(): Float { 27 | nextChar() 28 | val x = parseExpression() 29 | if (pos < str.length) 30 | throw RuntimeException("Unexpected: " + ch.toChar()) 31 | 32 | return x 33 | } 34 | 35 | // Grammar: 36 | // expression = term | expression `+` term | expression `-` term 37 | // term = factor | term `*` factor | term `/` factor 38 | // factor = `+` factor | `-` factor | `(` expression `)` 39 | // | number | functionName factor | factor `^` factor 40 | fun parseExpression(): Float { 41 | var x = parseTerm() 42 | while (true) { 43 | when { 44 | eat('+'.code) -> x += parseTerm() // addition 45 | eat('-'.code) -> x -= parseTerm() // subtraction 46 | else -> return x 47 | } 48 | } 49 | } 50 | 51 | fun parseTerm(): Float { 52 | var x = parseFactor() 53 | while (true) { 54 | when { 55 | eat('*'.code) -> x *= parseFactor() // multiplication 56 | eat('/'.code) -> x /= parseFactor() // division 57 | else -> return x 58 | } 59 | } 60 | } 61 | 62 | fun parseFactor(): Float { 63 | if (eat('+'.code)) 64 | return parseFactor() // unary plus 65 | if (eat('-'.code)) 66 | return -parseFactor() // unary minus 67 | var x: Float 68 | val startPos = pos 69 | if (eat('('.code)) { // parentheses 70 | x = parseExpression() 71 | eat(')'.code) 72 | } else if (ch >= '0'.code && ch <= '9'.code || ch == '.'.code) { // numbers 73 | while (ch >= '0'.code && ch <= '9'.code || ch == '.'.code) 74 | nextChar() 75 | x = str.substring(startPos, pos).toFloat() 76 | } else if (ch >= 'a'.code && ch <= 'z'.code) { // functions 77 | while (ch >= 'a'.code && ch <= 'z'.code) 78 | nextChar() 79 | val func = str.substring(startPos, pos) 80 | x = parseFactor() 81 | x = when (func) { 82 | "sqrt" -> sqrt(x) 83 | "sin" -> sin(Math.toRadians(x.toDouble())).toFloat() 84 | "cos" -> cos(Math.toRadians(x.toDouble())).toFloat() 85 | "tan" -> tan(Math.toRadians(x.toDouble())).toFloat() 86 | else -> throw RuntimeException("Unknown function: $func") 87 | } 88 | } else { 89 | throw RuntimeException("Unexpected: " + ch.toChar()) 90 | } 91 | if (eat('^'.code)) 92 | x = x.pow(parseFactor()) // exponentiation 93 | 94 | if(eat('E'.code)) { 95 | x *= 10f.pow(parseFactor()) // scientific notation 96 | } 97 | 98 | return x 99 | } 100 | }.parse() 101 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/LogFile.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import android.provider.MediaStore 5 | import android.content.ContentValues 6 | import android.content.pm.PackageManager 7 | import android.net.Uri 8 | import android.os.Build 9 | import android.os.Environment 10 | import java.io.* 11 | 12 | object LogFile { 13 | private val TAG = "LogFile" 14 | private var mOutputStream: OutputStream? = null 15 | private var mLastFile: File? = null 16 | private var mLastUri: Uri? = null 17 | 18 | fun create(fileName: String, subFolder: String, context: Context?) { 19 | context?.let { 20 | close() 21 | 22 | if (ConfigSettings.OUT_DIRECTORY.toDirectory() == DirectoryList.APP || RequiredPermissions.READ_STORAGE.result == PackageManager.PERMISSION_DENIED) { 23 | val path = context.getExternalFilesDir(subFolder) 24 | path?.let { 25 | if (!path.exists()) 26 | path.mkdir() 27 | 28 | val logFile = File(path, "/$fileName") 29 | if (!logFile.exists()) { 30 | logFile.createNewFile() 31 | } 32 | 33 | mOutputStream = FileOutputStream(logFile) 34 | mLastFile = logFile 35 | mLastUri = null 36 | } ?: DebugLog.w(TAG, "Unable to open file for logging: $subFolder/$fileName") 37 | } else { 38 | //get file directory 39 | var fileNameDir = ConfigSettings.OUT_DIRECTORY.toDirectory().location 40 | if (subFolder != "") 41 | fileNameDir += "/$subFolder" 42 | 43 | //try to open the file 44 | try { 45 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { 46 | val dirName = ConfigSettings.OUT_DIRECTORY.toDirectory().location 47 | val path = File(Environment.getExternalStoragePublicDirectory(dirName), "/$subFolder") 48 | if (!path.exists()) 49 | path.mkdir() 50 | 51 | val logFile = File(path, "/$fileName") 52 | if (!logFile.exists()) { 53 | logFile.createNewFile() 54 | } 55 | 56 | mOutputStream = FileOutputStream(logFile) 57 | mLastFile = logFile 58 | mLastUri = null 59 | } else { 60 | val contentValues = ContentValues() 61 | contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) 62 | contentValues.put( 63 | MediaStore.MediaColumns.MIME_TYPE, 64 | "application/my-custom-type" 65 | ) 66 | contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, fileNameDir) 67 | val resolver = context.contentResolver 68 | val uri = resolver.insert( 69 | MediaStore.Files.getContentUri("external"), 70 | contentValues 71 | ) 72 | 73 | mOutputStream = resolver.openOutputStream(uri!!) 74 | mLastFile = null 75 | mLastUri = uri 76 | } 77 | DebugLog.i(TAG, "Log opened: $fileNameDir/$fileName") 78 | } catch (e: Exception) { 79 | DebugLog.w(TAG, "Unable to open file for logging: $fileNameDir/$fileName") 80 | } 81 | } 82 | } ?: DebugLog.w(TAG, "Unable to open file for logging, invalid context") 83 | } 84 | 85 | fun close() { 86 | if(mOutputStream != null) { 87 | DebugLog.i(TAG, "Log closed.") 88 | mOutputStream!!.close() 89 | mOutputStream = null 90 | } 91 | } 92 | 93 | fun add(text: String) { 94 | mOutputStream?.write(text.toByteArray()) 95 | } 96 | 97 | fun addLine(text: String) { 98 | add(text + "\n") 99 | } 100 | 101 | fun getLastFile(): File? { 102 | return mLastFile 103 | } 104 | 105 | fun getLastUri(): Uri? { 106 | return mLastUri 107 | } 108 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/LogViewerEnabledFragment.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.graphics.Color 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.LinearLayout 9 | import androidx.fragment.app.Fragment 10 | import androidx.lifecycle.ViewModel 11 | import androidx.lifecycle.ViewModelProvider 12 | import androidx.navigation.fragment.findNavController 13 | 14 | class LogViewerEnabledViewModel : ViewModel() { 15 | } 16 | 17 | class LogViewerEnabledFragment: Fragment() { 18 | private var TAG = "LogViewerEnabledFragment" 19 | private var mEnableList:Array? = null 20 | private lateinit var mViewModel: LogViewerEnabledViewModel 21 | 22 | override fun onDestroy() { 23 | super.onDestroy() 24 | 25 | mEnableList = null 26 | 27 | DebugLog.d(TAG, "onDestroy") 28 | } 29 | 30 | override fun onCreateView( 31 | inflater: LayoutInflater, container: ViewGroup?, 32 | savedInstanceState: Bundle? 33 | ): View? { 34 | 35 | return inflater.inflate(R.layout.fragment_log_viewer_enabled, container, false) 36 | } 37 | 38 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 39 | super.onViewCreated(view, savedInstanceState) 40 | 41 | mViewModel = ViewModelProvider(this).get(LogViewerEnabledViewModel::class.java) 42 | 43 | val setButton = view.findViewById(R.id.buttonOk) 44 | setButton.apply { 45 | paintBG.color = ColorList.BT_BG.value 46 | paintRim.color = ColorList.BT_RIM.value 47 | setTextColor(ColorList.BT_TEXT.value) 48 | setOnClickListener { 49 | gLogViewerData?.let { logViewerData -> 50 | mEnableList?.let { enableList -> 51 | logViewerData.forEachIndexed() { i, pid -> 52 | pid?.enabled = enableList[i]?.isChecked ?: false 53 | } 54 | } 55 | } 56 | findNavController().navigateUp() 57 | } 58 | } 59 | 60 | val backButton = view.findViewById(R.id.buttonBack) 61 | backButton.apply { 62 | paintBG.color = ColorList.BT_BG.value 63 | paintRim.color = ColorList.BT_RIM.value 64 | setTextColor(ColorList.BT_TEXT.value) 65 | setOnClickListener { 66 | findNavController().navigateUp() 67 | } 68 | } 69 | 70 | gLogViewerData?.let { 71 | mEnableList = arrayOfNulls(it.count()) 72 | mEnableList?.let { enableList -> 73 | val lLayout = view.findViewById(R.id.logviewerLayoutScroll) 74 | it.forEachIndexed() { i, pid -> 75 | val pidLayout = androidx.appcompat.widget.SwitchCompat(requireContext()) 76 | pidLayout.text = pid?.name 77 | pidLayout.setTextColor(ColorList.TEXT.value) 78 | pidLayout.textSize = 24f 79 | pidLayout.isChecked = pid?.enabled ?: false 80 | pidLayout.setTextColor(pid?.color?: Color.WHITE) 81 | enableList[i] = pidLayout 82 | lLayout.addView(pidLayout) 83 | } 84 | } 85 | } 86 | 87 | DebugLog.d(TAG, "onViewCreated") 88 | } 89 | 90 | override fun onDestroyView() { 91 | super.onDestroyView() 92 | 93 | DebugLog.d(TAG, "onDestroyView") 94 | } 95 | 96 | override fun onResume() { 97 | super.onResume() 98 | 99 | //Set background color 100 | view?.setBackgroundColor(ColorList.BG_NORMAL.value) 101 | 102 | DebugLog.d(TAG, "onResume") 103 | } 104 | 105 | override fun onPause() { 106 | super.onPause() 107 | 108 | DebugLog.d(TAG, "onPause") 109 | } 110 | 111 | override fun onStart() { 112 | super.onStart() 113 | 114 | DebugLog.d(TAG, "onStart") 115 | } 116 | 117 | override fun onStop() { 118 | super.onStop() 119 | 120 | DebugLog.d(TAG, "onStop") 121 | } 122 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/LogViewerTabsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.graphics.Color 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.LinearLayout 9 | import androidx.fragment.app.Fragment 10 | import androidx.lifecycle.ViewModel 11 | import androidx.lifecycle.ViewModelProvider 12 | import androidx.navigation.fragment.findNavController 13 | 14 | class LogViewerTabsViewModel : ViewModel() { 15 | } 16 | 17 | class LogViewerTabsFragment: Fragment() { 18 | private var TAG = "LogViewerLayoutFragment" 19 | private var mTabsList:Array? = null 20 | private lateinit var mViewModel: LogViewerTabsViewModel 21 | 22 | override fun onDestroy() { 23 | super.onDestroy() 24 | 25 | mTabsList = null 26 | 27 | DebugLog.d(TAG, "onDestroy") 28 | } 29 | 30 | override fun onCreateView( 31 | inflater: LayoutInflater, container: ViewGroup?, 32 | savedInstanceState: Bundle? 33 | ): View? { 34 | 35 | return inflater.inflate(R.layout.fragment_log_viewer_tabs, container, false) 36 | } 37 | 38 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 39 | super.onViewCreated(view, savedInstanceState) 40 | 41 | mViewModel = ViewModelProvider(this).get(LogViewerTabsViewModel::class.java) 42 | 43 | val setButton = view.findViewById(R.id.buttonOk) 44 | setButton.apply { 45 | paintBG.color = ColorList.BT_BG.value 46 | paintRim.color = ColorList.BT_RIM.value 47 | setTextColor(ColorList.BT_TEXT.value) 48 | setOnClickListener { 49 | gLogViewerData?.let { logViewerData -> 50 | mTabsList?.let { tabsList -> 51 | logViewerData.forEachIndexed() { i, pid -> 52 | pid?.let { 53 | pid.enabled = false 54 | tabsList.forEachIndexed() { l, layout -> 55 | layout?.let { 56 | if (layout.isChecked && pid.tabs.contains(layout.text)) 57 | pid.enabled = true 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } 64 | findNavController().navigateUp() 65 | } 66 | } 67 | 68 | val backButton = view.findViewById(R.id.buttonBack) 69 | backButton.apply { 70 | paintBG.color = ColorList.BT_BG.value 71 | paintRim.color = ColorList.BT_RIM.value 72 | setTextColor(ColorList.BT_TEXT.value) 73 | setOnClickListener { 74 | findNavController().navigateUp() 75 | } 76 | } 77 | 78 | gLogViewerData?.let { logViewerData -> 79 | val lLayout = view.findViewById(R.id.logviewerLayoutScroll) 80 | var tabStrings:Array = arrayOf() 81 | tabStrings += "Default" 82 | logViewerData.forEachIndexed() { i, pid -> 83 | pid?.tabs?.split(".")?.forEach { tab -> 84 | val actualTab = tab.substringBefore("|") 85 | if (actualTab.isNotEmpty() && tabStrings.find { it == actualTab } == null && actualTab != "DSG") { 86 | DebugLog.d(TAG, "New Tab: $actualTab") 87 | tabStrings += actualTab 88 | } 89 | } 90 | } 91 | tabStrings += "DSG" 92 | 93 | mTabsList = arrayOfNulls(tabStrings.count()) 94 | mTabsList?.let { enableList -> 95 | tabStrings.forEachIndexed() { i, tab -> 96 | val pidLayout = androidx.appcompat.widget.SwitchCompat(requireContext()) 97 | pidLayout.text = tab 98 | pidLayout.setTextColor(ColorList.TEXT.value) 99 | pidLayout.textSize = 24f 100 | pidLayout.isChecked = false 101 | pidLayout.setTextColor(Color.WHITE) 102 | enableList[i] = pidLayout 103 | lLayout.addView(pidLayout) 104 | } 105 | } 106 | } 107 | 108 | DebugLog.d(TAG, "onViewCreated") 109 | } 110 | 111 | override fun onDestroyView() { 112 | super.onDestroyView() 113 | 114 | DebugLog.d(TAG, "onDestroyView") 115 | } 116 | 117 | override fun onResume() { 118 | super.onResume() 119 | 120 | //Set background color 121 | view?.setBackgroundColor(ColorList.BG_NORMAL.value) 122 | 123 | DebugLog.d(TAG, "onResume") 124 | } 125 | 126 | override fun onPause() { 127 | super.onPause() 128 | 129 | DebugLog.d(TAG, "onPause") 130 | } 131 | 132 | override fun onStart() { 133 | super.onStart() 134 | 135 | DebugLog.d(TAG, "onStart") 136 | } 137 | 138 | override fun onStop() { 139 | super.onStop() 140 | 141 | DebugLog.d(TAG, "onStop") 142 | } 143 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/LoggingViewPager.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.Fragment 5 | import androidx.viewpager2.adapter.FragmentStateAdapter 6 | 7 | class LoggingViewPagerAdapter(fm: Fragment) : FragmentStateAdapter(fm) { 8 | private var mNameList: Array = arrayOf() 9 | 10 | override fun getItemCount(): Int { 11 | return mNameList.count() 12 | } 13 | 14 | override fun createFragment(position: Int): Fragment { 15 | // Return a NEW fragment instance in createFragment(int) 16 | val fragment = LoggingBaseFragment() 17 | fragment.arguments = Bundle().apply { 18 | // Our object is just an integer :-P 19 | putString(LAYOUT_NAME, mNameList[position]) 20 | } 21 | return fragment 22 | } 23 | 24 | fun getName(position: Int): String { 25 | return mNameList[position] 26 | } 27 | 28 | fun add(name: String) { 29 | mNameList += name 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/MainFragment.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.ImageView 9 | import androidx.core.content.ContextCompat.startForegroundService 10 | import androidx.fragment.app.Fragment 11 | import androidx.navigation.fragment.findNavController 12 | 13 | class MainFragment : Fragment() { 14 | private val TAG = "MainFragment" 15 | 16 | override fun onCreateView( 17 | inflater: LayoutInflater, container: ViewGroup?, 18 | savedInstanceState: Bundle? 19 | ): View? { 20 | // Inflate the layout for this fragment 21 | return inflater.inflate(R.layout.fragment_main, container, false) 22 | } 23 | 24 | override fun onDestroy() { 25 | super.onDestroy() 26 | 27 | DebugLog.d(TAG, "onDestroy") 28 | } 29 | 30 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 31 | super.onViewCreated(view, savedInstanceState) 32 | 33 | val loggingButton = view.findViewById(R.id.buttonMainLogging) 34 | loggingButton.apply { 35 | paintBG.color = ColorList.BT_BG.value 36 | paintRim.color = ColorList.BT_RIM.value 37 | setTextColor(ColorList.BT_TEXT.value) 38 | setOnClickListener { 39 | sendServiceMessage(BTServiceTask.DO_START_LOG.toString()) 40 | findNavController().navigate(R.id.action_MainFragment_to_LoggingFragment) 41 | } 42 | } 43 | 44 | val flashingButton = view.findViewById(R.id.buttonMainFlashing) 45 | flashingButton.apply { 46 | paintBG.color = ColorList.BT_BG.value 47 | paintRim.color = ColorList.BT_RIM.value 48 | setTextColor(ColorList.BT_TEXT.value) 49 | setOnClickListener { 50 | findNavController().navigate(R.id.action_MainFragment_to_FlashingFragment) 51 | } 52 | } 53 | 54 | val logViewerButton = view.findViewById(R.id.buttonLogViewer) 55 | logViewerButton.apply { 56 | paintBG.color = ColorList.BT_BG.value 57 | paintRim.color = ColorList.BT_RIM.value 58 | setTextColor(ColorList.BT_TEXT.value) 59 | setOnClickListener { 60 | gLogViewerLoadLast = false 61 | findNavController().navigate(R.id.action_MainFragment_to_LogViewerFragment) 62 | } 63 | } 64 | 65 | val utilitiesButton = view.findViewById(R.id.buttonMainUtilities) 66 | utilitiesButton.apply { 67 | paintBG.color = ColorList.BT_BG.value 68 | paintRim.color = ColorList.BT_RIM.value 69 | setTextColor(ColorList.BT_TEXT.value) 70 | setOnClickListener { 71 | findNavController().navigate(R.id.action_MainFragment_to_UtilitiesFragment) 72 | } 73 | } 74 | 75 | val settingsButton = view.findViewById(R.id.buttonMainSettings) 76 | settingsButton.apply { 77 | paintBG.color = ColorList.BT_BG.value 78 | paintRim.color = ColorList.BT_RIM.value 79 | setTextColor(ColorList.BT_TEXT.value) 80 | setOnClickListener { 81 | TempPIDS.reset(context) 82 | ColorSettings.resetColors() 83 | findNavController().navigate(R.id.action_MainFragment_to_SettingsFragment) 84 | } 85 | } 86 | 87 | val exitButton = view.findViewById(R.id.buttonMainExit) 88 | exitButton.apply { 89 | paintBG.color = ColorList.BT_BG.value 90 | paintRim.color = ColorList.BT_RIM.value 91 | setTextColor(ColorList.BT_TEXT.value) 92 | setOnClickListener { 93 | //Write pid default files 94 | UDSLoggingMode.values().forEach { mode -> 95 | //write current PID list 96 | PIDCSVFile.write( 97 | getString(R.string.filename_pid_csv, mode.cfgName), 98 | requireActivity(), 99 | PIDs.getList(mode), 100 | true 101 | ) 102 | } 103 | 104 | //write current PID list 105 | PIDCSVFile.write( 106 | getString(R.string.filename_pid_csv, "DSG"), 107 | requireActivity(), 108 | PIDs.getDSGList(), 109 | true 110 | ) 111 | 112 | //clear globals 113 | gLogViewerData = null 114 | gUtilitiesMsgList = emptyArray() 115 | gFlashMsgList = emptyArray() 116 | 117 | //stop timer 118 | (activity as MainActivity).stopGUITimer() 119 | 120 | //Stop our BT Service 121 | sendServiceMessage(BTServiceTask.STOP_SERVICE.toString()) 122 | requireActivity().finish() 123 | } 124 | } 125 | 126 | //Set background color 127 | view.setBackgroundColor(ColorList.BG_NORMAL.value) 128 | view.findViewById(R.id.imageMainLogo).setBackgroundColor(ColorList.BG_NORMAL.value) 129 | 130 | DebugLog.d(TAG, "onViewCreated") 131 | } 132 | 133 | override fun onResume() { 134 | super.onResume() 135 | 136 | if(!ConfigSettings.AUTO_LOG.toBoolean()) 137 | sendServiceMessage(BTServiceTask.DO_STOP_TASK.toString()) 138 | 139 | DebugLog.d(TAG, "onResume") 140 | } 141 | 142 | override fun onPause() { 143 | super.onPause() 144 | 145 | DebugLog.d(TAG, "onPause") 146 | } 147 | 148 | private fun sendServiceMessage(type: String) { 149 | activity?.let { 150 | val serviceIntent = Intent(it, BTService::class.java) 151 | serviceIntent.action = type 152 | startForegroundService(it, serviceIntent) 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/SettingsLoggingFragment.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import android.os.Bundle 5 | import androidx.fragment.app.Fragment 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import androidx.recyclerview.widget.LinearLayoutManager 10 | import androidx.recyclerview.widget.RecyclerView 11 | import androidx.recyclerview.widget.ItemTouchHelper 12 | 13 | object TempPIDS { 14 | var list22: Array? = null 15 | var list3E: Array? = null 16 | var listDSG: Array? = null 17 | 18 | fun reset(context: Context?) { 19 | context?.let { 20 | list22 = PIDs.list22?.clone() 21 | list3E = PIDs.list3E?.clone() 22 | listDSG = PIDs.listDSG?.clone() 23 | } 24 | } 25 | 26 | fun clear() { 27 | list22 = arrayOfNulls(0) 28 | list3E = arrayOfNulls(0) 29 | listDSG = arrayOfNulls(0) 30 | } 31 | 32 | fun save(context: Context?) { 33 | context?.let { 34 | //write current PID list 35 | PIDCSVFile.write( 36 | context.getString( 37 | R.string.filename_pid_csv, 38 | UDSLoggingMode.MODE_22.cfgName 39 | ), context, list22, true 40 | ) 41 | PIDCSVFile.write( 42 | context.getString( 43 | R.string.filename_pid_csv, 44 | UDSLoggingMode.MODE_3E.cfgName 45 | ), context, list3E, true 46 | ) 47 | PIDCSVFile.write(context.getString(R.string.filename_pid_csv, "DSG"), context, listDSG, true 48 | ) 49 | } 50 | } 51 | } 52 | 53 | class SettingsMode22Fragment: SettingsLoggingFragment() { 54 | override val TAG = "Settings22" 55 | override val mMode = UDSLoggingMode.MODE_22 56 | override val mLayout = R.layout.fragment_settings_mode22 57 | } 58 | 59 | class SettingsMode3EFragment: SettingsLoggingFragment() { 60 | override val TAG = "Settings3E" 61 | override val mMode = UDSLoggingMode.MODE_3E 62 | override val mLayout = R.layout.fragment_settings_mode3e 63 | } 64 | 65 | class SettingsModeDSGFragment: SettingsLoggingFragment() { 66 | override val TAG = "SettingsDSG" 67 | override val mMode = UDSLoggingMode.MODE_22 68 | override val mLayout = R.layout.fragment_settings_modedsg 69 | override val mDSG = true 70 | } 71 | 72 | open class SettingsLoggingFragment : Fragment() { 73 | open val TAG = "Settings" 74 | open val mMode = UDSLoggingMode.MODE_22 75 | open val mDSG = false 76 | open val mLayout = R.layout.fragment_settings_mode22 77 | open val mPIDLayout = R.id.recycleViewPID 78 | private var mPIDAdapter: SettingsViewAdapter? = null 79 | private var mPIDLayouts: Array? = null 80 | 81 | override fun onCreateView( 82 | inflater: LayoutInflater, container: ViewGroup?, 83 | savedInstanceState: Bundle? 84 | ): View? { 85 | // Inflate the layout for this fragment 86 | return inflater.inflate(mLayout, container, false) 87 | } 88 | 89 | override fun onCreate(savedInstanceState: Bundle?) { 90 | super.onCreate(savedInstanceState) 91 | 92 | doLoad() 93 | } 94 | 95 | override fun onPause() { 96 | super.onPause() 97 | 98 | doSave() 99 | } 100 | 101 | override fun onStart() { 102 | super.onStart() 103 | 104 | doLoad() 105 | } 106 | 107 | fun doSetColor() { 108 | view?.let { currentView -> 109 | //Set background color 110 | currentView.setBackgroundColor(ColorList.BG_NORMAL.value) 111 | } 112 | } 113 | 114 | fun doSave() { 115 | mPIDAdapter?.let { adapter -> 116 | for (i in 0 until adapter.itemCount-1) { 117 | adapter.saveData() 118 | } 119 | } 120 | 121 | //Set colors 122 | doSetColor() 123 | } 124 | 125 | fun doLoad() { 126 | view?.let { currentView -> 127 | // set up the RecyclerView 128 | val recyclerView: RecyclerView = currentView.findViewById(R.id.recycleViewPID) 129 | recyclerView.layoutManager = LinearLayoutManager(context) 130 | mPIDAdapter = if(mDSG) SettingsViewAdapter(context, TempPIDS.listDSG) 131 | else when (mMode) { 132 | UDSLoggingMode.MODE_22 -> SettingsViewAdapter(context, TempPIDS.list22) 133 | UDSLoggingMode.MODE_3E -> SettingsViewAdapter(context, TempPIDS.list3E) 134 | } 135 | mPIDAdapter!!.loadData() 136 | val callback = ItemMoveCallback(mPIDAdapter!!) 137 | val touchHelper = ItemTouchHelper(callback) 138 | touchHelper.attachToRecyclerView(recyclerView) 139 | recyclerView.adapter = mPIDAdapter 140 | 141 | //Set colors 142 | doSetColor() 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/SettingsViewPager.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.viewpager2.adapter.FragmentStateAdapter 5 | 6 | class SettingsViewPagerAdapter(fm: Fragment) : FragmentStateAdapter(fm) { 7 | private var mFragmentList: Array = arrayOf() 8 | private var mNameList: Array = arrayOf() 9 | 10 | override fun getItemCount(): Int { 11 | return mFragmentList.count() 12 | } 13 | 14 | override fun createFragment(position: Int): Fragment { 15 | return mFragmentList[position] 16 | } 17 | 18 | fun getName(position: Int): String { 19 | return mNameList[position] 20 | } 21 | 22 | fun addFragment(frag: Fragment, name: String) { 23 | mFragmentList += frag 24 | mNameList += name 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/SwitchAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import android.widget.TextView 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.ArrayAdapter 9 | 10 | class SwitchArrayAdapter(context: Context, textViewResourceId: Int, list: Array) : 11 | ArrayAdapter(context, textViewResourceId) { 12 | private val mContext: Context = context 13 | private val id: Int = textViewResourceId 14 | private var items: Array = list 15 | 16 | override fun getView(position: Int, v: View?, parent: ViewGroup): View { 17 | var mView = v 18 | if (mView == null) { 19 | val vi = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 20 | mView = vi.inflate(id, null) 21 | } 22 | val text = mView!!.findViewById(R.id.textView) 23 | 24 | text.setTextColor(ColorList.TEXT.value) 25 | text.text = items[position] 26 | 27 | return mView 28 | } 29 | 30 | override fun add(`object`: String?) { 31 | items += `object`?:"" 32 | 33 | super.add(`object`) 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/SwitchButton.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import android.graphics.* 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | 8 | class SwitchButton: androidx.appcompat.widget.AppCompatTextView { 9 | constructor(context: Context) : super(context) { 10 | super.setGravity(Gravity.CENTER) 11 | } 12 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { 13 | super.setGravity(Gravity.CENTER) 14 | } 15 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 16 | super.setGravity(Gravity.CENTER) 17 | } 18 | 19 | private var mRect = RectF(0f, 0f, 0f,0f) 20 | private var mPressed = false 21 | var margin = 10f 22 | var round = 50f 23 | val paintBGPress: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 24 | style = Paint.Style.FILL 25 | color = Color.GRAY 26 | strokeCap = Paint.Cap.ROUND 27 | } 28 | val paintBG: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 29 | style = Paint.Style.FILL 30 | color = Color.LTGRAY 31 | strokeCap = Paint.Cap.ROUND 32 | } 33 | val paintRim: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 34 | style = Paint.Style.STROKE 35 | color = Color.BLUE 36 | strokeCap = Paint.Cap.ROUND 37 | strokeWidth = 7f 38 | } 39 | 40 | override fun setTextColor(color: Int) { 41 | super.setTextColor(color) 42 | invalidate() 43 | } 44 | 45 | override fun onDraw(canvas: Canvas) { 46 | if(mPressed) { 47 | canvas.drawRoundRect(mRect, round, round, paintBGPress) 48 | } else { 49 | canvas.drawRoundRect(mRect, round, round, paintBG) 50 | } 51 | canvas.drawRoundRect(mRect, round, round, paintRim) 52 | super.onDraw(canvas) 53 | } 54 | 55 | override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) { 56 | mRect.set(margin, margin, width.toFloat()-margin, height.toFloat()-margin) 57 | 58 | invalidate() 59 | } 60 | 61 | override fun performClick(): Boolean { 62 | mPressed = true 63 | postDelayed({ 64 | mPressed = false 65 | invalidate() 66 | }, 100) 67 | invalidate() 68 | return super.performClick() 69 | } 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/SwitchCockpit.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | import android.content.Context 4 | import android.graphics.* 5 | import android.util.AttributeSet 6 | import android.view.View 7 | 8 | class SwitchCockpit: View { 9 | constructor(context: Context) : super(context) { 10 | } 11 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { 12 | } 13 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 14 | } 15 | private val bgPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 16 | style = Paint.Style.FILL_AND_STROKE 17 | color = Color.BLACK 18 | strokeWidth = 100.0f 19 | } 20 | private val linePaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 21 | style = Paint.Style.STROKE 22 | color = Color.RED 23 | strokeWidth = 5.0f 24 | } 25 | private val gaugeRing: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 26 | style = Paint.Style.FILL_AND_STROKE 27 | color = Color.WHITE 28 | strokeWidth = 50.0f 29 | } 30 | private val boostPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 31 | style = Paint.Style.FILL_AND_STROKE 32 | color = Color.WHITE 33 | strokeWidth = 1.0f 34 | } 35 | private val rpmPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 36 | style = Paint.Style.FILL_AND_STROKE 37 | color = Color.WHITE 38 | strokeWidth = 1.0f 39 | } 40 | private val textPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { 41 | style = Paint.Style.FILL_AND_STROKE 42 | color = Color.WHITE 43 | strokeWidth = 1.0f 44 | textSize = 30f 45 | textAlign = Paint.Align.CENTER 46 | } 47 | private var mCurrentWidth = 0f 48 | private var mCurrentHeight = 0f 49 | private var mCurrentWidthCenter = 0f 50 | private var mCurrentHeightCenter = 0f 51 | private var mRect = RectF() 52 | var dataVelocity = 0f 53 | var dataRPM = 0f 54 | var dataBoost = 0f 55 | var dataAccelerationLatitude = 0f 56 | var dataAccelerationLongitude = 0f 57 | 58 | fun doDraw() { 59 | invalidate() 60 | } 61 | 62 | private fun drawBoostGauge(canvas: Canvas, boost: Float, rpm: Float, size: Float) { 63 | val boostSegmentCount = 20 64 | val boostSegmentSize = 350f / boostSegmentCount 65 | val angleSegment = 50f / boostSegmentCount 66 | val strokeWidth = boostPaint.strokeWidth / 2.0f 67 | val boostAmount = boost / 300f * boostSegmentCount 68 | val rpmAmount = rpm / 7000f * boostSegmentCount 69 | val colorSegment = 1f / boostSegmentCount.toFloat() 70 | 71 | boostPaint.color = Color.GREEN 72 | rpmPaint.color = Color.GREEN 73 | for(i in 0 .. boostSegmentCount) { 74 | if(i >= boostAmount.toInt()) boostPaint.color = Color.WHITE 75 | else boostPaint.color = Color.rgb(colorSegment * i.toFloat(), 1f - (colorSegment * i.toFloat()), 0f) 76 | if(i >= rpmAmount.toInt()) rpmPaint.color = Color.WHITE 77 | else rpmPaint.color = Color.rgb(colorSegment * i.toFloat(), 1f - (colorSegment * i.toFloat()), 0f) 78 | 79 | canvas.drawRoundRect(mCurrentWidthCenter - 300f, mCurrentHeightCenter + 140f - (boostSegmentSize * (i - 0.5f)), mCurrentWidthCenter - 100f, mCurrentHeightCenter + 140f - (boostSegmentSize * i), 50f, 50f, boostPaint) 80 | canvas.drawRoundRect(mCurrentWidthCenter + 300f, mCurrentHeightCenter + 140f - (boostSegmentSize * (i - 0.5f)), mCurrentWidthCenter + 100f, mCurrentHeightCenter + 140f - (boostSegmentSize * i), 50f, 50f, rpmPaint) 81 | } 82 | 83 | canvas.drawCircle(mCurrentWidthCenter, mCurrentHeightCenter, 200f, bgPaint) 84 | } 85 | 86 | private fun drawVelocityGauge(canvas: Canvas, velocity: Float, size: Float) { 87 | val angleStart = 140f 88 | val angleSegmentCount = 50 89 | val angleSegment = 260f / angleSegmentCount 90 | val amount = velocity / 220f * angleSegmentCount 91 | val strokeWidth = linePaint.strokeWidth / 2.0f 92 | mRect.set(mCurrentWidthCenter - 200f, mCurrentHeightCenter - 200f, 200f + mCurrentWidthCenter, 200f + mCurrentHeightCenter) 93 | 94 | gaugeRing.color = Color.RED 95 | for(i in 0 .. angleSegmentCount) { 96 | if(i == amount.toInt()) 97 | gaugeRing.color = Color.WHITE 98 | canvas.drawArc(mRect, angleStart+(angleSegment * i)-(angleSegment*0.25f), angleSegment * 0.5f, false, gaugeRing) 99 | } 100 | } 101 | 102 | private fun drawAccelerationGauge(canvas: Canvas, latitude: Float, longitude: Float, size: Float) { 103 | 104 | } 105 | 106 | private fun drawVelocityText(canvas: Canvas, velocity: Float, size: Float) { 107 | textPaint.textSize = 30f * size 108 | canvas.drawText( 109 | "$velocity Km/h", 110 | mCurrentWidthCenter, 111 | mCurrentHeightCenter+(100f*size), 112 | textPaint 113 | ) 114 | } 115 | 116 | override fun onDraw(canvas: Canvas) { 117 | //draw background 118 | canvas.drawRect(0f, 0f, mCurrentWidth, mCurrentHeight, bgPaint) 119 | 120 | drawBoostGauge(canvas, dataBoost, dataRPM, 1.0f) 121 | drawAccelerationGauge(canvas, dataAccelerationLatitude, dataAccelerationLongitude, 1.0f) 122 | drawVelocityGauge(canvas, dataVelocity, 1.0f) 123 | drawVelocityText(canvas, dataVelocity, 1.0f) 124 | 125 | super.onDraw(canvas) 126 | } 127 | 128 | override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) { 129 | mCurrentWidth = width.toFloat() 130 | mCurrentHeight = height.toFloat() 131 | mCurrentWidthCenter = mCurrentWidth / 2.0f 132 | mCurrentHeightCenter = mCurrentHeight / 2.0f 133 | 134 | invalidate() 135 | } 136 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/UDSdtc.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | enum class DTCCommands(val str: String, val command: ByteArray, val response: ByteArray) { 4 | EXT_DIAG("Extended Diagnostic", byteArrayOf(0x10.toByte(), 0x03.toByte()), byteArrayOf(0x50.toByte(), 0x03.toByte())), 5 | DTC_REQ("DTC Request", byteArrayOf(0x19.toByte(), 0x02.toByte(), 0xAB.toByte()), byteArrayOf(0x7F.toByte(), 0x19.toByte())) 6 | } 7 | 8 | object UDSdtc { 9 | private val TAG = "UDSdtc" 10 | private var mLastString: String = "" 11 | private var mTimeoutCounter: Int = TIME_OUT_DTC 12 | 13 | fun getInfo(): String { 14 | return mLastString 15 | } 16 | 17 | fun getStartCount(clear: Boolean): Int { 18 | return if(clear) 1 19 | else DTCCommands.values().count() 20 | } 21 | 22 | fun startTask(ticks: Int, clear: Boolean): ByteArray { 23 | return if (clear) startClearDTC(ticks) 24 | else return startGetDTC(ticks) 25 | } 26 | 27 | private fun startClearDTC(ticks: Int): ByteArray { 28 | if(ticks < getStartCount(true)) { 29 | //Send clear request 30 | val bleHeader = BLEHeader() 31 | bleHeader.rxID = 0x7E8 32 | bleHeader.txID = 0x700 33 | bleHeader.cmdSize = 1 34 | bleHeader.cmdFlags = BLECommandFlags.PER_CLEAR.value 35 | 36 | return bleHeader.toByteArray() + byteArrayOf(0x04.toByte()) 37 | } 38 | 39 | return byteArrayOf() 40 | } 41 | 42 | private fun startGetDTC(ticks: Int): ByteArray { 43 | if(ticks < getStartCount(false)) { 44 | //Send clear request 45 | val bleHeader = BLEHeader() 46 | bleHeader.cmdSize = DTCCommands.values()[ticks].command.count() 47 | bleHeader.cmdFlags = BLECommandFlags.PER_CLEAR.value 48 | 49 | return bleHeader.toByteArray() + DTCCommands.values()[ticks].command 50 | } 51 | 52 | return byteArrayOf() 53 | } 54 | 55 | fun processPacket(ticks: Int, buff: ByteArray?, clear: Boolean): UDSReturn { 56 | buff?.let { 57 | resetTimeout() 58 | 59 | return if(clear) processClearPacket(ticks, buff) 60 | else processGetPacket(ticks, buff) 61 | } 62 | 63 | return addTimeout() 64 | } 65 | 66 | private fun processClearPacket(ticks: Int, buff: ByteArray): UDSReturn { 67 | if(ticks < getStartCount(true)) { 68 | mLastString = if (buff.count() == 9 && buff[8] == 0x44.toByte()) { 69 | "ok." 70 | } else { 71 | "failed." 72 | } 73 | 74 | return UDSReturn.OK 75 | } 76 | return UDSReturn.ERROR_UNKNOWN 77 | } 78 | 79 | private fun processGetPacket(ticks: Int, buff: ByteArray): UDSReturn { 80 | if(ticks < getStartCount(false) && buff.count() > 8) { 81 | val data = buff.copyOfRange(8, buff.count()) 82 | var resOk = true 83 | DTCCommands.values()[ticks].response.forEachIndexed() { i, d -> 84 | if(d != data[i]) 85 | resOk = false 86 | } 87 | 88 | return if (resOk) { 89 | mLastString = "ok." 90 | UDSReturn.OK 91 | } else { 92 | mLastString = "failed." 93 | UDSReturn.ERROR_RESPONSE 94 | } 95 | } 96 | 97 | if(buff.count() > 8) { 98 | var firstPIDs = true 99 | mLastString = "" 100 | var data = buff.copyOfRange(8, buff.count()) 101 | if(data.count() >= 3 && data[0] == 0x59.toByte() && data[1] == 0x02.toByte() && data[2] == 0xFF.toByte()) { 102 | return if (data.count() > 3) { 103 | data = data.copyOfRange(3, data.count()) 104 | while(data.count() >= 4) { 105 | val resInt = (data[1] shl 8) + data[2] 106 | DTCs.list.forEachIndexed() { i, d-> 107 | if(d?.code == resInt) { 108 | if(!firstPIDs) 109 | mLastString += "\n" 110 | mLastString += "${d.pcode} ${d.name}" 111 | firstPIDs = false 112 | } 113 | } 114 | 115 | data = data.copyOfRange(4, data.count()) 116 | } 117 | 118 | UDSReturn.COMPLETE 119 | } else { 120 | mLastString += "None found." 121 | UDSReturn.COMPLETE 122 | } 123 | } 124 | return UDSReturn.ERROR_RESPONSE 125 | } 126 | 127 | return UDSReturn.ERROR_HEADER 128 | } 129 | 130 | private fun addTimeout(): UDSReturn { 131 | if(--mTimeoutCounter == 0) { 132 | return UDSReturn.ERROR_TIME_OUT 133 | } 134 | 135 | return UDSReturn.OK 136 | } 137 | 138 | private fun resetTimeout() { 139 | mTimeoutCounter = TIME_OUT_DTC 140 | } 141 | } -------------------------------------------------------------------------------- /app/src/main/java/com/app/simostools/UDSinfo.kt: -------------------------------------------------------------------------------- 1 | package com.app.simostools 2 | 3 | object UDSInfo { 4 | private var TAG = "UDSInfo" 5 | private var mLastString: String = "" 6 | private var mTimeoutCounter: Int = TIME_OUT_INFO 7 | 8 | fun getInfo(): String { 9 | return mLastString 10 | } 11 | 12 | fun getStartCount(): Int { 13 | return ECUInfo.values().count() 14 | } 15 | 16 | fun startTask(index: Int): ByteArray { 17 | val bleHeader = BLEHeader() 18 | bleHeader.cmdSize = 1 + ECUInfo.values()[index].address.count() 19 | bleHeader.cmdFlags = BLECommandFlags.PER_CLEAR.value 20 | 21 | return bleHeader.toByteArray() + byteArrayOf(0x22.toByte()) + ECUInfo.values()[index].address 22 | } 23 | 24 | fun processPacket(ticks: Int, buff: ByteArray?): UDSReturn { 25 | buff?.let { 26 | resetTimeout() 27 | 28 | if (buff.count() >= 11 && buff[8] == 0x62.toByte()) { 29 | mLastString = "${ECUInfo.values()[ticks].str}: ${ECUInfo.values()[ticks].parseResponse(buff.copyOfRange(11, buff.count()))}" 30 | 31 | return UDSReturn.OK 32 | } 33 | return UDSReturn.ERROR_UNKNOWN 34 | } 35 | 36 | return addTimeout() 37 | } 38 | 39 | private fun addTimeout(): UDSReturn { 40 | if(--mTimeoutCounter == 0) { 41 | return UDSReturn.ERROR_TIME_OUT 42 | } 43 | 44 | return UDSReturn.OK 45 | } 46 | 47 | private fun resetTimeout() { 48 | mTimeoutCounter = TIME_OUT_INFO 49 | } 50 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 10 | 16 | 19 | 22 | 23 | 24 | 25 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/simoslogger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/drawable/simoslogger.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/simostools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/drawable/simostools.png -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_color.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 27 | 28 | 37 | 38 | 46 | 47 | 55 | 56 | 64 | 65 | 73 | 74 | 82 | 83 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_flashing.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_log_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 29 | 30 | 39 | 40 | 45 | 46 | 53 | 54 | 61 | 62 | 63 | 64 | 69 | 70 | 77 | 78 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_logging_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 21 | 22 | 31 | 32 | 40 | 41 | 50 | 51 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 30 | 31 | 36 | 37 | 44 | 45 | 52 | 53 | 60 | 61 | 62 | 63 | 68 | 69 | 76 | 77 | 84 | 85 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_pid.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_settings_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | 25 | 26 | 31 | 32 | 33 | 34 | 43 | 44 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_utilities.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_color.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 27 | 28 | 37 | 38 | 48 | 49 | 59 | 60 | 70 | 71 | 80 | 81 | 90 | 91 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_flashing.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_log_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 29 | 30 | 39 | 40 | 45 | 46 | 53 | 54 | 61 | 62 | 63 | 64 | 69 | 70 | 77 | 78 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_logging_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 21 | 22 | 31 | 32 | 40 | 41 | 50 | 51 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 30 | 31 | 36 | 37 | 44 | 45 | 52 | 53 | 60 | 61 | 62 | 63 | 68 | 69 | 76 | 77 | 84 | 85 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_pid.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_settings_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | 25 | 26 | 31 | 32 | 33 | 34 | 43 | 44 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp-land/fragment_utilities.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_color.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 27 | 28 | 37 | 38 | 48 | 49 | 59 | 60 | 70 | 71 | 80 | 81 | 90 | 91 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_flashing.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_log_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 29 | 30 | 39 | 40 | 45 | 46 | 53 | 54 | 61 | 62 | 63 | 64 | 69 | 70 | 77 | 78 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_logging_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 21 | 22 | 31 | 32 | 41 | 42 | 51 | 52 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 30 | 31 | 36 | 37 | 44 | 45 | 52 | 53 | 54 | 55 | 60 | 61 | 68 | 69 | 76 | 77 | 78 | 83 | 84 | 91 | 92 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_message.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_pid.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_settings_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | 25 | 26 | 31 | 32 | 33 | 34 | 43 | 44 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/fragment_utilities.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 22 | 23 | 24 | 25 | 29 | 30 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_cockpit.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_color.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 27 | 28 | 37 | 38 | 46 | 47 | 55 | 56 | 64 | 65 | 73 | 74 | 82 | 83 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_flashing.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_log_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 29 | 30 | 39 | 40 | 45 | 46 | 53 | 54 | 61 | 62 | 63 | 64 | 69 | 70 | 77 | 78 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_log_viewer_enabled.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 38 | 39 | 46 | 47 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_log_viewer_tabs.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 38 | 39 | 46 | 47 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_logging_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_logging_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 21 | 22 | 31 | 32 | 41 | 42 | 51 | 52 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 30 | 31 | 36 | 37 | 44 | 45 | 52 | 53 | 54 | 55 | 60 | 61 | 68 | 69 | 76 | 77 | 78 | 79 | 84 | 85 | 92 | 93 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_message.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_pid.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | 25 | 26 | 31 | 32 | 33 | 34 | 43 | 44 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings_mode22.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings_mode3e.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings_modedsg.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_utilities.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 52 | 53 | 63 | 64 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 17 | 18 | 21 | 22 | 25 | 26 | 29 | 30 | 33 | 34 | 35 | 36 | 41 | 42 | 45 | 46 | 49 | 50 | 51 | 52 | 57 | 58 | 59 | 64 | 65 | 66 | 71 | 72 | 75 | 76 | 79 | 80 | 81 | 82 | 87 | 88 | 89 | 94 | 95 | 96 | 101 | 102 | 103 | 108 | 109 | 112 | 113 | 114 | 115 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /app/src/main/res/raw/pops.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/app/src/main/res/raw/pops.mp3 -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #0000EE 4 | #000000 5 | #03DAC5 6 | #546E7A 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 14 | 15 | 25 | 30 | 31 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:7.0.4' 9 | classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | task clean(type: Delete) { 17 | delete rootProject.buildDir 18 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 13 19:38:25 MDT 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /images/screenshot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/images/screenshot1.jpg -------------------------------------------------------------------------------- /images/screenshot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/images/screenshot2.jpg -------------------------------------------------------------------------------- /images/screenshot3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/images/screenshot3.jpg -------------------------------------------------------------------------------- /images/screenshot4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/images/screenshot4.jpg -------------------------------------------------------------------------------- /images/screenshot5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/images/screenshot5.jpg -------------------------------------------------------------------------------- /images/screenshot6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/images/screenshot6.jpg -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 3 | repositories { 4 | google() 5 | mavenCentral() 6 | jcenter() // Warning: this repository is going to shut down soon 7 | } 8 | } 9 | rootProject.name = "Simos Tools" 10 | include ':app' 11 | -------------------------------------------------------------------------------- /simos.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Switchleg1/SimosTools/f99771ceb0442c863601a84a282c6e67e6b311a8/simos.jks --------------------------------------------------------------------------------