├── app ├── .idea │ ├── .name │ ├── .gitignore │ ├── compiler.xml │ ├── vcs.xml │ ├── gradle.xml │ ├── jarRepositories.xml │ └── misc.xml ├── app │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── raw │ │ │ │ │ ├── ping.mp3 │ │ │ │ │ └── beeper.mp3 │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── themes.xml │ │ │ │ ├── drawable │ │ │ │ │ ├── bluetooth.png │ │ │ │ │ ├── settings.png │ │ │ │ │ ├── strength0.png │ │ │ │ │ ├── strength1.png │ │ │ │ │ ├── strength2.png │ │ │ │ │ ├── strength3.png │ │ │ │ │ ├── strength4.png │ │ │ │ │ └── strength5.png │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── values-night │ │ │ │ │ └── themes.xml │ │ │ │ ├── drawable-v24 │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ └── layout │ │ │ │ │ └── mqtt_settings_dialog.xml │ │ │ ├── ic_launcher-playstore.png │ │ │ ├── cpp │ │ │ │ ├── bluebridgeapp.cpp │ │ │ │ └── CMakeLists.txt │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── bluebridgeapp │ │ │ │ ├── Utils.java │ │ │ │ ├── MqttSettingsDialogFragment.java │ │ │ │ └── AnchorView.java │ │ ├── test │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── bluebridgeapp │ │ │ │ └── ExampleUnitTest.java │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── bluebridgeapp │ │ │ └── ExampleInstrumentedTest.java │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle ├── settings.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── doc ├── .gitignore └── SMS commands.docx ├── .gitignore ├── components └── n2klib │ ├── include │ ├── n2klib.h │ ├── N2kCANMsg.h │ ├── Seasmart.h │ ├── N2kDef.h │ ├── N2kStream.h │ ├── NMEA2000_CompilerDefns.h │ ├── NMEA2000_esp32.h │ ├── ActisenseReader.h │ ├── RingBuffer.h │ ├── N2kMessagesEnumToStr.h │ ├── N2kGroupFunctionDefaultHandlers.h │ └── N2kMaretron.h │ ├── CMakeLists.txt │ ├── N2kStream.cpp │ ├── N2kMaretron.cpp │ ├── Seasmart.cpp │ └── ActisenseReader.cpp ├── hw ├── .gitignore ├── bom.xlsx ├── BlueBridge.pcb ├── BlueBridge.prj ├── BlueBridge.sch ├── BlueBridge - PCB.pdf └── BlueBridge - Project.pdf ├── website ├── reativeAngleBg.bmp └── images │ ├── strength0.png │ ├── strength1.png │ ├── strength2.png │ ├── strength3.png │ ├── strength4.png │ ├── strength5.png │ ├── zoomIn_blur.png │ ├── zoomIn_focus.png │ ├── zoomOut_blur.png │ └── zoomOut_focus.png ├── CMakeLists.txt ├── sdkconfig.defaults ├── main ├── CMakeLists.txt ├── pdu.h ├── timer.h ├── publisher.h ├── led.h ├── temperature_sensor.h ├── timer.c ├── flash.h ├── pressure_sensor.h ├── property_parser.h ├── flash.c ├── wmm.h ├── serial.h ├── sms.h ├── led.c ├── spp_acceptor.h ├── serial.c ├── util.h ├── property_parser.c ├── WMM_COF.c ├── temperature_sensor.c ├── util.c ├── sms.c └── modem_interface.h ├── LICENSE └── README.md /app/.idea/.name: -------------------------------------------------------------------------------- 1 | BlueBridgeApp -------------------------------------------------------------------------------- /app/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | html/ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | sdkconfig 3 | -------------------------------------------------------------------------------- /components/n2klib/include/n2klib.h: -------------------------------------------------------------------------------- 1 | void func(void); 2 | -------------------------------------------------------------------------------- /hw/.gitignore: -------------------------------------------------------------------------------- 1 | ~BlueBridge.pcb 2 | ~BlueBridge.sch 3 | *.txt 4 | *.mop 5 | -------------------------------------------------------------------------------- /hw/bom.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/hw/bom.xlsx -------------------------------------------------------------------------------- /app/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /hw/BlueBridge.pcb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/hw/BlueBridge.pcb -------------------------------------------------------------------------------- /hw/BlueBridge.prj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/hw/BlueBridge.prj -------------------------------------------------------------------------------- /hw/BlueBridge.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/hw/BlueBridge.sch -------------------------------------------------------------------------------- /doc/SMS commands.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/doc/SMS commands.docx -------------------------------------------------------------------------------- /hw/BlueBridge - PCB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/hw/BlueBridge - PCB.pdf -------------------------------------------------------------------------------- /website/reativeAngleBg.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/reativeAngleBg.bmp -------------------------------------------------------------------------------- /hw/BlueBridge - Project.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/hw/BlueBridge - Project.pdf -------------------------------------------------------------------------------- /website/images/strength0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/strength0.png -------------------------------------------------------------------------------- /website/images/strength1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/strength1.png -------------------------------------------------------------------------------- /website/images/strength2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/strength2.png -------------------------------------------------------------------------------- /website/images/strength3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/strength3.png -------------------------------------------------------------------------------- /website/images/strength4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/strength4.png -------------------------------------------------------------------------------- /website/images/strength5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/strength5.png -------------------------------------------------------------------------------- /website/images/zoomIn_blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/zoomIn_blur.png -------------------------------------------------------------------------------- /website/images/zoomIn_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/zoomIn_focus.png -------------------------------------------------------------------------------- /website/images/zoomOut_blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/zoomOut_blur.png -------------------------------------------------------------------------------- /app/app/src/main/res/raw/ping.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/raw/ping.mp3 -------------------------------------------------------------------------------- /app/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Blue Bridge 3 | -------------------------------------------------------------------------------- /website/images/zoomOut_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/website/images/zoomOut_focus.png -------------------------------------------------------------------------------- /app/app/src/main/res/raw/beeper.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/raw/beeper.mp3 -------------------------------------------------------------------------------- /app/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/bluetooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/bluetooth.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/settings.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/strength0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/strength0.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/strength1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/strength1.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/strength2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/strength2.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/strength3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/strength3.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/strength4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/strength4.png -------------------------------------------------------------------------------- /app/app/src/main/res/drawable/strength5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/drawable/strength5.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | add_compile_definitions(ESP32) 3 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 4 | project(BlueBridge) 5 | -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miniwinwm/BlueBridge/HEAD/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /app/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Mar 03 19:03:20 GMT 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /app/.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 | -------------------------------------------------------------------------------- /app/app/src/main/cpp/bluebridgeapp.cpp: -------------------------------------------------------------------------------- 1 | // Write C++ code here. 2 | // 3 | // Do not forget to dynamically load the C++ library into your application. 4 | // 5 | // For instance, 6 | // 7 | // In MainActivity.java: 8 | // static { 9 | // System.loadLibrary("bluebridgeapp"); 10 | // } 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | plugins { 3 | id 'com.android.application' version '7.1.2' apply false 4 | id 'com.android.library' version '7.1.2' apply false 5 | } 6 | 7 | task clean(type: Delete) { 8 | delete rootProject.buildDir 9 | } -------------------------------------------------------------------------------- /sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | CONFIG_BT_ENABLED=y 2 | CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n 3 | CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y 4 | CONFIG_BTDM_CTRL_MODE_BTDM=n 5 | CONFIG_BT_CLASSIC_ENABLED=y 6 | CONFIG_WIFI_ENABLED=n 7 | CONFIG_BT_SPP_ENABLED=y 8 | CONFIG_BT_BLE_ENABLED=n 9 | CONFIG_FREERTOS_HZ=1000 10 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=32768 -------------------------------------------------------------------------------- /app/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "BlueBridgeApp" 16 | include ':app' 17 | -------------------------------------------------------------------------------- /app/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/app/src/test/java/com/example/bluebridgeapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.bluebridgeapp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "main.cpp" 2 | "pressure_sensor.c" 3 | "serial.c" 4 | "spp_acceptor.c" 5 | "flash.c" 6 | "nmea.c" 7 | "timer.c" 8 | "wmm.c" 9 | "WMM_COF.c" 10 | "modem.c" 11 | "modem_interface.c" 12 | "mqtt.c" 13 | "publisher.c" 14 | "pdu.c" 15 | "settings.c" 16 | "property_parser.c" 17 | "sms.c" 18 | "util.c" 19 | "led.c" 20 | "temperature_sensor.c" 21 | INCLUDE_DIRS ".") 22 | -------------------------------------------------------------------------------- /components/n2klib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "nmea2000_esp32.cpp" 2 | "nmea2000.cpp" 3 | "N2kMsg.cpp" 4 | "N2kStream.cpp" 5 | "N2kMessages.cpp" 6 | "Seasmart.cpp" 7 | "N2kDeviceList.cpp" 8 | "N2kGroupFunction.cpp" 9 | "N2kGroupFunctionDefaultHandlers.cpp" 10 | "N2kMaretron.cpp" 11 | INCLUDE_DIRS "include" 12 | REQUIRES "driver" 13 | PRIV_REQUIRES "esp_timer") 14 | -------------------------------------------------------------------------------- /app/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /app/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/app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/app/src/androidTest/java/com/example/bluebridgeapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.bluebridgeapp; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.example.bluebridgeapp", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 John Blaiklock 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | The user of this code is not a citizen, business or resident of Russia or Belarus. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /app/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /main/pdu.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Avalon Project Authors. All rights reserved. 2 | // Use of this source code is governed by the Apache License 2.0 3 | // that can be found in the LICENSE file. 4 | #ifndef SMS_PDU_H_ 5 | #define SMS_PDU_H_ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include 12 | 13 | enum { SMS_MAX_PDU_LENGTH = 256 }; 14 | 15 | /* 16 | * Encode an SMS message. Output the encoded message into output pdu buffer. 17 | * Returns the length of the SMS encoded message in the output buffer or 18 | * a negative number in case encoding failed (for example provided output buffer 19 | * does not have enough space). 20 | */ 21 | int pdu_encode(const char* service_center_number, const char* phone_number, const char* text, 22 | unsigned char* pdu, int pdu_size); 23 | 24 | /* 25 | * Decode an SMS message. Output the decoded message into the sms text buffer. 26 | * Returns the length of the SMS decoded message or a negative number in 27 | * case decoding failed (for example provided output buffer has not enough 28 | * space). 29 | */ 30 | int pdu_decode(const unsigned char* pdu, int pdu_len, 31 | time_t* sms_time, 32 | char* phone_number, int phone_number_size, 33 | char* text, int text_size); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif // SMS_SMS_H_ -------------------------------------------------------------------------------- /app/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 | # Enables namespacing of each library's R class so that its R class includes only the 19 | # resources declared in the library itself and none from the library's dependencies, 20 | # thereby reducing the size of the R class for that library 21 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /app/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | } 4 | 5 | android { 6 | compileSdk 32 7 | 8 | defaultConfig { 9 | applicationId "com.example.bluebridgeapp" 10 | minSdk 21 11 | targetSdk 32 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | externalNativeBuild { 17 | cmake { 18 | cppFlags '' 19 | } 20 | } 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | externalNativeBuild { 34 | cmake { 35 | path file('src/main/cpp/CMakeLists.txt') 36 | version '3.18.1' 37 | } 38 | } 39 | packagingOptions { 40 | exclude 'META-INF/INDEX.LIST' 41 | exclude 'META-INF/io.netty.versions.properties' 42 | } 43 | } 44 | 45 | dependencies { 46 | implementation 'com.hivemq:hivemq-mqtt-client:1.3.0' 47 | implementation 'androidx.appcompat:appcompat:1.4.1' 48 | implementation 'com.google.android.material:material:1.5.0' 49 | implementation 'androidx.constraintlayout:constraintlayout:2.1.3' 50 | testImplementation 'junit:junit:4.13.2' 51 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 52 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 53 | } -------------------------------------------------------------------------------- /app/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | -------------------------------------------------------------------------------- /app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 10 | 16 | 19 | 22 | 23 | 24 | 25 | 31 | -------------------------------------------------------------------------------- /app/app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # For more information about using CMake with Android Studio, read the 3 | # documentation: https://d.android.com/studio/projects/add-native-code.html 4 | 5 | # Sets the minimum version of CMake required to build the native library. 6 | 7 | cmake_minimum_required(VERSION 3.18.1) 8 | 9 | # Declares and names the project. 10 | 11 | project("bluebridgeapp") 12 | 13 | # Creates and names a library, sets it as either STATIC 14 | # or SHARED, and provides the relative paths to its source code. 15 | # You can define multiple libraries, and CMake builds them for you. 16 | # Gradle automatically packages shared libraries with your APK. 17 | 18 | add_library( # Sets the name of the library. 19 | bluebridgeapp 20 | 21 | # Sets the library as a shared library. 22 | SHARED 23 | 24 | # Provides a relative path to your source file(s). 25 | bluebridgeapp.cpp 26 | ) 27 | 28 | # Searches for a specified prebuilt library and stores the path as a 29 | # variable. Because CMake includes system libraries in the search path by 30 | # default, you only need to specify the name of the public NDK library 31 | # you want to add. CMake verifies that the library exists before 32 | # completing its build. 33 | 34 | find_library( # Sets the name of the path variable. 35 | log-lib 36 | 37 | # Specifies the name of the NDK library that 38 | # you want CMake to locate. 39 | log ) 40 | 41 | # Specifies libraries CMake should link to your target library. You 42 | # can link multiple libraries, such as libraries you define in this 43 | # build script, prebuilt third-party libraries, or system libraries. 44 | 45 | target_link_libraries( # Specifies the target library. 46 | bluebridgeapp 47 | 48 | # Links the target library to the log library 49 | # included in the NDK. 50 | ${log-lib} ) 51 | -------------------------------------------------------------------------------- /main/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef TIMER_H 28 | #define TIMER_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | /************ 45 | *** TYPES *** 46 | ************/ 47 | 48 | /************************* 49 | *** EXTERNAL VARIABLES *** 50 | *************************/ 51 | 52 | /*************************** 53 | *** FUNCTIONS PROTOTYPES *** 54 | ***************************/ 55 | 56 | /** 57 | * Get system up time in milliseconds 58 | * 59 | * @return Time in milliseconds 60 | */ 61 | uint32_t timer_get_time_ms(); 62 | 63 | /** 64 | * Get system up time in seconds 65 | * 66 | * @return Time in seconds 67 | */ 68 | uint32_t timer_get_time_s(); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /main/publisher.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef PUBLISHER_H 28 | #define PUBLISHER_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | /************** 39 | *** DEFINES *** 40 | **************/ 41 | 42 | #define PUBLISHER_MAX_FAILED_COUNT 10U ///< Maximum number of times a publish is allowed to fail before a reboot of device 43 | 44 | /************ 45 | *** TYPES *** 46 | ************/ 47 | 48 | /************************* 49 | *** EXTERNAL VARIABLES *** 50 | *************************/ 51 | 52 | /*************************** 53 | *** FUNCTIONS PROTOTYPES *** 54 | ***************************/ 55 | 56 | /** 57 | * Task function for publishing boat data via MQTT and receiving SMS control messages 58 | * 59 | * @param parameters Pointer to any parameters sent to the task on start up 60 | */ 61 | void publisher_task(void *parameters); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif -------------------------------------------------------------------------------- /main/led.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef LED_H 28 | #define LED_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | /************ 45 | *** TYPES *** 46 | ************/ 47 | 48 | /************************* 49 | *** EXTERNAL VARIABLES *** 50 | *************************/ 51 | 52 | /*************************** 53 | *** FUNCTIONS PROTOTYPES *** 54 | ***************************/ 55 | 56 | /** 57 | * Initialize the LED driver. Call once before using other functions. 58 | */ 59 | void led_init(void); 60 | 61 | /** 62 | * Flash the LED 63 | * 64 | * @param ms Time to flash the LED for in milliseconds 65 | * @note Calling with a short flash length while a longer flash is in progress will be ignored. 66 | */ 67 | void led_flash(uint32_t ms); 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif -------------------------------------------------------------------------------- /main/temperature_sensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef TEMPERATURE_SENSOR_H 28 | #define TEMPERATURE_SENSOR_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | 45 | /************ 46 | *** TYPES *** 47 | ************/ 48 | 49 | /************************* 50 | *** EXTERNAL VARIABLES *** 51 | *************************/ 52 | 53 | /*************************** 54 | *** FUNCTIONS PROTOTYPES *** 55 | ***************************/ 56 | 57 | /** 58 | * Initialize the temperature sensor driver. Call this once at startup before using other functions. 59 | */ 60 | void temperature_sensor_init(void); 61 | 62 | /** 63 | * Read exhaust temperature sensor from sensor 64 | * 65 | * @return temperature in degrees C 66 | */ 67 | float temperature_sensor_read(void); 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /main/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include "freertos/freeRTOS.h" 32 | #include "freertos/task.h" 33 | #include "timer.h" 34 | 35 | /************** 36 | *** DEFINES *** 37 | **************/ 38 | 39 | /************ 40 | *** TYPES *** 41 | ************/ 42 | 43 | /******************************** 44 | *** LOCAL FUNCTION PROTOTYPES *** 45 | ********************************/ 46 | 47 | /********************** 48 | *** LOCAL VARIABLES *** 49 | **********************/ 50 | 51 | /*********************** 52 | *** GLOBAL VARIABLES *** 53 | ***********************/ 54 | 55 | /**************** 56 | *** CONSTANTS *** 57 | ****************/ 58 | 59 | /********************** 60 | *** LOCAL FUNCTIONS *** 61 | **********************/ 62 | 63 | /*********************** 64 | *** GLOBAL FUNCTIONS *** 65 | ***********************/ 66 | 67 | uint32_t timer_get_time_ms() 68 | { 69 | return (uint32_t)xTaskGetTickCount() * (1000UL / configTICK_RATE_HZ); 70 | } 71 | 72 | uint32_t timer_get_time_s() 73 | { 74 | return timer_get_time_ms() / 1000UL; 75 | } 76 | -------------------------------------------------------------------------------- /main/flash.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef FLASH_H 28 | #define FLASH_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | /************ 45 | *** TYPES *** 46 | ************/ 47 | 48 | /************************* 49 | *** EXTERNAL VARIABLES *** 50 | *************************/ 51 | 52 | /*************************** 53 | *** FUNCTIONS PROTOTYPES *** 54 | ***************************/ 55 | 56 | /** 57 | * Initialize the flash driver. Call once before using flash functions. 58 | */ 59 | void flash_init(void); 60 | 61 | /** 62 | * Load data from flash into memory 63 | * 64 | * @param data Buffer to load data into 65 | * @param length Length in bytes of data 66 | */ 67 | void flash_load_data(void *data, size_t length); 68 | 69 | /** 70 | * Save data into flash memory 71 | * 72 | * @param data Buffer containing data to write into flash 73 | * @param length Length in bytes of data 74 | */ 75 | void flash_store_data(const void *data, size_t length); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /components/n2klib/include/N2kCANMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | N2kCANMsg.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef _tN2kCANMsg_H_ 25 | #define _tN2kCANMsg_H_ 26 | #include 27 | 28 | class tN2kCANMsg 29 | { 30 | public: 31 | tN2kCANMsg() 32 | : Ready(false),FreeMsg(true),SystemMessage(false), KnownMessage(false) 33 | #if !defined(N2K_NO_ISO_MULTI_PACKET_SUPPORT) 34 | ,TPRequireCTS(false), TPMaxPackets(0) 35 | #endif 36 | { 37 | N2kMsg.Clear(); 38 | } 39 | tN2kMsg N2kMsg; 40 | bool Ready; // Ready for handling 41 | bool FreeMsg; // Msg is free for fill up 42 | bool SystemMessage; 43 | bool KnownMessage; 44 | #if !defined(N2K_NO_ISO_MULTI_PACKET_SUPPORT) 45 | unsigned char TPRequireCTS; // =0 no, n=after each n frames 46 | unsigned char TPMaxPackets; // =0 not TP message. >0 number of packets can be received. 47 | #endif 48 | unsigned char LastFrame; // Last received frame sequence number on fast packets or multi packet 49 | unsigned char CopiedLen; 50 | 51 | public: 52 | void FreeMessage() { 53 | FreeMsg=true; Ready=false; SystemMessage=false; 54 | #if !defined(N2K_NO_ISO_MULTI_PACKET_SUPPORT) 55 | TPMaxPackets=0; TPRequireCTS=false; 56 | #endif 57 | N2kMsg.Clear(); N2kMsg.Source=0; 58 | } 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /main/pressure_sensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef PRESSURE_SENSOR_H 28 | #define PRESSURE_SENSOR_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | #define I2C_MEASUREMENT_PERIOD_MS 1000U ///< Period in milliseconds to take a measurement from pressure sensor 45 | 46 | /************ 47 | *** TYPES *** 48 | ************/ 49 | 50 | /************************* 51 | *** EXTERNAL VARIABLES *** 52 | *************************/ 53 | 54 | /*************************** 55 | *** FUNCTIONS PROTOTYPES *** 56 | ***************************/ 57 | 58 | /** 59 | * Initialize the pressure sensor driver. Call this once at startup before using other functions. 60 | */ 61 | void pressure_sensor_init(void); 62 | 63 | /** 64 | * Read a pressure sensor measurement if one is available 65 | * 66 | * @param read_measurement Pointer to float that will contain the read pressure in mb if it is available 67 | * @return If a measurement is available and the parameter is not NULL then true else false 68 | */ 69 | bool pressure_sensor_read_measurement_mb(float *read_measurement); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /components/n2klib/include/Seasmart.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License 3 | 4 | Copyright (c) 2017-2021 Thomas Sarlandie thomas@sarlandie.net 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | */ 24 | 25 | #ifndef _Seasmart_h_ 26 | #define _Seasmart_h_ 27 | 28 | #include 29 | 30 | /** 31 | * Converts a tN2kMsg into a $PCDIN NMEA sentence, following the Seasmart 32 | * specification. The buffer must be at least (30 + 2*msg.DataLen) bytes long. 33 | * 34 | * Reference: http://www.seasmart.net/pdf/SeaSmart_HTTP_Protocol_RevG_043012.pdf 35 | * 36 | * If the buffer is not long enough, this function returns 0 and does not do 37 | * anything. 38 | * 39 | * If the buffer is long enough, this function returns the number of bytes 40 | * written including the terminating \0 (but this function does not add the 41 | * NMEA separator \r\n). 42 | */ 43 | size_t N2kToSeasmart(const tN2kMsg &msg, uint32_t timestamp, char *buffer, size_t size); 44 | 45 | /** 46 | * Converts a null terminated $PCDIN NMEA sentence into a tN2kMsg and updates 47 | * timestamp with the timestamp of the sentence. 48 | * 49 | * Reference: http://www.seasmart.net/pdf/SeaSmart_HTTP_Protocol_RevG_043012.pdf 50 | * 51 | * The NMEA \r\n terminator is not required. 52 | * 53 | * Returns true if it succeeded. 54 | * Returns false if an error occured. 55 | */ 56 | bool SeasmartToN2k(const char *buffer, uint32_t ×tamp, tN2kMsg &msg); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /components/n2klib/include/N2kDef.h: -------------------------------------------------------------------------------- 1 | /* 2 | N2kDef.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | Type definitions and utility macros used in the NMEA2000 libraries. 24 | 25 | */ 26 | 27 | #ifndef _tN2kDef_H_ 28 | #define _tN2kDef_H_ 29 | 30 | #include 31 | 32 | #if !defined(ARDUINO) 33 | extern "C" { 34 | // Application execution delay. Must be implemented by application. 35 | extern void delay(uint32_t ms); 36 | 37 | // Current uptime in milliseconds. Must be implemented by application. 38 | extern uint32_t millis(); 39 | } 40 | #endif 41 | 42 | // Declare PROGMEM macros to nothing on non-AVR targets. 43 | #if !defined(__AVR__) && !defined(ARDUINO) 44 | // ESP8266 provides it's own definition - Do not override it. 45 | #if !defined(ARDUINO_ARCH_ESP8266) 46 | #define PROGMEM 47 | #define pgm_read_byte(var) *var 48 | #define pgm_read_word(var) *var 49 | #define pgm_read_dword(var) *var 50 | #endif 51 | #endif 52 | 53 | // Definition for the F(str) macro. On Arduinos use what the framework 54 | // provides to utilize the Stream class. On standard AVR8 we declare 55 | // our own helper class which is handled by the N2kStream. On anything 56 | // else we resort to char strings. 57 | #if defined(ARDUINO) 58 | #include 59 | #elif defined(__AVR__) 60 | #include 61 | class __FlashStringHelper; 62 | #define F(str) (reinterpret_cast(PSTR(str))) 63 | #else 64 | #ifndef F 65 | #define F(str) str 66 | #endif 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /components/n2klib/include/N2kStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | N2kStream.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | I/O stream used in the NMEA2000 libraries. 24 | 25 | */ 26 | 27 | #ifndef _tN2kStream_H_ 28 | #define _tN2kStream_H_ 29 | 30 | #include "N2kDef.h" 31 | #include 32 | #include 33 | 34 | #ifdef ARDUINO 35 | // Arduino users get away with using the standard Stream class and its 36 | // subclasses. Forward declare the Stream class here and include Arduino.h in 37 | // the application. 38 | #include 39 | typedef Stream N2kStream; 40 | #else 41 | // Non Arduino platforms need to implement this themselves if they want to use 42 | // functions which operate on streams. 43 | class N2kStream { 44 | public: 45 | // Returns first byte if incoming data, or -1 on no available data. 46 | virtual int read() = 0; 47 | 48 | // Write data to stream. 49 | virtual size_t write(const uint8_t* data, size_t size) = 0; 50 | 51 | // Print string to stream. 52 | size_t print(const char* str); 53 | 54 | #if defined(__AVR__) 55 | // Flash stored string stream for AVR platforms. 56 | size_t print(const __FlashStringHelper* str); 57 | size_t println(const __FlashStringHelper* str); 58 | #endif 59 | 60 | // Print value to stream. 61 | size_t print(int val, uint8_t radix = 10); 62 | 63 | // Print string and newline to stream. 64 | size_t println(const char *str); 65 | 66 | // Print value and newline to stream. 67 | size_t println(int val, uint8_t radix = 10); 68 | }; 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /main/property_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef PROPERTY_PARSER_H 28 | #define PROPERTY_PARSER_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | #include 40 | 41 | /************** 42 | *** DEFINES *** 43 | **************/ 44 | 45 | /************ 46 | *** TYPES *** 47 | ************/ 48 | 49 | /** 50 | * Callback function called by parser when a key/value pair or command is found. 51 | * 52 | * @param key String containg the key or command 53 | * @param value String containing the value or empty string for a command 54 | * @note All \n and = values are removed 55 | */ 56 | typedef bool (*parser_callback_t)(char *key, char *value); 57 | 58 | /************************* 59 | *** EXTERNAL VARIABLES *** 60 | *************************/ 61 | 62 | /*************************** 63 | *** FUNCTIONS PROTOTYPES *** 64 | ***************************/ 65 | 66 | /** 67 | * Parse key/value pairs in format key=value\n. There can be multiple key/value pairs. Also parses commands in 68 | * format command\n. In this case the returned value is an empty string. 69 | * 70 | * @param str The string to parse. The last item does not need to end in a \n. 71 | * @param parser_callback A callback function that is called when a key/value pair or a command is found 72 | * @return The number of key/value and commands found. 73 | */ 74 | uint16_t property_parse(char *str, parser_callback_t parser_callback); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif -------------------------------------------------------------------------------- /components/n2klib/N2kStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | N2kStream.cpp 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | I/O stream used in the NMEA2000 libraries. 24 | 25 | */ 26 | #include "N2kStream.h" 27 | #include 28 | 29 | #ifdef ARDUINO 30 | // Arduino uses its own implementation. 31 | #else 32 | size_t N2kStream::print(const char *str) { 33 | if(str == 0) 34 | return 0; 35 | 36 | return write(reinterpret_cast(str), strlen(str)); 37 | } 38 | 39 | #if defined(__AVR__) 40 | size_t N2kStream::print(const __FlashStringHelper* str) { 41 | size_t bytes_written = 0; 42 | PGM_P src = (PGM_P) str; 43 | for(uint8_t c = pgm_read_byte(src); c != 0; ++src, ++bytes_written) 44 | write(&c, 1); 45 | 46 | return bytes_written; 47 | } 48 | 49 | size_t N2kStream::print(const __FlashStringHelper* str) { 50 | return print(str) + print("\r\n"); 51 | } 52 | #endif 53 | 54 | 55 | size_t N2kStream::print(int val, uint8_t radix) { 56 | 57 | if(val == 0) { 58 | // 0 is always 0 regardless of radix. 59 | return write(reinterpret_cast("0"), 1); 60 | } 61 | 62 | // Enough for binary representation. 63 | char buf[8 * sizeof(val) + 1]; 64 | char *ptr = &buf[sizeof(buf) - 1]; 65 | *ptr = '\0'; 66 | 67 | do { 68 | *--ptr="0123456789abcdef"[val % radix]; 69 | val /= radix; 70 | } while(val != 0); 71 | 72 | return print(ptr); 73 | } 74 | 75 | size_t N2kStream::println(const char *str) { 76 | return print(str) + print("\r\n"); 77 | } 78 | 79 | size_t N2kStream::println(int val, uint8_t radix) { 80 | return print(val, radix) + print("\r\n"); 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /main/flash.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include "flash.h" 32 | #include "nvs_flash.h" 33 | 34 | /************** 35 | *** DEFINES *** 36 | **************/ 37 | 38 | /************ 39 | *** TYPES *** 40 | ************/ 41 | 42 | /******************************** 43 | *** LOCAL FUNCTION PROTOTYPES *** 44 | ********************************/ 45 | 46 | /********************** 47 | *** LOCAL VARIABLES *** 48 | **********************/ 49 | 50 | /*********************** 51 | *** GLOBAL VARIABLES *** 52 | ***********************/ 53 | 54 | /**************** 55 | *** CONSTANTS *** 56 | ****************/ 57 | 58 | /********************** 59 | *** LOCAL FUNCTIONS *** 60 | **********************/ 61 | 62 | /*********************** 63 | *** GLOBAL FUNCTIONS *** 64 | ***********************/ 65 | 66 | void flash_init(void) 67 | { 68 | esp_err_t err = nvs_flash_init(); 69 | if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) 70 | { 71 | /* NVS partition was truncated and needs to be erased */ 72 | nvs_flash_erase(); 73 | err = nvs_flash_init(); 74 | } 75 | } 76 | 77 | void flash_load_data(void *data, size_t length) 78 | { 79 | nvs_handle my_handle; 80 | size_t required_size = length; 81 | 82 | nvs_open("MINIWIN_NON_VOL", NVS_READONLY, &my_handle); 83 | 84 | nvs_get_blob(my_handle, "SETTINGS", data, &required_size); 85 | 86 | nvs_close(my_handle); 87 | } 88 | 89 | void flash_store_data(const void *data, size_t length) 90 | { 91 | nvs_handle my_handle; 92 | 93 | nvs_open("MINIWIN_NON_VOL", NVS_READWRITE, &my_handle); 94 | 95 | nvs_set_blob(my_handle, "SETTINGS", data, (size_t)length); 96 | nvs_commit(my_handle); 97 | 98 | nvs_close(my_handle); 99 | } 100 | -------------------------------------------------------------------------------- /app/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 | -------------------------------------------------------------------------------- /main/wmm.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef WMM_H 28 | #define WMM_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | #define WMM_EPOCH 2020.0f ///< the start year of the model coefficients 45 | 46 | /************ 47 | *** TYPES *** 48 | ************/ 49 | 50 | /** 51 | * A field in the model coefficients table 52 | */ 53 | typedef struct 54 | { 55 | float gnm; 56 | float hnm; 57 | float dgnm; 58 | float dhnm; 59 | } wmm_cof_record_t; 60 | 61 | /************************* 62 | *** EXTERNAL VARIABLES *** 63 | *************************/ 64 | 65 | extern const uint8_t wmm_cof_entries_encoded[]; ///< the encoded coefficients table 66 | 67 | /*************************** 68 | *** FUNCTIONS PROTOTYPES *** 69 | ***************************/ 70 | 71 | /** 72 | * Get magnetic declination for a time and location 73 | * 74 | * @param glat Latitude in degrees and fraction degrees, negative for south, 0-90 75 | * @param glon Longitude in degrees and fraction degrees, negative for west, -180 to 180 76 | * @param time_years Time in years and fractional years 77 | * @param dec Pointer to float for result, declination in degrees, west negative 78 | */ 79 | void E0000(float glat, float glon, float time_years, float *dec); 80 | 81 | /** 82 | * Initialize the model. Call once before calling other functions 83 | */ 84 | void wmm_init(void); 85 | 86 | /** 87 | * Get the date in the years and fractional years 88 | * 89 | * @param year 2 digit format 90 | * @param month 1-12 91 | * @param date 1-31 92 | * @return Date in years and fractional years 93 | */ 94 | float wmm_get_date(uint8_t year, uint8_t month, uint8_t date); 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /components/n2klib/include/NMEA2000_CompilerDefns.h: -------------------------------------------------------------------------------- 1 | /* 2 | NMEA2000_CompilerDefns.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | 24 | */ 25 | 26 | /* 27 | As default NMEA 2000 library will have all NMEA 2000 mandatory features automatically enabled. 28 | Some rarely used or new requirements takes so much memory, that you may want to leave 29 | them away. Arduino IDE does not have possibility to define compiler definitions on 30 | project, so here is sample file, where you can disable some features and save memory. 31 | Note that YOU SHOULD NEWER UPDATE this file to the library with definitions enabled! If 32 | you want to change any definitions inside, copy this file under you libraries to e.g. 33 | path NMEA2000_my and remove it from downloaded NMEA2000 library path. 34 | 35 | 36 | */ 37 | 38 | #ifndef _NMEA2000_COMPILER_DEFNS_H_ 39 | #define _NMEA2000_COMPILER_DEFNS_H_ 40 | 41 | // ISO Multipacket is a other way to send long messages instead of NMEA 2000 fastpacket. 42 | // Normally NMEA 2000 devices communicates by using fastpacket, but this is mandatory 43 | // for certified NMEA 2000 devices. 44 | // This uses appr. 2 kB of rom. No measured ram effect. 45 | // #define N2K_NO_ISO_MULTI_PACKET_SUPPORT 1 // Uncomment this, if you do not need ISO Multi-packet support 46 | 47 | // Group functions has been used to control different settings. Mandatory default handlers sets heartbeat interval 48 | // and node "name" device instance lower, upper and system instance values. 49 | // This uses appr. 4 kB of rom and 100 B ram 50 | // #define N2K_NO_GROUP_FUNCTION_SUPPORT 1 // Uncomment this, if you do not need Group Function support 51 | 52 | // Heartbeat is new way to other devices see that node is alive. Support for this has been slowly 53 | // implemented to new firmwares. Since this is new feature I'll expect it takes time before 54 | // e.g. MFD:s can rely this. 55 | // This uses appr. 0.5 kB of rom. No measured ram effect. 56 | // #define N2K_NO_HEARTBEAT_SUPPORT 1 // Uncomment this, if you do not want device to send heartbeat 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /app/app/src/main/java/com/example/bluebridgeapp/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) John Blaiklock 2022 BlueBridge 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | package com.example.bluebridgeapp; 26 | 27 | import android.app.Activity; 28 | import android.view.inputmethod.InputMethodManager; 29 | 30 | public class Utils { 31 | public final static float DEGREES_TO_RADS = 57.296f; 32 | 33 | /** 34 | * Calculate distance in metres between 2 points coordinates in degrees 35 | * 36 | * @param lat1 Latitude of first point in degrees 37 | * @param long1 longitude of first point in degrees 38 | * @param lat2 Latitude of second point in degrees 39 | * @param long2 longitude of second point in degrees 40 | * @return Distance between points in m 41 | * */ 42 | public static float DistanceBetweenPoints(float lat1, float long1, float lat2, float long2) 43 | { 44 | float half_dlat; 45 | float half_dlong; 46 | float a; 47 | float c; 48 | 49 | lat1 /= DEGREES_TO_RADS; 50 | long1 /= DEGREES_TO_RADS; 51 | lat2 /= DEGREES_TO_RADS; 52 | long2 /= DEGREES_TO_RADS; 53 | half_dlat = (lat2 - lat1) / 2.0f; 54 | half_dlong = (long2 - long1) / 2.0f; 55 | a = (float)(Math.sin(half_dlat) * Math.sin(half_dlat) + Math.sin(half_dlong) * Math.sin(half_dlong) * Math.cos(lat1) * Math.cos(lat2)); 56 | c = 2.0f * (float)(Math.atan2(Math.sqrt(a), Math.sqrt(1.0f - a))); 57 | 58 | return 6371000.0f * c; 59 | } 60 | 61 | /** 62 | * Hide the soft keyboard shown when text input is expected 63 | * 64 | * @param activity The activity owning the input control corresponding to the soft keyboard 65 | */ 66 | public static void hideSoftKeyboard(Activity activity) { 67 | InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); 68 | if (activity.getCurrentFocus() != null) { 69 | if (inputMethodManager.isAcceptingText()) { 70 | inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(),0); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /main/serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef SERIAL_H 28 | #define SERIAL_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | #include 40 | 41 | /************** 42 | *** DEFINES *** 43 | **************/ 44 | 45 | /************ 46 | *** TYPES *** 47 | ************/ 48 | 49 | /************************* 50 | *** EXTERNAL VARIABLES *** 51 | *************************/ 52 | 53 | /*************************** 54 | *** FUNCTIONS PROTOTYPES *** 55 | ***************************/ 56 | 57 | /** 58 | * Initialize the serial ports, call this once at startuo before using any other functions 59 | * 60 | * @param baud_rate_1 Baud rate to use to initialize serial port 1 61 | * @param baud_rate_2 Baud rate to use to initialize serial port 2 62 | */ 63 | void serial_init(uint32_t baud_rate_1, uint32_t baud_rate_2); 64 | 65 | /** 66 | * Read data from serial port 1 67 | * 68 | * @param buffer_length The length of the supplied buffer 69 | * @param data The buffer to read data into 70 | * @return How many bytes were read 71 | */ 72 | size_t serial_1_read_data(size_t buffer_length, uint8_t *data); 73 | 74 | /** 75 | * Write data to serial port 1 76 | * 77 | * @param length The length of data 78 | * @param data The data to write 79 | * @return How many bytes were written 80 | */ 81 | size_t serial_1_send_data(size_t length, const uint8_t *data); 82 | 83 | /** 84 | * Read data from serial port 2 85 | * 86 | * @param buffer_length The length of the supplied buffer 87 | * @param data The buffer to read data into 88 | * @return How many bytes were read 89 | */ 90 | size_t serial_2_read_data(size_t buffer_length, uint8_t *data); 91 | 92 | /** 93 | * Write data to serial port 2 94 | * 95 | * @param length The length of data 96 | * @param data The data to write 97 | * @return How many bytes were written 98 | */ 99 | size_t serial_2_send_data(size_t length, const uint8_t *data); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /components/n2klib/include/NMEA2000_esp32.h: -------------------------------------------------------------------------------- 1 | /* 2 | NMEA2000_esp32.h 3 | 4 | Copyright (c) 2015-2020 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | Inherited NMEA2000 object for ESP32 modules. See also NMEA2000 library. 24 | 25 | Thanks to Thomas Barth, barth-dev.de, who has written ESP32 CAN code. To avoid extra 26 | libraries, I implemented his code directly to the NMEA2000_esp32 to avoid extra 27 | can.h library, which may cause even naming problem. 28 | 29 | The library sets as default CAN Tx pin to GPIO 16 and CAN Rx pint to GPIO 4. If you 30 | want to use other pins (I have not tested can any pins be used), add defines e.g. 31 | #define ESP32_CAN_TX_PIN GPIO_NUM_34 32 | #define ESP32_CAN_RX_PIN GPIO_NUM_35 33 | before including NMEA2000_esp32.h or NMEA2000_CAN.h 34 | */ 35 | 36 | #ifndef _NMEA2000_ESP32_H_ 37 | #define _NMEA2000_ESP32_H_ 38 | 39 | #include "freertos/FreeRTOS.h" 40 | #include "freertos/queue.h" 41 | #include "driver/gpio.h" 42 | #include "NMEA2000.h" 43 | #include "N2kMsg.h" 44 | #include "ESP32_CAN_def.h" 45 | 46 | #ifndef ESP32_CAN_TX_PIN 47 | #define ESP32_CAN_TX_PIN GPIO_NUM_5 48 | #endif 49 | #ifndef ESP32_CAN_RX_PIN 50 | #define ESP32_CAN_RX_PIN GPIO_NUM_4 51 | #endif 52 | 53 | class tNMEA2000_esp32 : public tNMEA2000 54 | { 55 | private: 56 | bool IsOpen; 57 | static bool CanInUse; 58 | 59 | protected: 60 | struct tCANFrame { 61 | uint32_t id; // can identifier 62 | uint8_t len; // length of data 63 | uint8_t buf[8]; 64 | }; 65 | 66 | protected: 67 | CAN_speed_t speed; 68 | gpio_num_t TxPin; 69 | gpio_num_t RxPin; 70 | QueueHandle_t RxQueue; 71 | QueueHandle_t TxQueue; 72 | 73 | protected: 74 | void CAN_read_frame(); // Read frame to queue within interrupt 75 | void CAN_send_frame(tCANFrame &frame); // Send frame 76 | void CAN_init(); 77 | 78 | protected: 79 | bool CANSendFrame(unsigned long id, unsigned char len, const unsigned char *buf, bool wait_sent=true); 80 | bool CANOpen(); 81 | bool CANGetFrame(unsigned long &id, unsigned char &len, unsigned char *buf); 82 | virtual void InitCANFrameBuffers(); 83 | 84 | public: 85 | tNMEA2000_esp32(gpio_num_t _TxPin=ESP32_CAN_TX_PIN, gpio_num_t _RxPin=ESP32_CAN_RX_PIN); 86 | 87 | void InterruptHandler(); 88 | }; 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /components/n2klib/include/ActisenseReader.h: -------------------------------------------------------------------------------- 1 | /* 2 | ActisenseReader.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | 24 | This is class for reading Actisense format messages from given stream. 25 | 26 | There is unresolved problem to use programming port with reading data. 27 | Read works fine for a while, but then stops. With e.g. Arduino Due 28 | USB port there is no problem. 29 | */ 30 | #ifndef _ACTISENSE_READER_H_ 31 | #define _ACTISENSE_READER_H_ 32 | 33 | #include "N2kMsg.h" 34 | #include "N2kStream.h" 35 | 36 | class tActisenseReader 37 | { 38 | protected: 39 | #define MAX_STREAM_MSG_BUF_LEN 300 40 | bool StartOfTextReceived; 41 | bool MsgIsComing; 42 | bool EscapeReceived; 43 | int byteSum; 44 | // Buffer for incoming messages from stream 45 | unsigned char MsgBuf[MAX_STREAM_MSG_BUF_LEN]; 46 | int MsgWritePos; 47 | unsigned char DefaultSource; 48 | 49 | protected: 50 | N2kStream* ReadStream; 51 | // Handler callback 52 | void (*MsgHandler)(const tN2kMsg &N2kMsg); 53 | 54 | protected: 55 | bool AddByteToBuffer(char NewByte); 56 | void ClearBuffer(); 57 | bool CheckMessage(tN2kMsg &N2kMsg); 58 | 59 | public: 60 | tActisenseReader(); 61 | // Set stream, which would be used for reading messages. You have to 62 | // open stream first, so e.g. for SerialUSB call begin first. 63 | void SetReadStream(N2kStream* _stream) { ReadStream=_stream; } 64 | 65 | // If you use application, which sends data by using Actisense data request type, source 66 | // set by this function will be set as source. Default=65; 67 | void SetDefaultSource(unsigned char source) { DefaultSource=source; } 68 | 69 | // You can either call this or ParseMessages periodically. 70 | bool GetMessageFromStream(tN2kMsg &N2kMsg, bool ReadOut=true); 71 | 72 | bool IsStart(char ch); 73 | // Set message handler with SetMsgHandler and then call this periodically or use GetMessageFromStream 74 | void ParseMessages(); 75 | // Set message handler to be used in ParseMessages, when message has been received. 76 | void SetMsgHandler(void (*_MsgHandler)(const tN2kMsg &N2kMsg)) { MsgHandler=_MsgHandler; } 77 | 78 | bool Handling() const { return MsgIsComing || EscapeReceived || StartOfTextReceived; } 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /main/sms.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef SMS_H 28 | #define SMS_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | #include 40 | 41 | /************** 42 | *** DEFINES *** 43 | **************/ 44 | 45 | #define SMS_MAX_PHONE_NUMBER_LENGTH 24UL ///< Maximum number of characters in a phone number including international part 46 | 47 | /************ 48 | *** TYPES *** 49 | ************/ 50 | 51 | /************************* 52 | *** EXTERNAL VARIABLES *** 53 | *************************/ 54 | 55 | /*************************** 56 | *** FUNCTIONS PROTOTYPES *** 57 | ***************************/ 58 | 59 | /** 60 | * Initialize the SMS library. Call once before using other functions. 61 | */ 62 | void sms_init(void); 63 | 64 | /** 65 | * Check if there is a waiting SMS message and get its id if there is. 66 | * 67 | * @param sms_id Pointer to where the id of a waiting message will be saved. 68 | * @return true if there is a waiting message or false if not or sms_id is NULL. 69 | * @note If there is no waiting message then sms_id will not be changed. 70 | */ 71 | bool sms_check_for_new(uint32_t *sms_id); 72 | 73 | /** 74 | * Retrieve a received SMS message of known id 75 | * 76 | * @param sms_id The id of the message as previously obtained from sms_check_for_new(). 77 | * @param phone_number Pointer to buffer that will contain the sender's phone number of a received message. 78 | * @param phone_number_buffer_length The length in bytes of phone_number 79 | * @param message_text Pointer to buffer that will contained the received message text 80 | * @param message_text_buffer_length The length in bytes of message_text 81 | */ 82 | bool sms_receive(uint32_t sms_id, char *phone_number, size_t phone_number_buffer_length, char *message_text, size_t message_text_buffer_length); 83 | 84 | /** 85 | * Send a SMS message 86 | * 87 | * @param message_text The text of the message to send. Only up to 160 characters will be sent. 88 | * @param phone_number The phone number of the recipient. 89 | */ 90 | bool sms_send(const char *message_text, const char *phone_number); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | #endif -------------------------------------------------------------------------------- /main/led.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include "driver/gpio.h" 32 | #include "freertos/FreeRTOS.h" 33 | #include "freertos/timers.h" 34 | #include "led.h" 35 | 36 | /************** 37 | *** DEFINES *** 38 | **************/ 39 | 40 | /************ 41 | *** TYPES *** 42 | ************/ 43 | 44 | /******************************** 45 | *** LOCAL FUNCTION PROTOTYPES *** 46 | ********************************/ 47 | 48 | static void led_timer_callback(xTimerHandle pxTimer); 49 | 50 | /********************** 51 | *** LOCAL VARIABLES *** 52 | **********************/ 53 | 54 | static xTimerHandle timer_led; ///< Timer for the LED flash duration 55 | static uint32_t current_period; ///< Duration of the current flash set to 0 when flash finished 56 | 57 | /*********************** 58 | *** GLOBAL VARIABLES *** 59 | ***********************/ 60 | 61 | /**************** 62 | *** CONSTANTS *** 63 | ****************/ 64 | 65 | /********************** 66 | *** LOCAL FUNCTIONS *** 67 | **********************/ 68 | 69 | /** 70 | * Timer callback called when the LED flash ends and needs to be switched off 71 | * 72 | * @param pxTimer Unused 73 | */ 74 | static void led_timer_callback(xTimerHandle pxTimer) 75 | { 76 | (void)pxTimer; 77 | 78 | gpio_set_level(GPIO_NUM_17, 0UL); 79 | current_period = 0UL; 80 | } 81 | 82 | /*********************** 83 | *** GLOBAL FUNCTIONS *** 84 | ***********************/ 85 | 86 | void led_init(void) 87 | { 88 | gpio_config_t io_conf = {}; 89 | io_conf.intr_type = GPIO_INTR_DISABLE; 90 | io_conf.mode = GPIO_MODE_OUTPUT; 91 | io_conf.pin_bit_mask = 1ULL << GPIO_NUM_17; 92 | io_conf.pull_down_en = 0; 93 | io_conf.pull_up_en = 0; 94 | gpio_config(&io_conf); 95 | 96 | gpio_set_level(GPIO_NUM_17, 0UL); 97 | 98 | timer_led = xTimerCreate("timerled", pdMS_TO_TICKS(1000), pdFALSE, (void*)0, led_timer_callback); 99 | } 100 | 101 | void led_flash(uint32_t ms) 102 | { 103 | if (timer_led != NULL && ms > 0UL) 104 | { 105 | if (ms > current_period) 106 | { 107 | current_period = ms; 108 | 109 | (void)xTimerStop(timer_led, (TickType_t)0); 110 | (void)xTimerChangePeriod(timer_led, pdMS_TO_TICKS(ms), (TickType_t)0); 111 | (void)xTimerStart(timer_led, (TickType_t)0); 112 | gpio_set_level(GPIO_NUM_17, 1UL); 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /main/spp_acceptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | This work is based on code in file BluetoothSerial.cpp distributed as part of 26 | the ESP32 driver layer of the Arduino library for the ESP32 platform. The 27 | license for the source code is given below: 28 | 29 | // Copyright 2018 Evandro Luis Copercini 30 | // 31 | // Licensed under the Apache License, Version 2.0 (the "License"); 32 | // you may not use this file except in compliance with the License. 33 | // You may obtain a copy of the License at 34 | // 35 | // http://www.apache.org/licenses/LICENSE-2.0 36 | // 37 | // Unless required by applicable law or agreed to in writing, software 38 | // distributed under the License is distributed on an "AS IS" BASIS, 39 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | // See the License for the specific language governing permissions and 41 | // limitations under the License. 42 | 43 | The above source code has been modified to enable it to build directly 44 | with the ESP32-IDF framework. 45 | 46 | */ 47 | 48 | #ifndef SPP_ACCEPTOR_H 49 | #define SPP_ACCEPTOR_H 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | /*************** 56 | *** INCLUDES *** 57 | ***************/ 58 | 59 | #include 60 | 61 | /************** 62 | *** DEFINES *** 63 | **************/ 64 | 65 | /************ 66 | *** TYPES *** 67 | ************/ 68 | 69 | /************************* 70 | *** EXTERNAL VARIABLES *** 71 | *************************/ 72 | 73 | /*************************** 74 | *** FUNCTIONS PROTOTYPES *** 75 | ***************************/ 76 | 77 | /** 78 | * Initialize the serial port profile Bluetooth driver 79 | */ 80 | void spp_init(void); 81 | 82 | /** 83 | * Write data using the Bluetooth serial port profile driver 84 | * 85 | * @param buffer The data to write 86 | * @param size The length of data in buffer 87 | * @return How many bytes were written 88 | */ 89 | size_t spp_write(const uint8_t *buffer, size_t size); 90 | 91 | /** 92 | * Read a single byte using the Bluetooth serial port profile driver 93 | * 94 | * @return The byte read or -1 if not possible 95 | */ 96 | int spp_read(void); 97 | 98 | /** 99 | * Get the length of data to read from the Bluetooth serial port profile connection 100 | * 101 | * @return Bytes waiting to be read 102 | */ 103 | size_t spp_bytes_received_size(void); 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 |

