Clean up some strings and show checksum check

Signed-off-by: Severin Kaderli <severin@kaderli.dev>
This commit is contained in:
Severin Kaderli 2023-01-04 22:41:05 +01:00
parent 308104f321
commit 1a221761b8
Signed by: severinkaderli
GPG key ID: F419F8835B72F0C4
7 changed files with 118 additions and 27 deletions

View file

@ -0,0 +1,51 @@
package dev.kaderli.magsend
class Utility {
companion object {
/**
* Calculates the CRC-8-AUTOSAR checksum of the given array of bytes.
*
* This code is based on the code examples from the following page:
* http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
*
* The specifics of the algorithm is coming from the AUTOSAR CRC specification:
* https://www.autosar.org/fileadmin/user_upload/standards/classic/21-11/AUTOSAR_SWS_CRCLibrary.pdf
*
* > Utility.crc8Autosar(arrayListOf(0x0, 0x0, 0x0, 0x0)).toString(16)
* "12"
* > Utility.crc8Autosar(arrayListOf(0xF2, 0x01, 0x83)).toString(16)
* "c2"
* > Utility.crc8Autosar(arrayListOf(0x0F, 0xAA, 0x00, 0x55)).toString(16)
* "c6"
* > Utility.crc8Autosar(arrayListOf(0x00, 0xff, 0x55, 0x11)).toString(16)
* "77"
* > Utility.crc8Autosar(arrayListOf(0x33, 0x22, 0x55, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)).toString(16)
* "11"
* > Utility.crc8Autosar(arrayListOf(0x92, 0x6b, 0x55)).toString(16)
* "33"
* > Utility.crc8Autosar(arrayListOf(0xff, 0xff, 0xff, 0xff)).toString(16)
* "6c"
*/
fun crc8Autosar(bytes: List<Int>): Int {
val polynomial = 0x2f;
val xorOut = 0xff;
var crc = 0xff;
for (byte in bytes) {
crc = crc xor byte;
for(i in 1..8) {
crc = if ((crc and 0x80) != 0) {
((crc shl 1) xor polynomial) and 0xff;
} else {
crc shl 1
}
}
}
return crc xor xorOut;
}
}
}

View file

