mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-06-01 22:19:18 +02:00
fix: address top Crashlytics crashes in beta 2.7.14 (#5672)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
+5
-1
@@ -23,13 +23,17 @@ import kotlin.math.roundToLong
|
||||
object NumberFormatter {
|
||||
/** Formats a double value with the specified number of decimal places. */
|
||||
fun format(value: Double, decimalPlaces: Int): String {
|
||||
if (value.isNaN() || value.isInfinite()) return "—"
|
||||
val factor = 10.0.pow(decimalPlaces)
|
||||
val rounded = (value * factor).roundToLong()
|
||||
return formatFixedPoint(rounded, decimalPlaces)
|
||||
}
|
||||
|
||||
/** Formats a float value with the specified number of decimal places. */
|
||||
fun format(value: Float, decimalPlaces: Int): String = format(value.toDouble(), decimalPlaces)
|
||||
fun format(value: Float, decimalPlaces: Int): String {
|
||||
if (value.isNaN() || value.isInfinite()) return "—"
|
||||
return format(value.toDouble(), decimalPlaces)
|
||||
}
|
||||
|
||||
private fun formatFixedPoint(scaledValue: Long, decimalPlaces: Int): String {
|
||||
if (decimalPlaces == 0) return scaledValue.toString()
|
||||
|
||||
+13
@@ -35,4 +35,17 @@ class NumberFormatterTest {
|
||||
assertEquals("1", NumberFormatter.format(1.23, 0))
|
||||
assertEquals("-1", NumberFormatter.format(-1.23, 0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFormatNaN() {
|
||||
assertEquals("—", NumberFormatter.format(Double.NaN, 2))
|
||||
assertEquals("—", NumberFormatter.format(Float.NaN, 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFormatInfinity() {
|
||||
assertEquals("—", NumberFormatter.format(Double.POSITIVE_INFINITY, 2))
|
||||
assertEquals("—", NumberFormatter.format(Double.NEGATIVE_INFINITY, 2))
|
||||
assertEquals("—", NumberFormatter.format(Float.POSITIVE_INFINITY, 1))
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -51,7 +51,13 @@ class StoreForwardPacketHandlerImpl(
|
||||
|
||||
override fun handleStoreAndForward(packet: MeshPacket, dataPacket: DataPacket, myNodeNum: Int) {
|
||||
val payload = packet.decoded?.payload ?: return
|
||||
val u = StoreAndForward.ADAPTER.decode(payload)
|
||||
val u =
|
||||
try {
|
||||
StoreAndForward.ADAPTER.decode(payload)
|
||||
} catch (e: IOException) {
|
||||
Logger.e(e) { "Failed to parse StoreAndForward packet" }
|
||||
return
|
||||
}
|
||||
handleReceivedStoreAndForward(dataPacket, u, myNodeNum)
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -338,4 +338,18 @@ class StoreForwardPacketHandlerImplTest {
|
||||
|
||||
verifySuspend { packetRepository.updateSFPPStatus(any(), any(), any(), any(), any(), any(), any()) }
|
||||
}
|
||||
|
||||
// ---------- Legacy S&F: malformed proto ----------
|
||||
|
||||
@Test
|
||||
fun `handleStoreAndForward with malformed payload does not crash`() = testScope.runTest {
|
||||
val malformedPayload = ByteString.of(0xFF.toByte(), 0xFE.toByte(), 0x07, 0x0E)
|
||||
val packet =
|
||||
MeshPacket(from = 999, decoded = Data(portnum = PortNum.STORE_FORWARD_APP, payload = malformedPayload))
|
||||
val dataPacket = makeDataPacket(999)
|
||||
|
||||
// Should not throw — the handler catches the IOException from proto decoding
|
||||
handler.handleStoreAndForward(packet, dataPacket, myNodeNum)
|
||||
advanceUntilIdle()
|
||||
}
|
||||
}
|
||||
|
||||
+16
-7
@@ -86,14 +86,23 @@ internal class SerialConnectionImpl(
|
||||
}
|
||||
|
||||
port.open(usbDeviceConnection)
|
||||
port.setParameters(115200, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
|
||||
try {
|
||||
port.setParameters(115200, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
|
||||
|
||||
// Assert DTR/RTS so native USB-CDC firmware (RAK4631 / nRF52840) recognizes the host as
|
||||
// present and starts its serial-side Meshtastic protocol. Empirically, omitting these
|
||||
// signals causes the firmware to never respond to WAKE_BYTES, stalling the handshake at
|
||||
// Stage 1. Bridge-chip boards (CH340, CP210x, FTDI) tolerate the assertion.
|
||||
port.dtr = true
|
||||
port.rts = true
|
||||
// Assert DTR/RTS so native USB-CDC firmware (RAK4631 / nRF52840) recognizes the host as
|
||||
// present and starts its serial-side Meshtastic protocol. Empirically, omitting these
|
||||
// signals causes the firmware to never respond to WAKE_BYTES, stalling the handshake at
|
||||
// Stage 1. Bridge-chip boards (CH340, CP210x, FTDI) tolerate the assertion.
|
||||
port.dtr = true
|
||||
port.rts = true
|
||||
} catch (e: java.io.IOException) {
|
||||
Logger.w(e) { "USB control transfer failed during port setup — device may have disconnected" }
|
||||
closed.set(true)
|
||||
ignoreException(silent = true) { port.close() }
|
||||
closedLatch.countDown()
|
||||
listener.onDisconnected(e)
|
||||
return
|
||||
}
|
||||
|
||||
Logger.d { "Starting serial reader thread" }
|
||||
val io =
|
||||
|
||||
Reference in New Issue
Block a user