Blue Bridge

5 |

6 | 7 |

8 | 9 | The Blue Bridge project is a hardware device, embedded software, an Android application and a webpage for sharing of boat data to allow remote monitoring and anchor watching. Boat data are received from the boat's instruments via NMEA2000 and NMEA0183 connections and are then distributed via Bluetooth to local recipients or via the internet for remote recipients with internet access. Also included in the hardware are: an atmospheric pressure sensor which is shared both with the data recipients via Bluetooth and the internet and also the boat's NMEA2000 data network, and connections for a pair of PT-1000 sensors which measure the temperature inside 2 exhaust gas pipes the values of which are distrubted via NMEA2000. 10 | 11 | For local recipients the boat data are converted to NMEA0183 format and sent via a Bluetooth link to a local device. This could be a laptop, tablet or phone running a navigation software package (the format of the data are tailored for OpenCPN but will work with other navigation packages). Another recipient of the boat data over Bluetooth can be the Android anchor watching app that is part of this project. 12 | 13 | For remote recipients the boat data are sent out using a GSM modem with a data connection to a server on the internet. This server is a MQTT broker from which other internet connected devices can receive the data. Remote recipients of the data can be a webpage included as part of this project or the same Android anchor watching app mentioned above using an internet connection rather than a Bluetooth one. This allows remote monitoring of the boat's instruments and position using the webpage or 14 | remote anchor watching using the Android application. 15 | 16 | The diagram above shows the various connections. The hardware device has no user interface so is configured via SMS messages from any mobile phone. Details of these messages are under the docs folder. 17 | 18 | This is the webpage that is found under the webpage folder above: 19 |
20 | http://miniwinwm.000webhostapp.com/ 21 |