@ -27,6 +27,7 @@ abstract class BaseSensorActivity : BaseActivity(), SensorEventListener {
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
override fun onSensorChanged(event: SensorEvent) {
// Calculate the absolute magnetic field strength
val magneticFieldStrength = sqrt(event.values[0].pow(2) + event.values[1].pow(2) + event.values[2].pow(2))
sensorValueReceived(magneticFieldStrength)
}

View file

@ -1,17 +1,20 @@
package dev.kaderli.magsend.activity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import dev.kaderli.magsend.R
import dev.kaderli.magsend.Utility
import dev.kaderli.magsend.model.Sample
import dev.kaderli.magsend.model.Signal
import java.lang.Integer.min
import java.util.stream.Collectors
class ReceiveActivity : BaseSensorActivity() {
private lateinit var receiveDescription: TextView
private lateinit var preambleStatus: TextView
private lateinit var crcStatus: TextView
private lateinit var headerStatus: TextView
private lateinit var receiveValue: TextView
@ -30,9 +33,13 @@ class ReceiveActivity : BaseSensorActivity() {
*/
private var preambleReceived = false
private var receivingComplete = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
receiveDescription = findViewById(R.id.receiveDescription)
preambleStatus = findViewById(R.id.preambleStatus)
crcStatus = findViewById(R.id.crcStatus)
headerStatus = findViewById(R.id.headerStatus)
receiveValue = findViewById(R.id.receiveValue)
}
@ -182,7 +189,6 @@ class ReceiveActivity : BaseSensorActivity() {
}
}
val packetData = ArrayList<Int>()
var lastSignal: Sample<Signal>? = null
var isFirstSignal = true
@ -194,7 +200,6 @@ class ReceiveActivity : BaseSensorActivity() {
if (sample.value != lastSignal!!.value) {
if (samplesSinceLastSignal > (maxSamplesInARow * 0.75) || isFirstSignal) {
//Log.i(TAG, "$samplesSinceLastSignal")
if (sample.value == Signal.High) {
packetData.add(0)
} else {
@ -208,13 +213,14 @@ class ReceiveActivity : BaseSensorActivity() {
samplesSinceLastSignal++
}
//Log.i(TAG, "$cleanSignal")
return packetData
}
override fun sensorValueReceived(magneticFieldStrength: Float) {
if (receivingComplete) {
return;
}
// Add the current received sensor value to the samples
samples.add(Sample(magneticFieldStrength))
@ -252,14 +258,26 @@ class ReceiveActivity : BaseSensorActivity() {
for (i in 1..numberOfAvailablePayloadBytes) {
payload += listToInteger(packet.take(4 + (8 * i)).takeLast(8)).toChar().toString()
}
receiveValue.text = payload
// TODO: CRC show and calculate if it's correct
if (packet.size >= 4 + (8 * payloadLength) + 8) {
// CRC Check
val crc = listToInteger(packet.take(4 + (8 * payloadLength) + 8).takeLast(8))
Log.i(TAG, "CRC: $crc")
val receivedCrc = listToInteger(packet.take(4 + (8 * payloadLength) + 8).takeLast(8))
val calculatedCrc =
Utility.crc8Autosar(receiveValue.text.codePoints().boxed().collect(Collectors.toList()))
if (receivedCrc == calculatedCrc) {
crcStatus.setText(R.string.crc_status_valid)
crcStatus.setTextColor(ContextCompat.getColor(this, R.color.success))
} else {
crcStatus.setText(R.string.crc_status_invalid)
crcStatus.setTextColor(ContextCompat.getColor(this, R.color.error))
}
// Mark receiving as complete
receiveDescription.setText(R.string.receive_description_complete)
receivingComplete = true
}
}
}
@ -278,8 +296,15 @@ class ReceiveActivity : BaseSensorActivity() {
fun restartReceiveProcess(view: View) {
preambleReceived = false
receivingComplete = false
receiveDescription.setText(R.string.receive_description)
preambleStatus.setText(R.string.preamble_status_not_detected)
preambleStatus.setTextColor(ContextCompat.getColor(this, R.color.error))
headerStatus.text = ""
crcStatus.text = ""
receiveValue.text = ""
samples.clear()
signal.clear()
}

View file

@ -8,7 +8,7 @@
<TextView
android:id="@+id/receiveDescription"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_margins"
android:paddingHorizontal="@dimen/layout_margins"
@ -21,10 +21,10 @@
android:id="@+id/preambleStatus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/component_spacing_small"
android:layout_marginTop="@dimen/component_spacing"
android:paddingHorizontal="@dimen/layout_margins"
android:text="@string/preamble_status_not_detected"
android:textColor="#FF0000"
android:textColor="@color/error"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/receiveDescription" />
@ -40,21 +40,31 @@
app:layout_constraintTop_toBottomOf="@+id/preambleStatus" />
<TextView
android:id="@+id/receiveValue"
android:layout_width="wrap_content"
android:id="@+id/crcStatus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/component_spacing"
android:text="___"
android:textSize="48sp"
android:layout_marginTop="@dimen/component_spacing_small"
android:paddingHorizontal="@dimen/layout_margins"
android:textColor="@color/success"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/headerStatus" />
<TextView
android:id="@+id/restartDescription"
android:id="@+id/receiveValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/component_spacing"
android:textSize="48sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/crcStatus" />
<TextView
android:id="@+id/restartDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/component_spacing_large"
android:paddingHorizontal="@dimen/layout_margins"
android:text="@string/restart_description"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="error">#FFFF0000</color>
<color name="success">#FF00FF00</color>
<color name="error">#FFFF5454</color>
<color name="success">#FF4BB543</color>
</resources>

View file

@ -4,4 +4,5 @@
<dimen name="component_spacing">24dp</dimen>
<dimen name="title_text_size">48sp</dimen>
<dimen name="component_spacing_small">8dp</dimen>
<dimen name="component_spacing_large">48dp</dimen>
</resources>

View file

@ -5,7 +5,7 @@
<string name="receive_button_label">Receive</string>
<string name="calibrate_button_label">Calibrate</string>
<string name="calibration_description">Open up the website and start the calibration mode. Put your Smartphone on different locations on the sending device and note the value below. The location with the highest value is the most optimal for data transmission.</string>
<string name="receive_description">Currently listening for transmissions. The text that was received so far is displayed below.</string>
<string name="receive_description">Currently listening for transmissions.\nThe text that was received so far is displayed below.</string>
<string name="restart_description">To start listening to a new message click the following button.</string>
<string name="restart_button_label">Restart</string>
<string name="calibration_activity_label">Calibration</string>
@ -14,4 +14,7 @@
<string name="preamble_status_not_detected">Preamble not detected X</string>
<string name="preamble_status_detected">Preamble detected ✓</string>
<string name="payload_length">The payload length is %1$d bytes</string>
<string name="receive_description_complete">The transmission is completed.\nThe received text is displayed below.</string>
<string name="crc_status_valid">The checksum is valid ✓.</string>
<string name="crc_status_invalid">The checksum is invalid X.</string>
</resources>