22 | This is the Android anchor watching app found under the app folder above built with Android Studio: 23 |

24 | 25 |

26 |
27 | This project using custom hardware running an ESP32 based DevKitC board. In addition to this are the following daughter boards: a BMP280 pressure sensor board, a SIM800L GSM modem board and a modem power supply board. The schematic and PCB layout are created in DesignSpark from RS. All hardware design files are found under the hw folder above. This is the hardware as assembled: 28 |

29 | 30 |

31 | Software development for the ESP32 is done using the Espressif ESP-IDF development environment. Currently the following data items are received by the NMEA2000 connection: depth, log, trip, boatspeed, wind direction, wind speed, GPS position, SoG, CoG, water temperature. The following data items are recived by the NMEA0183 connection: GPS position, SoG, CoG, AIS data. Either interface could be extended to receive further data items. 32 |

33 | This project has now reached first release and has been tested on a boat with a Raymarine NMEA2000/STNG based system. Bug fixing and minor changes and feature additions may still occur. To see a list of outstanding work and changes to come see todo.txt. 34 |

35 | Future additions: The latest hardware design has the option of fitting a RF transceiver module. This could be used to implement communication with a wireless remote control for an autopilot. 36 | -------------------------------------------------------------------------------- /main/serial.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include "driver/uart.h" 32 | #include "driver/gpio.h" 33 | #include "serial.h" 34 | #include "spp_acceptor.h" 35 | 36 | /************** 37 | *** DEFINES *** 38 | **************/ 39 | 40 | /************ 41 | *** TYPES *** 42 | ************/ 43 | 44 | /******************************** 45 | *** LOCAL FUNCTION PROTOTYPES *** 46 | ********************************/ 47 | 48 | /********************** 49 | *** LOCAL VARIABLES *** 50 | **********************/ 51 | 52 | /*********************** 53 | *** GLOBAL VARIABLES *** 54 | ***********************/ 55 | 56 | /**************** 57 | *** CONSTANTS *** 58 | ****************/ 59 | 60 | /********************** 61 | *** LOCAL FUNCTIONS *** 62 | **********************/ 63 | 64 | /*********************** 65 | *** GLOBAL FUNCTIONS *** 66 | ***********************/ 67 | 68 | void serial_init(uint32_t baud_rate_1, uint32_t baud_rate_2) 69 | { 70 | (void)baud_rate_2; 71 | 72 | spp_init(); 73 | 74 | uart_config_t uart_config = 75 | { 76 | .baud_rate = baud_rate_1, 77 | .data_bits = UART_DATA_8_BITS, 78 | .parity = UART_PARITY_DISABLE, 79 | .stop_bits = UART_STOP_BITS_1, 80 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, 81 | .source_clk = UART_SCLK_APB, 82 | }; 83 | 84 | uart_driver_install(UART_NUM_2, 2048, 2048, 0, NULL, 0); 85 | uart_param_config(UART_NUM_2, &uart_config); 86 | uart_set_pin(UART_NUM_2, GPIO_NUM_17, GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); 87 | } 88 | 89 | size_t serial_1_send_data(size_t length, const uint8_t *data) 90 | { 91 | return (size_t)uart_tx_chars(UART_NUM_2, (const char *)data, (uint32_t)length); 92 | } 93 | 94 | size_t serial_1_read_data(size_t buffer_length, uint8_t *data) 95 | { 96 | size_t bytes_available; 97 | size_t bytes_read; 98 | 99 | uart_get_buffered_data_len(UART_NUM_2, &bytes_available); 100 | 101 | if (bytes_available <= buffer_length) 102 | { 103 | bytes_read = (size_t)uart_read_bytes(UART_NUM_2, (void *)data, (uint32_t)bytes_available, (TickType_t)1); 104 | } 105 | else 106 | { 107 | bytes_read = (size_t)uart_read_bytes(UART_NUM_2, (void *)data, (uint32_t)buffer_length, (TickType_t)1); 108 | } 109 | 110 | return bytes_read; 111 | } 112 | 113 | size_t serial_2_send_data(size_t length, const uint8_t *data) 114 | { 115 | spp_write(data, length); 116 | 117 | return length; 118 | } 119 | 120 | size_t serial_2_read_data(size_t buffer_length, uint8_t *data) 121 | { 122 | size_t bytes_available; 123 | size_t bytes_to_read; 124 | size_t i; 125 | int result; 126 | 127 | bytes_available = spp_bytes_received_size(); 128 | 129 | if (bytes_available <= buffer_length) 130 | { 131 | bytes_to_read = bytes_available; 132 | } 133 | else 134 | { 135 | bytes_to_read = buffer_length; 136 | } 137 | 138 | for (i = (size_t)0; i < bytes_to_read; i++) 139 | { 140 | result = spp_read(); 141 | if (result == -1) 142 | { 143 | return i; 144 | } 145 | 146 | data[i] = (uint8_t)result; 147 | } 148 | 149 | return bytes_to_read; 150 | } 151 | -------------------------------------------------------------------------------- /main/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef UTIL_H 28 | #define UTIL_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /*************** 35 | *** INCLUDES *** 36 | ***************/ 37 | 38 | #include 39 | #include 40 | 41 | /************** 42 | *** DEFINES *** 43 | **************/ 44 | 45 | /************ 46 | *** TYPES *** 47 | ************/ 48 | 49 | /************************* 50 | *** EXTERNAL VARIABLES *** 51 | *************************/ 52 | 53 | /*************************** 54 | *** FUNCTIONS PROTOTYPES *** 55 | ***************************/ 56 | 57 | /** 58 | * Remove traiing whitespace from a string 59 | * 60 | * @param str The string to remove trailing whitespace from 61 | */ 62 | void trim_trailing_ws(char *str); 63 | 64 | /** 65 | * Convert a hex number in upper or lower case to an int. No leading 0x. 66 | * 67 | * @param s The string containing the hex number 68 | * @return The converted number 69 | */ 70 | uint32_t util_htoi(const char *s); 71 | 72 | /** 73 | * Replace every instance of a character in a string with another 74 | * 75 | * @param s The string to replace characters in 76 | * @param orig The character to replace 77 | * @param rep The character to replace with 78 | */ 79 | void util_replace_char(char *s, char orig, char rep); 80 | 81 | /** 82 | * Replace each lower case character with its upper case equivalent 83 | * 84 | * @param s String contaiining the characters to check and replace 85 | * @return The inpur string or NULL if the input string is NULL 86 | */ 87 | char *util_capitalize_string(char *s); 88 | 89 | /** 90 | * Convert a seconds value to a text representation in format xxhyymzzs 91 | * 92 | * @param seconds The input time to convert in seconds 93 | * @return The converted text value 94 | * @note This function is not thread safer 95 | */ 96 | char *util_seconds_to_hms(uint32_t seconds); 97 | 98 | /** 99 | * Parse a text hour/minute/second value in xxhyymzzs format to an integer of the total number of seconds 100 | * 101 | * @param hms String containing the value to convert. Must contain at least a number and an h, m or s. The letters h, m and s must be in that order. 102 | * @param result Pointer to value to hold result 103 | * @return If successful true else false 104 | */ 105 | bool util_hms_to_seconds(const char *hms, uint32_t *result); 106 | 107 | /** 108 | * Simple hash function of ASCII string using the DJB2 algorithm 109 | * 110 | * @param str The string to hash 111 | * @return The hash value 112 | */ 113 | uint32_t util_hash_djb2(const char *str); 114 | 115 | /** 116 | * Perform a safe equivalent of strcat 117 | * 118 | * @param dest Buffer to hold the concatenated string 119 | * @param size Size in bytes of dest 120 | * @param src The source string to append to what already exists in dest 121 | * @return true if string concatenated successfully 122 | */ 123 | bool util_safe_strcat(char *dest, size_t size, const char *src); 124 | 125 | /** 126 | * Perform a safe equivalent of strcpy. 127 | * 128 | * @param dest Pointer to destination string 129 | * @param size The size of the dest buffer 130 | * @param src Pointer to source string to copy 131 | */ 132 | bool util_safe_strcpy(char *dest, size_t size, const char *src); 133 | 134 | #ifdef __cplusplus 135 | } 136 | #endif 137 | 138 | #endif -------------------------------------------------------------------------------- /main/property_parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include 32 | #include "property_parser.h" 33 | 34 | /************** 35 | *** DEFINES *** 36 | **************/ 37 | 38 | /************ 39 | *** TYPES *** 40 | ************/ 41 | 42 | /** 43 | * Parser state machine states 44 | */ 45 | typedef enum 46 | { 47 | NOT_STARTED, ///< Not started in a new key/value or command 48 | IN_KEY, ///< In a key or command 49 | RECEIVED_EQUALS, ///< Received a = between key and value 50 | IN_VALUE, ///< In a value 51 | } parse_state_t; 52 | 53 | /******************************** 54 | *** LOCAL FUNCTION PROTOTYPES *** 55 | ********************************/ 56 | 57 | /********************** 58 | *** LOCAL VARIABLES *** 59 | **********************/ 60 | 61 | /*********************** 62 | *** GLOBAL VARIABLES *** 63 | ***********************/ 64 | 65 | /**************** 66 | *** CONSTANTS *** 67 | ****************/ 68 | 69 | /********************** 70 | *** LOCAL FUNCTIONS *** 71 | **********************/ 72 | 73 | /*********************** 74 | *** GLOBAL FUNCTIONS *** 75 | ***********************/ 76 | 77 | uint16_t property_parse(char *str, parser_callback_t parser_callback) 78 | { 79 | char *key = ""; 80 | char *value = ""; 81 | uint16_t c; 82 | parse_state_t parse_state; 83 | uint16_t found = 0U; 84 | 85 | if (str == NULL || parser_callback == NULL) 86 | { 87 | return 0U; 88 | } 89 | 90 | size_t len = strlen(str); 91 | 92 | if (len == (size_t)0) 93 | { 94 | return 0U; 95 | } 96 | 97 | c = 0U; 98 | parse_state = NOT_STARTED; 99 | while (true) 100 | { 101 | if (c == len) 102 | { 103 | break; 104 | } 105 | 106 | if (parse_state == NOT_STARTED) 107 | { 108 | if (str[c] == '=' || str[c] == '\r' || str[c] == '\n') 109 | { 110 | c++; 111 | continue; 112 | } 113 | 114 | key = &str[c]; 115 | parse_state = IN_KEY; 116 | c++; 117 | continue; 118 | } 119 | else if (parse_state == IN_KEY) 120 | { 121 | if (str[c] == '\r' || str[c] == '\n') 122 | { 123 | parse_state = NOT_STARTED; 124 | str[c] = '\0'; 125 | 126 | if (strlen(key) > (size_t)0) 127 | { 128 | found++; 129 | parser_callback(key, ""); 130 | } 131 | key = ""; 132 | } 133 | else if (str[c] == '=') 134 | { 135 | str[c] = '\0'; 136 | parse_state = RECEIVED_EQUALS; 137 | } 138 | c++; 139 | continue; 140 | } 141 | else if (parse_state == RECEIVED_EQUALS) 142 | { 143 | if (str[c] == '\n' || str[c] == '\r') 144 | { 145 | key = ""; 146 | parse_state = NOT_STARTED; 147 | } 148 | else 149 | { 150 | parse_state = IN_VALUE; 151 | value = &str[c]; 152 | } 153 | c++; 154 | continue; 155 | } 156 | else if (parse_state == IN_VALUE) 157 | { 158 | if (str[c] == '\r' || str[c] == '\n') 159 | { 160 | parse_state = NOT_STARTED; 161 | str[c] = '\0'; 162 | 163 | if (strlen(key) > (size_t)0 && strlen(value) > (size_t)0) 164 | { 165 | found++; 166 | parser_callback(key, value); 167 | } 168 | 169 | key = ""; 170 | value = ""; 171 | } 172 | c++; 173 | continue; 174 | } 175 | } 176 | 177 | if (strlen(key) > (size_t)0) 178 | { 179 | if (parser_callback(key, value)) 180 | { 181 | found++; 182 | } 183 | } 184 | 185 | return found; 186 | } -------------------------------------------------------------------------------- /components/n2klib/include/RingBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | RingBuffer.h 3 | 4 | Copyright (c) 2020-2021 Timo Lappalainen 5 | 6 | The MIT License 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Simple tRingBuffer and tPriorityRingBuffer template classes. 27 | 28 | With tRingBuffer one can save simple data structures to ring buffer. 29 | Note that you have to take care of data locking from other threads or interrupts for copy time. 30 | E.g. 31 | 32 | struct tCANData { 33 | uint32_t id; 34 | uint8_t len; 35 | uint8_t data[8]; 36 | }; 37 | 38 | tPriorityRingBuffer CANMessages(100); 39 | ... 40 | void SendMessage() { 41 | tCANData msgOut; 42 | msgOut.id=1; 43 | msgOut.len=1; 44 | msgOut.data[0]=1; 45 | lockData(); 46 | CANMessages.add(msgOut); 47 | releaseData(); 48 | } 49 | 50 | As an alternative if you want to avoid data copying twice, you can request reference to next 51 | data to be saved and copy data directly to it. 52 | 53 | void SendMessage() { 54 | tCANData *msgOut; 55 | lockData(); 56 | if ( (msgOut=CANMessages)!=0 ) { 57 | msgOut->id=1; 58 | msgOut->len=1; 59 | msgOut->data[0]=1; 60 | } 61 | releaseData(); 62 | } 63 | 64 | tPriorityRingBuffer is similar as tRingBuffer, but it extends functionality with item priority. When you add 65 | items to buffer, you can give them priority and when you read them, highest priority item will be read out 66 | first. 67 | */ 68 | 69 | #ifndef _RING_BUFFER_H_ 70 | #define _RING_BUFFER_H_ 71 | 72 | #include 73 | 74 | template class tRingBuffer { 75 | 76 | protected: 77 | T *buffer; 78 | uint16_t head; 79 | uint16_t tail; 80 | uint16_t size; 81 | 82 | public: 83 | tRingBuffer(uint16_t _size); 84 | virtual ~tRingBuffer(); 85 | uint16_t getSize() const { return size; } 86 | bool isEmpty() const; 87 | void clear(); 88 | uint16_t count(); 89 | // Get pointer to next add item if available. 90 | T *getAddRef(); 91 | bool add(const T &val); 92 | // Get pointer to next read item if available. 93 | const T *getReadRef(); 94 | bool read(T &val); 95 | }; 96 | 97 | template class tPriorityRingBuffer { 98 | protected: 99 | #define INVALID_RING_REF (uint16_t)(-1) 100 | #define INVALID_PRIORITY_REF (uint8_t)(-1) 101 | 102 | struct tValueSlot { 103 | T Value; 104 | uint16_t next; 105 | uint8_t priority; 106 | }; 107 | 108 | struct tPriorityRef { 109 | uint16_t next; 110 | uint16_t last; 111 | tPriorityRef() : next(INVALID_RING_REF), last(INVALID_RING_REF) {;} 112 | void clear() { next=INVALID_RING_REF; last=INVALID_RING_REF; } 113 | }; 114 | protected: 115 | uint16_t head; 116 | uint16_t tail; 117 | uint16_t size; 118 | uint8_t maxPriorities; 119 | tValueSlot *buffer; 120 | tPriorityRef *priorityReferencies; 121 | 122 | public: 123 | tPriorityRingBuffer(uint16_t _size, uint8_t _maxPriorities=1); 124 | virtual ~tPriorityRingBuffer(); 125 | uint16_t getSize() const { return size; } 126 | bool isEmpty(uint8_t _priority=0xff) const; 127 | void clear(); 128 | void clean(); 129 | uint16_t count(); 130 | 131 | bool add(const T &val, uint8_t _priority=0); 132 | bool read(T &val); 133 | 134 | T *getAddRef(uint8_t _priority=0); 135 | const T *getReadRef(uint8_t _priority); 136 | // Get reference to highest available. 137 | const T *getReadRef(uint8_t *_priority=0); 138 | }; 139 | 140 | 141 | #include "RingBuffer.tpp" 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /main/WMM_COF.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include 32 | 33 | /************** 34 | *** DEFINES *** 35 | **************/ 36 | 37 | /************ 38 | *** TYPES *** 39 | ************/ 40 | 41 | /******************************** 42 | *** LOCAL FUNCTION PROTOTYPES *** 43 | ********************************/ 44 | 45 | /********************** 46 | *** LOCAL VARIABLES *** 47 | **********************/ 48 | 49 | /*********************** 50 | *** GLOBAL VARIABLES *** 51 | ***********************/ 52 | 53 | /**************** 54 | *** CONSTANTS *** 55 | ****************/ 56 | 57 | /** 58 | * Variable length integer encoded WMM coefficients table 59 | */ 60 | const uint8_t wmm_cof_entries_encoded[] = 61 | {0xDD, 0xF2, 0x23, 0x00, 0x83, 0x01, 0x00, 0xEB, 0xE2, 0x01, 0x81, 0xD7, 0x05, 0x8D, 0x01, 0xFB, 0x03, 0xE8, 0x86, 0x03, 0x00, 0xF3, 0x01, 0x00, 0xBC, 0xD1, 0x03, 0xDC, 0xD3, 0x03, 0xC7, 0x01, 0xEE, 0x04, 0x80, 0x86, 0x02, 0xF4, 0x72, 0x56, 0xEF, 0x03, 0x87, 0xD5, 0x01, 0x00, 0x1C, 0x00, 0xC2, 0xF4, 0x02, 0xF6, 0x0C, 0x7E, 0x39, 0x8A, 0xC1, 0x01, 0xB2, 0x25, 0x22, 0x4A, 0x89, 0x52, 0xF5, 0x54, 0xFA, 0x01, 0x0B, 0x87, 0x8D, 0x01, 0x00, 0x4B, 0x00, 0x9E, 0x7E, 0x84, 0x2C, 0x50, 0x02, 0x9E, 0x0D, 0xF0, 0x18, 0x7C, 0x85, 0x01, 0xD6, 0x30, 0x8E, 0x1F, 0x36, 0x25, 0x9F, 0x07, 0xED, 0x36, 0x77, 0x78, 0xE8, 0x24, 0x00, 0x43, 0x00, 0xAF, 0x38, 0x9D, 0x07, 0x06, 0x01, 0x96, 0x1D, 0xA4, 0x20, 0x47, 0x19, 0xFF, 0x15, 0xFD, 0x12, 0x01, 0x49, 0xE8, 0x17, 0x82, 0x05, 0x0C, 0x1E, 0x89, 0x02, 0x9F, 0x0F, 0x0A, 0x05, 0x93, 0x0A, 0x00, 0x46, 0x00, 0x90, 0x0A, 0xFF, 0x02, 0x44, 0x01, 0x9A, 0x0B, 0xBA, 0x03, 0x05, 0x52, 0xFF, 0x12, 0x8F, 0x08, 0x0E, 0x4E, 0xEA, 0x05, 0xC4, 0x0A, 0x4E, 0x09, 0x87, 0x02, 0x9A, 0x01, 0x00, 0x01, 0xC7, 0x0A, 0xA9, 0x0A, 0x08, 0x0A, 0xA6, 0x0C, 0x00, 0x41, 0x00, 0xC0, 0x0C, 0xC2, 0x08, 0x43, 0x05, 0xD3, 0x01, 0xE8, 0x02, 0x41, 0x06, 0xB5, 0x08, 0x17, 0x07, 0x47, 0x9E, 0x02, 0xAB, 0x03, 0x02, 0x42, 0x80, 0x01, 0x56, 0x45, 0x4C, 0xC8, 0x01, 0xD0, 0x04, 0x48, 0x02, 0xA2, 0x01, 0x53, 0x0A, 0x03, 0xAC, 0x03, 0x00, 0x41, 0x00, 0xA2, 0x01, 0x94, 0x01, 0x01, 0x43, 0xEF, 0x02, 0xD9, 0x02, 0x41, 0x07, 0x44, 0x80, 0x02, 0x05, 0x42, 0xD3, 0x03, 0xF6, 0x01, 0x41, 0x05, 0x99, 0x02, 0x95, 0x02, 0x04, 0x43, 0x89, 0x02, 0x24, 0x05, 0x45, 0xE5, 0x02, 0xC5, 0x01, 0x00, 0x04, 0x43, 0x1C, 0x04, 0x01, 0x32, 0x00, 0x41, 0x00, 0x92, 0x01, 0xE9, 0x03, 0x42, 0x43, 0x1D, 0xAF, 0x01, 0x00, 0x02, 0x4E, 0xA2, 0x01, 0x04, 0x44, 0x4B, 0x73, 0x43, 0x04, 0xC5, 0x02, 0x7E, 0x00, 0x01, 0x0B, 0x8E, 0x01, 0x03, 0x00, 0x99, 0x01, 0x04, 0x00, 0x42, 0xDD, 0x01, 0x4F, 0x00, 0x05, 0xF7, 0x01, 0xA1, 0x01, 0x44, 0x02, 0x53, 0x00, 0x00, 0x00, 0x7E, 0x22, 0x00, 0x00, 0x41, 0x42, 0x00, 0x01, 0x11, 0x23, 0x02, 0x43, 0x49, 0x30, 0x41, 0x01, 0x06, 0xD6, 0x01, 0x42, 0x42, 0x49, 0x41, 0x00, 0x01, 0x13, 0x6A, 0x41, 0x00, 0x0E, 0x62, 0x42, 0x41, 0x58, 0x41, 0x41, 0x02, 0x67, 0xD8, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x41, 0x00, 0x59, 0x1A, 0x00, 0x01, 0x18, 0x45, 0x00, 0x00, 0x49, 0x44, 0x00, 0x02, 0x03, 0x06, 0x41, 0x00, 0x47, 0x42, 0x00, 0x00, 0x41, 0x51, 0x00, 0x01, 0x0E, 0x50, 0x41, 0x00, 0x46, 0x5E, 0x41, 0x41, 0x02, 0x54, 0x41, 0x00, 0x1F, 0x5A, 0x41, 0x00, 0x54, 0x00, 0x00, 0x00, 0x41, 0x4C, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x41, 0x4C, 0x52, 0x00, 0x01, 0x07, 0x01, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x05, 0x41, 0x00, 0x00, 0x42, 0x06, 0x00, 0x01, 0x45, 0x02, 0x00, 0x00, 0x01, 0x49, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x43, 0x05, 0x41, 0x41}; 62 | 63 | /********************** 64 | *** LOCAL FUNCTIONS *** 65 | **********************/ 66 | 67 | /*********************** 68 | *** GLOBAL FUNCTIONS *** 69 | ***********************/ -------------------------------------------------------------------------------- /app/app/src/main/res/layout/mqtt_settings_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 31 | 32 | 38 | 39 | 49 | 50 | 56 | 57 | 68 | 69 | 75 | 76 | 87 | 88 | 94 | 95 | 99 | 100 | 106 | 107 | 113 | 114 | 115 | 121 | 122 | 127 | -------------------------------------------------------------------------------- /components/n2klib/N2kMaretron.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | N2kMaretron.cpp 3 | 4 | Copyright (c) 2019-2021 Vassilis Bourdakis, 5 | Timo Lappalainen, Kave Oy, www.kave.fi, 6 | 7 | Authors Vassilis Bourdakis 8 | Timo Lappalainen 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of 11 | this software and associated documentation files (the "Software"), to deal in 12 | the Software without restriction, including without limitation the rights to use, 13 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 14 | Software, and to permit persons to whom the Software is furnished to do so, 15 | subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 21 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 22 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 24 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 25 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | #include "N2kTypes.h" 29 | #include "N2kMaretron.h" 30 | #include 31 | 32 | #define MaretronProprietary 0x9889 // Maretron 137 + reserved + industry code=marine 33 | 34 | 35 | //***************************************************************************** 36 | // Temperature High Range [MARETRON TMP100] 37 | // Temperatures should be in Kelvin 38 | void SetN2kMaretronPGN130823(tN2kMsg &N2kMsg, unsigned char SID, unsigned char TempInstance, tN2kTempSource TempSource, 39 | double ActualTemperature, double SetTemperature) { 40 | N2kMsg.SetPGN(130823L); 41 | N2kMsg.Priority=5; 42 | N2kMsg.Add2ByteUInt(MaretronProprietary); 43 | N2kMsg.AddByte(SID); 44 | N2kMsg.AddByte((unsigned char)TempInstance); 45 | N2kMsg.AddByte((unsigned char)TempSource); 46 | N2kMsg.Add2ByteUDouble(ActualTemperature,0.1); 47 | N2kMsg.Add2ByteUDouble(SetTemperature,0.1); 48 | } 49 | 50 | bool ParseN2kMaretronPGN130823(const tN2kMsg &N2kMsg, unsigned char &SID, unsigned char &TempInstance, tN2kTempSource &TempSource, 51 | double &ActualTemperature, double &SetTemperature) { 52 | if (N2kMsg.PGN!=130823L) return false; 53 | int Index=0; 54 | if (N2kMsg.Get2ByteUInt(Index)!=MaretronProprietary ) return false; 55 | SID=N2kMsg.GetByte(Index); 56 | TempInstance=N2kMsg.GetByte(Index); 57 | TempSource=(tN2kTempSource)(N2kMsg.GetByte(Index)); 58 | ActualTemperature=N2kMsg.Get2ByteUDouble(0.1,Index); 59 | SetTemperature=N2kMsg.Get2ByteUDouble(0.1,Index); 60 | return true; 61 | } 62 | 63 | //***************************************************************************** 64 | // Fluid Flow Rate [MARETRON FFM100] 65 | // Flow unit is 1 lt/hour 66 | void SetN2kMaretronPGN65286(tN2kMsg &N2kMsg, unsigned char SID, unsigned char FlowRateInstance, tN2kFluidType FluidType, 67 | double FluidFlowRate) { 68 | N2kMsg.SetPGN(65286L); 69 | N2kMsg.Priority=5; 70 | N2kMsg.Add2ByteUInt(MaretronProprietary); 71 | N2kMsg.AddByte(SID); 72 | N2kMsg.AddByte((unsigned char)FlowRateInstance); 73 | N2kMsg.AddByte((unsigned char)FluidType); 74 | N2kMsg.Add3ByteDouble(FluidFlowRate,0.1); 75 | } 76 | 77 | bool ParseN2kMaretronPGN65286(const tN2kMsg &N2kMsg, unsigned char &SID, unsigned char &FlowRateInstance, tN2kFluidType &FluidType, 78 | double &FluidFlowRate) { 79 | if (N2kMsg.PGN!=65286L) return false; 80 | int Index=0; 81 | if (N2kMsg.Get2ByteUInt(Index)!=MaretronProprietary ) return false; 82 | SID=N2kMsg.GetByte(Index); 83 | FlowRateInstance=N2kMsg.GetByte(Index); 84 | FluidType=(tN2kFluidType)(N2kMsg.GetByte(Index)); 85 | FluidFlowRate=N2kMsg.Get3ByteDouble(0.1,Index); 86 | return true; 87 | } 88 | 89 | //***************************************************************************** 90 | // Trip Volume [MARETRON FFM100] 91 | // Volume unit is 1 litre 92 | void SetN2kMaretronPGN65287(tN2kMsg &N2kMsg, unsigned char SID, unsigned char VolumeInstance, tN2kFluidType FluidType, 93 | double TripVolume) { 94 | N2kMsg.SetPGN(65287L); 95 | N2kMsg.Priority=5; 96 | N2kMsg.Add2ByteUInt(MaretronProprietary); 97 | N2kMsg.AddByte(SID); 98 | N2kMsg.AddByte((unsigned char)VolumeInstance); 99 | N2kMsg.AddByte((unsigned char)FluidType); 100 | N2kMsg.Add3ByteDouble(TripVolume,1); 101 | } 102 | 103 | bool ParseN2kMaretronPGN65287(const tN2kMsg &N2kMsg, unsigned char &SID, unsigned char &VolumeInstance, tN2kFluidType &FluidType, 104 | double &TripVolume) { 105 | if (N2kMsg.PGN!=65287L) return false; 106 | int Index=0; 107 | if (N2kMsg.Get2ByteUInt(Index)!=MaretronProprietary ) return false; 108 | SID=N2kMsg.GetByte(Index); 109 | VolumeInstance=N2kMsg.GetByte(Index); 110 | FluidType=(tN2kFluidType)(N2kMsg.GetByte(Index)); 111 | TripVolume=N2kMsg.Get3ByteDouble(1,Index); 112 | return true; 113 | } -------------------------------------------------------------------------------- /components/n2klib/Seasmart.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License 3 | 4 | Copyright (c) 2017-2021 Thomas Sarlandie thomas@sarlandie.net 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include "Seasmart.h" 29 | 30 | /* Some private helper functions to generate hex-serialized NMEA messages */ 31 | static const char *hex = "0123456789ABCDEF"; 32 | 33 | static int appendByte(char *s, uint8_t byte) { 34 | s[0] = hex[byte >> 4]; 35 | s[1] = hex[byte & 0xf]; 36 | return 2; 37 | } 38 | 39 | static int append2Bytes(char *s, uint16_t i) { 40 | appendByte(s, i >> 8); 41 | appendByte(s + 2, i & 0xff); 42 | return 4; 43 | } 44 | 45 | static int appendWord(char *s, uint32_t i) { 46 | append2Bytes(s, i >> 16); 47 | append2Bytes(s + 4, i & 0xffff); 48 | return 8; 49 | } 50 | 51 | static uint8_t nmea_compute_checksum(const char *sentence) { 52 | if (sentence == 0) { 53 | return 0; 54 | } 55 | 56 | // Skip the $ at the beginning 57 | int i = 1; 58 | 59 | int checksum = 0; 60 | while (sentence[i] != '*') { 61 | checksum ^= sentence[i]; 62 | i++; 63 | } 64 | return checksum; 65 | } 66 | 67 | size_t N2kToSeasmart(const tN2kMsg &msg, uint32_t timestamp, char *buffer, size_t size) { 68 | size_t pcdin_sentence_length = 6+1+6+1+8+1+2+1+msg.DataLen*2+1+2 + 1; 69 | 70 | if (size < pcdin_sentence_length) { 71 | return 0; 72 | } 73 | 74 | char *s = buffer; 75 | 76 | strcpy(s, "$PCDIN,"); 77 | s += 7; 78 | s += appendByte(s, msg.PGN >> 16); 79 | s += append2Bytes(s, msg.PGN & 0xffff); 80 | *s++ = ','; 81 | s += appendWord(s, timestamp); 82 | *s++ = ','; 83 | s += appendByte(s, msg.Source); 84 | *s++ = ','; 85 | 86 | for (int i = 0; i < msg.DataLen; i++) { 87 | s += appendByte(s, msg.Data[i]); 88 | } 89 | 90 | *s++ = '*'; 91 | s += appendByte(s, nmea_compute_checksum(buffer)); 92 | *s = 0; 93 | 94 | return (size_t)(s - buffer); 95 | } 96 | 97 | /* 98 | * Attemts to read n bytes in hexadecimal from input string to value. 99 | * 100 | * Returns true if successful, false otherwise. 101 | */ 102 | static bool readNHexByte(const char *s, unsigned int n, uint32_t &value) { 103 | if (strlen(s) < 2*n) { 104 | return -1; 105 | } 106 | for (unsigned int i = 0; i < 2*n; i++) { 107 | if (!isxdigit(s[i])) { 108 | return -1; 109 | } 110 | } 111 | 112 | char sNumber[2*n + 1]; 113 | strncpy(sNumber, s, sizeof(sNumber)); 114 | sNumber[sizeof(sNumber) - 1] = 0; 115 | 116 | value = strtol(sNumber, 0, 16); 117 | return true; 118 | } 119 | 120 | bool SeasmartToN2k(const char *buffer, uint32_t ×tamp, tN2kMsg &msg) { 121 | msg.Clear(); 122 | 123 | const char *s = buffer; 124 | if (strncmp("$PCDIN,", s, 6) != 0) { 125 | return false; 126 | } 127 | s += 7; 128 | 129 | uint32_t pgnHigh; 130 | uint32_t pgnLow; 131 | if (!readNHexByte(s, 1, pgnHigh)) { 132 | return false; 133 | } 134 | s += 2; 135 | if (!readNHexByte(s, 2, pgnLow)) { 136 | return false; 137 | } 138 | s += 5; 139 | msg.PGN = (pgnHigh << 16) + pgnLow; 140 | 141 | if (!readNHexByte(s, 4, timestamp)) { 142 | return false; 143 | } 144 | s += 9; 145 | 146 | uint32_t source; 147 | if (!readNHexByte(s, 1, source)) { 148 | return false; 149 | } 150 | msg.Source = source; 151 | s += 3; 152 | 153 | int dataLen = 0; 154 | while (s[dataLen] != 0 && s[dataLen] != '*') { 155 | dataLen++; 156 | } 157 | if (dataLen % 2 != 0) { 158 | return false; 159 | } 160 | dataLen /= 2; 161 | 162 | msg.DataLen = dataLen; 163 | if (msg.DataLen > msg.MaxDataLen) { 164 | return false; 165 | } 166 | for (int i = 0; i < dataLen; i++) { 167 | uint32_t byte; 168 | if (!readNHexByte(s, 1, byte)) { 169 | return false; 170 | } 171 | msg.Data[i] = byte; 172 | s += 2; 173 | } 174 | 175 | // Skip the terminating '*' which marks beginning of checksum 176 | s += 1; 177 | uint32_t checksum; 178 | if (!readNHexByte(s, 1, checksum)) { 179 | return false; 180 | } 181 | 182 | if (checksum != nmea_compute_checksum(buffer)) { 183 | return false; 184 | } 185 | 186 | return true; 187 | } 188 | -------------------------------------------------------------------------------- /components/n2klib/include/N2kMessagesEnumToStr.h: -------------------------------------------------------------------------------- 1 | /* 2 | N2kMessagesEnumToStr.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | This is collection of functions for handling NMEA2000 bus messages. 24 | Library contains functions to convert enums in N2kMessages.h to 25 | const char * 26 | 27 | If you do not need enums in clear text, you do not need this library. 28 | */ 29 | 30 | #ifndef _N2kMessagesEnumToStr_H_ 31 | #define _N2kMessagesEnumToStr_H_ 32 | 33 | #include "N2kMessages.h" 34 | 35 | const char *N2kEnumTypeEmpty=""; 36 | 37 | template void PrintN2kEnumType(T a, Stream *OutputStream, bool addLF=true) { 38 | const char *str=N2kEnumTypeToStr(a); 39 | if (str[0] != '\0') { 40 | if (addLF) { OutputStream->println(str); } else { OutputStream->print(str); } 41 | } else { 42 | OutputStream->print(F("unknown (")); OutputStream->print(a); OutputStream->println(F(")")); 43 | } 44 | } 45 | 46 | #define MakeN2kEnumTypeToStrFunc(enumType,strs) \ 47 | const char * N2kEnumTypeToStr(enumType enumVal) { \ 48 | if ( enumVal<(sizeof(strs)/sizeof(const char *)) ) { \ 49 | return strs[enumVal]; \ 50 | } else { return N2kEnumTypeEmpty; }\ 51 | } 52 | 53 | //***************************************************************************** 54 | const char* tN2kHeadingReferenceStrs[] = { "true", "magnetic" }; 55 | MakeN2kEnumTypeToStrFunc(tN2kHeadingReference,tN2kHeadingReferenceStrs) 56 | 57 | const char* tN2kTimeSourceStrs[] = { "GPS", "GLONASS", "radio station", "local cesium clock", "local rubidium clock", "local crystal clock" }; 58 | MakeN2kEnumTypeToStrFunc(tN2kTimeSource,tN2kTimeSourceStrs) 59 | 60 | const char* tN2kGNSStypeStrs[] = { "GPS", "GLONASS", "GPS+GLONASS", "GPS+SBAS/WAAS", "GPS+SBAS/WAAS+GLONASS", "Chayka", "integrated", "surveyed", "Galileo" }; 61 | MakeN2kEnumTypeToStrFunc(tN2kGNSStype,tN2kGNSStypeStrs) 62 | 63 | const char* tN2kGNSSmethodStrs[] = { "no GNSS", "GNSS fix", "DGNSS", "precise GNSS" }; 64 | MakeN2kEnumTypeToStrFunc(tN2kGNSSmethod,tN2kGNSSmethodStrs) 65 | 66 | const char* tN2kTempSourceStrs[] = { "sea", "outside", "inside", "engine room", "main cabin", "live well", "bait well", "refridgeration", 67 | "heating system", "dew point", "apparent wind chill", "theoretical wind chill", "heat index", "freezer", "exhaust gas"}; 68 | MakeN2kEnumTypeToStrFunc(tN2kTempSource,tN2kTempSourceStrs) 69 | 70 | const char* tN2kBatTypeStrs[] = { "flooded", "gel", "AGM"}; 71 | MakeN2kEnumTypeToStrFunc(tN2kBatType,tN2kBatTypeStrs) 72 | 73 | const char* tN2kBatEqSupportStrs[] = { "no", "yes", "error"}; 74 | MakeN2kEnumTypeToStrFunc(tN2kBatEqSupport,tN2kBatEqSupportStrs) 75 | 76 | const char* tN2kBatNomVoltStrs[] = { "6V", "12V", "24V", "32V", "62V", "42V", "48V"}; 77 | MakeN2kEnumTypeToStrFunc(tN2kBatNomVolt,tN2kBatNomVoltStrs) 78 | 79 | const char* tN2kBatChemStrs[] = { "lead acid", "LiIon", "NiCad", "NiMh"}; 80 | MakeN2kEnumTypeToStrFunc(tN2kBatChem,tN2kBatChemStrs) 81 | 82 | const char* tN2kDCTypeStrs[] = { "battery", "altenator", "converter", "solar cell", "wind generator"}; 83 | MakeN2kEnumTypeToStrFunc(tN2kDCType,tN2kDCTypeStrs) 84 | 85 | const char* tN2kTransmissionGearStrs[] = { "forward", "neutral", "reverse", "unknown"}; 86 | MakeN2kEnumTypeToStrFunc(tN2kTransmissionGear,tN2kTransmissionGearStrs) 87 | 88 | const char* tN2kOnOffStrs[] = { "0", "1", "err", "NA" }; 89 | MakeN2kEnumTypeToStrFunc(tN2kOnOff,tN2kOnOffStrs) 90 | 91 | const char* tN2kPressureStrs[] = { "atmospheric", "water", "steam", "compressed air", "hydraulic", "filter", "altimete setting", "oil", "fuel" }; 92 | MakeN2kEnumTypeToStrFunc(tN2kPressureSource,tN2kPressureStrs) 93 | 94 | const char* tN2kHumidityStrs[] = { "inside", "outside" }; 95 | MakeN2kEnumTypeToStrFunc(tN2kHumiditySource,tN2kHumidityStrs) 96 | 97 | const char* tN2kRudderDirectionOrderStrs[] = { "no direction order", "move to starboard", "move to port" }; 98 | MakeN2kEnumTypeToStrFunc(tN2kRudderDirectionOrder,tN2kRudderDirectionOrderStrs) 99 | 100 | const char* tN2kSpeedWaterReferenceTypeStrs[] = {"Paddle wheel","Pitot tube","Doppler","Correlation (ultra sound)","Electro Magnetic"}; 101 | MakeN2kEnumTypeToStrFunc(tN2kSpeedWaterReferenceType,tN2kSpeedWaterReferenceTypeStrs); 102 | 103 | const char* tN2kMagneticVariationStrs[] = { "Manual","Automatic Chart","Automatic Table","Automatic Calculation","WMM 2000","WMM 2005","WMM 2010","WMM 2015","WMM 2020" }; 104 | MakeN2kEnumTypeToStrFunc(tN2kMagneticVariation, tN2kSpeedWaterReferenceTypeStrs); 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /components/n2klib/include/N2kGroupFunctionDefaultHandlers.h: -------------------------------------------------------------------------------- 1 | /* 2 | N2kGroupFunctionDefaultHandlers.h 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | */ 24 | 25 | /* 26 | The file contains default group function handler classes for PGN 60928, 126993. 27 | These handlers are mandatory for NMEA 2000 certified devices. 28 | */ 29 | 30 | #ifndef _N2kGroupFunctionDefaultHandlers_H_ 31 | #define _N2kGroupFunctionDefaultHandlers_H_ 32 | 33 | #include "NMEA2000_CompilerDefns.h" 34 | #include "N2kGroupFunction.h" 35 | 36 | #if !defined(N2K_NO_GROUP_FUNCTION_SUPPORT) 37 | 38 | //***************************************************************************** 39 | // See document http://www.nmea.org/Assets/20140710%20nmea-2000-060928%20iso%20address%20claim%20pgn%20corrigendum.pdf 40 | // For requirements for handling Group function request for PGN 60928 41 | class tN2kGroupFunctionHandlerForPGN60928 : public tN2kGroupFunctionHandler { 42 | protected: 43 | virtual bool HandleRequest(const tN2kMsg &N2kMsg, 44 | uint32_t TransmissionInterval, 45 | uint16_t TransmissionIntervalOffset, 46 | uint8_t NumberOfParameterPairs, 47 | int iDev); 48 | virtual bool HandleCommand(const tN2kMsg &N2kMsg, uint8_t PrioritySetting, uint8_t NumberOfParameterPairs, int iDev); 49 | public: 50 | tN2kGroupFunctionHandlerForPGN60928(tNMEA2000 *_pNMEA2000) : tN2kGroupFunctionHandler(_pNMEA2000,60928L) {} 51 | }; 52 | 53 | //***************************************************************************** 54 | // This is mandatory. 55 | class tN2kGroupFunctionHandlerForPGN126464 : public tN2kGroupFunctionHandler { 56 | protected: 57 | virtual bool HandleRequest(const tN2kMsg &N2kMsg, 58 | uint32_t TransmissionInterval, 59 | uint16_t TransmissionIntervalOffset, 60 | uint8_t NumberOfParameterPairs, 61 | int iDev); 62 | public: 63 | tN2kGroupFunctionHandlerForPGN126464(tNMEA2000 *_pNMEA2000) : tN2kGroupFunctionHandler(_pNMEA2000,126464L) {} 64 | }; 65 | 66 | #if !defined(N2K_NO_HEARTBEAT_SUPPORT) 67 | //***************************************************************************** 68 | // See document https://www.nmea.org/Assets/20140102%20nmea-2000-126993%20heartbeat%20pgn%20corrigendum.pdf for 69 | // Heartbeat settings 70 | class tN2kGroupFunctionHandlerForPGN126993 : public tN2kGroupFunctionHandler { 71 | protected: 72 | virtual bool HandleRequest(const tN2kMsg &N2kMsg, 73 | uint32_t TransmissionInterval, 74 | uint16_t TransmissionIntervalOffset, 75 | uint8_t NumberOfParameterPairs, 76 | int iDev); 77 | public: 78 | tN2kGroupFunctionHandlerForPGN126993(tNMEA2000 *_pNMEA2000) : tN2kGroupFunctionHandler(_pNMEA2000,126993L) {} 79 | }; 80 | #endif 81 | 82 | //***************************************************************************** 83 | // This is not mandatory, but prefered 84 | class tN2kGroupFunctionHandlerForPGN126996 : public tN2kGroupFunctionHandler { 85 | protected: 86 | virtual bool HandleRequest(const tN2kMsg &N2kMsg, 87 | uint32_t TransmissionInterval, 88 | uint16_t TransmissionIntervalOffset, 89 | uint8_t NumberOfParameterPairs, 90 | int iDev); 91 | public: 92 | tN2kGroupFunctionHandlerForPGN126996(tNMEA2000 *_pNMEA2000) : tN2kGroupFunctionHandler(_pNMEA2000,126996L) {} 93 | }; 94 | 95 | //***************************************************************************** 96 | // This is not mandatory, but prefered 97 | class tN2kGroupFunctionHandlerForPGN126998 : public tN2kGroupFunctionHandler { 98 | protected: 99 | virtual bool HandleRequest(const tN2kMsg &N2kMsg, 100 | uint32_t TransmissionInterval, 101 | uint16_t TransmissionIntervalOffset, 102 | uint8_t NumberOfParameterPairs, 103 | int iDev); 104 | virtual bool HandleCommand(const tN2kMsg &N2kMsg, uint8_t PrioritySetting, uint8_t NumberOfParameterPairs, int iDev); 105 | public: 106 | tN2kGroupFunctionHandlerForPGN126998(tNMEA2000 *_pNMEA2000) : tN2kGroupFunctionHandler(_pNMEA2000,126998L) {} 107 | }; 108 | 109 | #endif 110 | #endif 111 | -------------------------------------------------------------------------------- /main/temperature_sensor.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include 32 | #include 33 | #include "driver/i2c.h" 34 | #include "driver/adc.h" 35 | #include "esp_adc_cal.h" 36 | #include "temperature_sensor.h" 37 | #include "esp_log.h" 38 | 39 | /************** 40 | *** DEFINES *** 41 | **************/ 42 | 43 | #define VOLTAGE_DIVIDER_RESISTANCE 9310.0f 44 | #define NO_OF_SAMPLES 32 45 | #define VOLTAGE_REF 5.0f 46 | 47 | /************ 48 | *** TYPES *** 49 | ************/ 50 | 51 | /******************************** 52 | *** LOCAL FUNCTION PROTOTYPES *** 53 | ********************************/ 54 | 55 | /** 56 | * Convert a sensor resistance to a sensor temperature for a PT-1000 sensor 57 | * 58 | * @param r resistance in ohms 59 | * @return temperature in degrees C 60 | */ 61 | static float temperature_sensor_temp_from_resistance(float r); 62 | 63 | /********************** 64 | *** LOCAL VARIABLES *** 65 | **********************/ 66 | 67 | static esp_adc_cal_characteristics_t adc_chars; 68 | static float temperatures[5]; 69 | static uint8_t next_temperature_position; 70 | 71 | /*********************** 72 | *** GLOBAL VARIABLES *** 73 | ***********************/ 74 | 75 | /**************** 76 | *** CONSTANTS *** 77 | ****************/ 78 | 79 | /********************** 80 | *** LOCAL FUNCTIONS *** 81 | **********************/ 82 | 83 | static float temperature_sensor_temp_from_resistance(float r) 84 | { 85 | float t; 86 | const float A = 3.90802e-3f; 87 | const float B = -5.80195e-7f; 88 | const float R0 = 1000.0f; 89 | 90 | t = A * A - 4.00f * B * (1.0f - r / R0); 91 | 92 | if (t < 0.0f) 93 | { 94 | // trap sqrt error 95 | return -9999.99f; 96 | } 97 | 98 | t = (-A + sqrt(t)) / (2.0f * B); 99 | 100 | return t; 101 | } 102 | 103 | /*********************** 104 | *** GLOBAL FUNCTIONS *** 105 | ***********************/ 106 | 107 | void temperature_sensor_init(void) 108 | { 109 | if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) 110 | { 111 | ESP_LOGI(pcTaskGetName(NULL), "eFuse Vref: Supported"); 112 | } 113 | else 114 | { 115 | ESP_LOGI(pcTaskGetName(NULL), "eFuse Vref: NOT supported"); 116 | } 117 | 118 | adc1_config_width(ADC_WIDTH_BIT_12); 119 | adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); 120 | esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_12, 0, &adc_chars); 121 | 122 | if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) 123 | { 124 | ESP_LOGI(pcTaskGetName(NULL), "Characterized using Two Point Value"); 125 | } 126 | else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) 127 | { 128 | ESP_LOGI(pcTaskGetName(NULL), "Characterized using eFuse Vref"); 129 | } 130 | else 131 | { 132 | ESP_LOGI(pcTaskGetName(NULL), "Characterized using Default Vref"); 133 | } 134 | } 135 | 136 | float temperature_sensor_read(void) 137 | { 138 | uint32_t adc_readings[NO_OF_SAMPLES]; 139 | bool sorted; 140 | uint32_t swap_value; 141 | uint32_t adc_reading; 142 | 143 | for (int i = 0; i < NO_OF_SAMPLES; i++) 144 | { 145 | adc_readings[i] = adc1_get_raw(ADC1_CHANNEL_4); 146 | } 147 | 148 | do 149 | { 150 | sorted = true; 151 | for (int i = 0U; i < (NO_OF_SAMPLES - 1U); i++) 152 | { 153 | if (adc_readings[i] > adc_readings[i + 1U]) 154 | { 155 | swap_value = adc_readings[i + 1U]; 156 | adc_readings[i + 1U] = adc_readings[i]; 157 | adc_readings[i] = swap_value; 158 | sorted = false; 159 | } 160 | } 161 | } 162 | while (!sorted); 163 | adc_reading = (adc_readings[NO_OF_SAMPLES / 2] + adc_readings[NO_OF_SAMPLES / 2 - 1]) / 2; 164 | 165 | // convert adc_reading to voltage in mV 166 | uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, &adc_chars); 167 | 168 | float voltagef = ((float)voltage) / 1000.0f; 169 | voltagef -= 0.08f; // incorrect ADC reading frig 170 | ESP_LOGI(pcTaskGetName(NULL), "Exhaust PT1000 temperature sensor voltage = %f", voltagef); 171 | 172 | float resistance = (VOLTAGE_DIVIDER_RESISTANCE * voltagef) / (VOLTAGE_REF - voltagef); 173 | ESP_LOGI(pcTaskGetName(NULL), "Exhaust PT1000 temperature sensor resistance = %f", resistance); 174 | 175 | temperatures[next_temperature_position] = temperature_sensor_temp_from_resistance(resistance); 176 | ESP_LOGI(pcTaskGetName(NULL), "Exhaust temperature = %f", temperatures[next_temperature_position]); 177 | 178 | next_temperature_position++; 179 | if (next_temperature_position == sizeof(temperatures) / sizeof(float)) 180 | { 181 | next_temperature_position = 0U; 182 | } 183 | 184 | float mean_temperature = 0.0f; 185 | for (uint8_t i = 0U; i < sizeof(temperatures) / sizeof(float); i++) 186 | { 187 | mean_temperature += temperatures[i]; 188 | } 189 | 190 | return mean_temperature / (float)(sizeof(temperatures) / sizeof(float)); 191 | } 192 | -------------------------------------------------------------------------------- /app/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 | -------------------------------------------------------------------------------- /main/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include 32 | #include 33 | #include 34 | #include "util.h" 35 | 36 | /************** 37 | *** DEFINES *** 38 | **************/ 39 | 40 | /************ 41 | *** TYPES *** 42 | ************/ 43 | 44 | /******************************** 45 | *** LOCAL FUNCTION PROTOTYPES *** 46 | ********************************/ 47 | 48 | /********************** 49 | *** LOCAL VARIABLES *** 50 | **********************/ 51 | 52 | /*********************** 53 | *** GLOBAL VARIABLES *** 54 | ***********************/ 55 | 56 | /**************** 57 | *** CONSTANTS *** 58 | ****************/ 59 | 60 | /********************** 61 | *** LOCAL FUNCTIONS *** 62 | **********************/ 63 | 64 | /*********************** 65 | *** GLOBAL FUNCTIONS *** 66 | ***********************/ 67 | 68 | void trim_trailing_ws(char *str) 69 | { 70 | int32_t index; 71 | int32_t i; 72 | 73 | // set default index 74 | index = -1; 75 | 76 | // find last index of non-white space character 77 | i = 0; 78 | while (str[i] != '\0') 79 | { 80 | if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n' && str[i] != '\r') 81 | { 82 | index = i; 83 | } 84 | 85 | i++; 86 | } 87 | 88 | // mark next character to last non-white space character as NULL 89 | str[index + 1] = '\0'; 90 | } 91 | 92 | bool util_safe_strcpy(char *dest, size_t size, const char *src) 93 | { 94 | if (dest == NULL || src == NULL || strlen(src) + (size_t)1 > size) 95 | { 96 | return false; 97 | } 98 | 99 | (void)strcpy(dest, src); 100 | 101 | return true; 102 | } 103 | 104 | bool util_safe_strcat(char *dest, size_t size, const char *src) 105 | { 106 | if (dest == NULL || src == NULL || (strlen(dest) + strlen(src) + (size_t)1 > size)) 107 | { 108 | return false; 109 | } 110 | 111 | (void)strcat(dest, src); 112 | 113 | return true; 114 | } 115 | 116 | uint32_t util_htoi(const char *s) 117 | { 118 | uint32_t val = 0UL; 119 | uint8_t x = 0U; 120 | 121 | if (s == NULL) 122 | { 123 | return 0UL; 124 | } 125 | 126 | while (s[x] != '\0') 127 | { 128 | if (s[x] >= '0' && s[x] <= '9') 129 | { 130 | val = val * 16UL + (uint32_t)(s[x] - '0'); 131 | } 132 | else if (s[x] >= 'A' && s[x] <= 'F') 133 | { 134 | val = val * 16UL + (uint32_t)(s[x] - 'A') + 10UL; 135 | } 136 | else if (s[x] >= 'a' && s[x] <= 'f') 137 | { 138 | val = val * 16UL + (uint32_t)(s[x] - 'a') + 10UL; 139 | } 140 | else 141 | { 142 | return 0UL; 143 | } 144 | 145 | x++; 146 | } 147 | 148 | return val; 149 | } 150 | 151 | void util_replace_char(char *s, char orig, char rep) 152 | { 153 | char *ix = s; 154 | 155 | if (s == NULL) 156 | { 157 | return; 158 | } 159 | 160 | while((ix = strchr(ix, orig))) 161 | { 162 | *ix++ = rep; 163 | } 164 | } 165 | 166 | char *util_capitalize_string(char *s) 167 | { 168 | char *o = s; 169 | 170 | if (s == NULL) 171 | { 172 | return NULL; 173 | } 174 | 175 | while ((*s = toupper(*s))) 176 | { 177 | s++; 178 | } 179 | 180 | return o; 181 | } 182 | 183 | char *util_seconds_to_hms(uint32_t seconds) 184 | { 185 | static char result[15]; 186 | char f[10]; 187 | uint32_t h = seconds / 3600UL; 188 | uint32_t m = (seconds - (seconds / 3600UL) * 3600UL ) / 60UL; 189 | uint32_t s = seconds % 60UL; 190 | 191 | result[0] = '\0'; 192 | if (h > 0) 193 | { 194 | (void)snprintf(f, sizeof(f), "%uh", (unsigned int)h); 195 | (void)util_safe_strcat(result, sizeof(result), f); 196 | } 197 | 198 | if (m > 0UL) 199 | { 200 | (void)snprintf(f, sizeof(f), "%um", (unsigned int)m); 201 | (void)util_safe_strcat(result, sizeof(result), f); 202 | } 203 | 204 | if (s > 0UL) 205 | { 206 | (void)snprintf(f, sizeof(f), "%us", (unsigned int)s); 207 | (void)util_safe_strcat(result, sizeof(result), f); 208 | } 209 | 210 | return result; 211 | } 212 | 213 | bool util_hms_to_seconds(const char *hms, uint32_t *result) 214 | { 215 | uint32_t field_val = 0UL; 216 | 217 | if (result == NULL) 218 | { 219 | return false; 220 | } 221 | 222 | *result = 0UL; 223 | 224 | if (hms == NULL) 225 | { 226 | return false; 227 | } 228 | 229 | if (strlen(hms) < (size_t)2) 230 | { 231 | return false; 232 | } 233 | 234 | if (hms[strlen(hms) - (size_t)1] != 's' && hms[strlen(hms) - (size_t)1] != 'm' && hms[strlen(hms) - (size_t)1] != 'h') 235 | { 236 | return false; 237 | } 238 | 239 | while (true) 240 | { 241 | if (*hms == '\0') 242 | { 243 | break; 244 | } 245 | 246 | if (isdigit((int)*hms)) 247 | { 248 | field_val *= 10UL; 249 | field_val += *hms - '0'; 250 | } 251 | else if (*hms == 'h') 252 | { 253 | *result += field_val * 3600UL; 254 | field_val = 0UL; 255 | } 256 | else if (*hms == 'm') 257 | { 258 | *result += field_val * 60UL; 259 | field_val = 0UL; 260 | } 261 | else if (*hms == 's') 262 | { 263 | *result += field_val; 264 | field_val = 0UL; 265 | } 266 | else 267 | { 268 | return false; 269 | } 270 | 271 | hms++; 272 | } 273 | 274 | return true; 275 | } 276 | 277 | uint32_t util_hash_djb2(const char *str) 278 | { 279 | uint32_t hash = 5381UL; 280 | char c; 281 | 282 | while ((c = *str++)) 283 | { 284 | hash = ((hash << 5) + hash) + (uint32_t)c; 285 | } 286 | 287 | return hash; 288 | } -------------------------------------------------------------------------------- /main/sms.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MIT License 4 | 5 | Copyright (c) John Blaiklock 2022 BlueBridge 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | /*************** 28 | *** INCLUDES *** 29 | ***************/ 30 | 31 | #include 32 | #include "freertos/FreeRTOS.h" 33 | #include "freertos/queue.h" 34 | #include "esp_log.h" 35 | #include "sms.h" 36 | #include "modem.h" 37 | #include "pdu.h" 38 | #include "util.h" 39 | 40 | /************** 41 | *** DEFINES *** 42 | **************/ 43 | 44 | /************ 45 | *** TYPES *** 46 | ************/ 47 | 48 | /******************************** 49 | *** LOCAL FUNCTION PROTOTYPES *** 50 | ********************************/ 51 | 52 | static void sms_notification_callback(uint32_t sms_id); 53 | 54 | /********************** 55 | *** LOCAL VARIABLES *** 56 | **********************/ 57 | 58 | static QueueHandle_t sms_waiting_id_queue_handle; ///< Queue of id's of received SMS messages 59 | 60 | /*********************** 61 | *** GLOBAL VARIABLES *** 62 | ***********************/ 63 | 64 | /**************** 65 | *** CONSTANTS *** 66 | ****************/ 67 | 68 | /********************** 69 | *** LOCAL FUNCTIONS *** 70 | **********************/ 71 | 72 | /** 73 | * Call back function called by modem when a new SMS has been received 74 | * 75 | * @param sms_id The id of the received message 76 | */ 77 | static void sms_notification_callback(uint32_t sms_id) 78 | { 79 | ESP_LOGI(pcTaskGetName(NULL), "SMS received notification, SMS Id is %u", sms_id); 80 | xQueueSendToBack(sms_waiting_id_queue_handle, (const void *)(&sms_id), (TickType_t)0); 81 | } 82 | 83 | /*********************** 84 | *** GLOBAL FUNCTIONS *** 85 | ***********************/ 86 | 87 | void sms_init(void) 88 | { 89 | sms_waiting_id_queue_handle = xQueueCreate((UBaseType_t)10, (UBaseType_t)sizeof(uint32_t)); 90 | ModemSetSmsNotificationCallback(sms_notification_callback); 91 | } 92 | 93 | bool sms_check_for_new(uint32_t *sms_id) 94 | { 95 | if (sms_id == NULL) 96 | { 97 | return false; 98 | } 99 | 100 | if (xQueueReceive(sms_waiting_id_queue_handle, sms_id, (TickType_t)0) == pdTRUE ) 101 | { 102 | return true; 103 | } 104 | 105 | return false; 106 | } 107 | 108 | bool sms_receive(uint32_t sms_id, char *phone_number, size_t phone_number_buffer_length, char *message_text, size_t message_text_buffer_length) 109 | { 110 | size_t length; 111 | uint8_t *pdu_ascii_hex_buf; 112 | uint8_t pdu_bin_buf[SMS_MAX_PDU_LENGTH]; 113 | time_t receive_time; 114 | char ascii_hex_byte[3]; 115 | int32_t text_length; 116 | size_t i; 117 | 118 | pdu_ascii_hex_buf = pvPortMalloc((size_t)(SMS_MAX_PDU_LENGTH * 2 + 1)); 119 | if (pdu_ascii_hex_buf == NULL) 120 | { 121 | return false; 122 | } 123 | 124 | ModemStatus_t modem_status = ModemSmsReceiveMessage(sms_id, &length, pdu_ascii_hex_buf, (size_t)(SMS_MAX_PDU_LENGTH * 2 + 1), 1000UL); 125 | ESP_LOGI(pcTaskGetName(NULL), "ModemSmsReceiveMessage length=%u %s", (uint32_t)length, ModemStatusToText(modem_status)); 126 | 127 | if (modem_status == MODEM_OK && length > (size_t)0) 128 | { 129 | // convert ascii hex to binary 130 | ascii_hex_byte[2] = (uint8_t)'\0'; 131 | for (i = (size_t)0; i < length / (size_t)2; i++) 132 | { 133 | ascii_hex_byte[0] = pdu_ascii_hex_buf[(unsigned int)i * 2]; 134 | ascii_hex_byte[1] = pdu_ascii_hex_buf[(unsigned int)i * 2 + 1]; 135 | pdu_bin_buf[(unsigned int)i] = (uint8_t)util_htoi(ascii_hex_byte); 136 | } 137 | 138 | // decode sms pdu 139 | text_length = (int32_t)pdu_decode((const unsigned char *)pdu_bin_buf, 140 | (int)length / 2, 141 | &receive_time, 142 | phone_number, 143 | (int)phone_number_buffer_length, 144 | message_text, 145 | (int)message_text_buffer_length); 146 | 147 | // parse sms text for key/value pairs 148 | if (text_length > 0) 149 | { 150 | vPortFree(pdu_ascii_hex_buf); 151 | return true; 152 | } 153 | else 154 | { 155 | ESP_LOGI(pcTaskGetName(NULL), "SMS PDU decode failed %d", text_length); 156 | ESP_LOGI(pcTaskGetName(NULL), "ModemSmsReceiveMessage length=%u %s", (uint32_t)length, ModemStatusToText(modem_status)); 157 | ESP_LOGI(pcTaskGetName(NULL), "ModemSmsReceiveMessage pdu=%s", pdu_ascii_hex_buf); 158 | } 159 | } 160 | 161 | vPortFree(pdu_ascii_hex_buf); 162 | 163 | return false; 164 | } 165 | 166 | bool sms_send(const char *message_text, const char *phone_number) 167 | { 168 | char *ascii_hex_pdu = NULL; 169 | uint8_t *binary_pdu = NULL; 170 | size_t pdu_binary_length; 171 | size_t i; 172 | char ascii_hex_byte[3]; 173 | bool success = false; 174 | ModemStatus_t modem_status; 175 | 176 | if (message_text != NULL && phone_number != NULL) 177 | { 178 | ascii_hex_pdu = pvPortMalloc((size_t)(SMS_MAX_PDU_LENGTH * 2 + 1)); 179 | binary_pdu = pvPortMalloc((size_t)SMS_MAX_PDU_LENGTH); 180 | 181 | if (ascii_hex_pdu != NULL && binary_pdu != NULL) 182 | { 183 | pdu_binary_length = (int32_t)pdu_encode(NULL, phone_number, message_text, (unsigned char *)binary_pdu, SMS_MAX_PDU_LENGTH); 184 | if (pdu_binary_length > 0) 185 | { 186 | ascii_hex_pdu[0] = '\0'; 187 | for (i = 0; i < pdu_binary_length; i++) 188 | { 189 | (void)sprintf(ascii_hex_byte, "%02x", binary_pdu[i]); 190 | (void)util_safe_strcat(ascii_hex_pdu, (size_t)(SMS_MAX_PDU_LENGTH * 2), ascii_hex_byte); 191 | } 192 | 193 | modem_status = ModemSmsSendMessage(ascii_hex_pdu, 60000UL); 194 | ESP_LOGI(pcTaskGetName(NULL), "ModemSmsSendMessage %s", ModemStatusToText(modem_status)); 195 | success = (modem_status == MODEM_OK); 196 | } 197 | } 198 | 199 | vPortFree(ascii_hex_pdu); 200 | vPortFree(binary_pdu); 201 | } 202 | 203 | return success; 204 | } -------------------------------------------------------------------------------- /components/n2klib/ActisenseReader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ActisenseReader.cpp 3 | 4 | Copyright (c) 2015-2021 Timo Lappalainen, Kave Oy, www.kave.fi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 17 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | 24 | This is class for reading Actisense format messages from given stream. 25 | */ 26 | #include "ActisenseReader.h" 27 | #include 28 | 29 | //***************************************************************************** 30 | tActisenseReader::tActisenseReader() { 31 | DefaultSource=65; 32 | ReadStream=0; 33 | ClearBuffer(); 34 | } 35 | 36 | //***************************************************************************** 37 | void tActisenseReader::ClearBuffer() { 38 | MsgWritePos=0; 39 | byteSum=0; 40 | StartOfTextReceived=false; 41 | MsgIsComing=false; 42 | EscapeReceived=false; 43 | } 44 | 45 | //***************************************************************************** 46 | bool tActisenseReader::AddByteToBuffer(char NewByte) { 47 | if (MsgWritePos>=MAX_STREAM_MSG_BUF_LEN) return false; 48 | 49 | MsgBuf[MsgWritePos]=NewByte; 50 | MsgWritePos++; 51 | if ( MsgBuf[1]+3!=MsgWritePos ) byteSum+=NewByte; // !Do not add CRC to byteSum 52 | return true; 53 | } 54 | 55 | #define Escape 0x10 56 | #define StartOfText 0x02 57 | #define EndOfText 0x03 58 | #define MsgTypeN2kData 0x93 59 | #define MsgTypeN2kRequest 0x94 60 | 61 | //***************************************************************************** 62 | bool tActisenseReader::CheckMessage(tN2kMsg &N2kMsg) { 63 | 64 | N2kMsg.Clear(); 65 | 66 | if (MsgWritePos!=MsgBuf[1]+3) { 67 | return false; // Length does not match. Add type, length and crc 68 | } 69 | 70 | uint8_t CheckSum = (uint8_t)((byteSum == 0) ? 0 : (256 - byteSum)); 71 | if ( CheckSum!=MsgBuf[MsgWritePos-1] ) { 72 | return false; // Checksum does not match 73 | } 74 | 75 | int i=2; 76 | N2kMsg.Priority=MsgBuf[i++]; 77 | N2kMsg.PGN=GetBuf3ByteUInt(i,MsgBuf); 78 | N2kMsg.Destination=MsgBuf[i++]; 79 | if ( MsgBuf[0]==MsgTypeN2kData ) { 80 | N2kMsg.Source=MsgBuf[i++]; 81 | N2kMsg.MsgTime=GetBuf4ByteUInt(i,MsgBuf); 82 | } else { 83 | N2kMsg.Source=DefaultSource; 84 | N2kMsg.MsgTime=millis(); 85 | } 86 | N2kMsg.DataLen=MsgBuf[i++]; 87 | 88 | if ( N2kMsg.DataLen>tN2kMsg::MaxDataLen ) { 89 | N2kMsg.Clear(); 90 | return false; // Too long data 91 | } 92 | 93 | for (int j=0; i<02><93>