mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: Add SFPP confirmed status to Messages and Reactions (#4139)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> Co-authored-by: Mac DeCourcy <github.znq26@slmail.me>
This commit is contained in:
parent
78bd1ad6dd
commit
782c068ead
21 changed files with 2699 additions and 61 deletions
|
|
@ -39,6 +39,8 @@ enum class MessageStatus : Parcelable {
|
|||
QUEUED, // Waiting to send to the mesh as soon as we connect to the device
|
||||
ENROUTE, // Delivered to the radio, but no ACK or NAK received
|
||||
DELIVERED, // We received an ack
|
||||
SFPP_ROUTING, // Message is being routed/buffered in the SFPP system
|
||||
SFPP_CONFIRMED, // Message is confirmed on the SFPP chain
|
||||
ERROR, // We received back a nak, message not delivered
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ data class DataPacket(
|
|||
var viaMqtt: Boolean = false, // True if this packet passed via MQTT somewhere along its path
|
||||
var retryCount: Int = 0, // Number of automatic retry attempts
|
||||
var emoji: Int = 0,
|
||||
var sfppHash: ByteArray? = null,
|
||||
) : Parcelable {
|
||||
|
||||
/** If there was an error with this message, this string describes what was wrong. */
|
||||
|
|
@ -142,6 +145,7 @@ data class DataPacket(
|
|||
parcel.readInt() == 1, // viaMqtt
|
||||
parcel.readInt(), // retryCount
|
||||
parcel.readInt(), // emoji
|
||||
parcel.createByteArray(), // sfppHash
|
||||
)
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
|
|
@ -168,6 +172,7 @@ data class DataPacket(
|
|||
if (relayNode != other.relayNode) return false
|
||||
if (retryCount != other.retryCount) return false
|
||||
if (emoji != other.emoji) return false
|
||||
if (!sfppHash.contentEquals(other.sfppHash)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -190,6 +195,7 @@ data class DataPacket(
|
|||
result = 31 * result + relayNode.hashCode()
|
||||
result = 31 * result + retryCount
|
||||
result = 31 * result + emoji
|
||||
result = 31 * result + (sfppHash?.contentHashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +219,7 @@ data class DataPacket(
|
|||
parcel.writeInt(if (viaMqtt) 1 else 0)
|
||||
parcel.writeInt(retryCount)
|
||||
parcel.writeInt(emoji)
|
||||
parcel.writeByteArray(sfppHash)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int = 0
|
||||
|
|
@ -238,6 +245,7 @@ data class DataPacket(
|
|||
viaMqtt = parcel.readInt() == 1
|
||||
retryCount = parcel.readInt()
|
||||
emoji = parcel.readInt()
|
||||
sfppHash = parcel.createByteArray()
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<DataPacket> {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.model.util
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.security.MessageDigest
|
||||
|
||||
object SfppHasher {
|
||||
private const val HASH_SIZE = 16
|
||||
private const val INT_BYTES = 4
|
||||
|
||||
fun computeMessageHash(encryptedPayload: ByteArray, to: Int, from: Int, id: Int): ByteArray {
|
||||
val digest = MessageDigest.getInstance("SHA-256")
|
||||
digest.update(encryptedPayload)
|
||||
digest.update(ByteBuffer.allocate(INT_BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(to).array())
|
||||
digest.update(ByteBuffer.allocate(INT_BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(from).array())
|
||||
digest.update(ByteBuffer.allocate(INT_BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(id).array())
|
||||
return digest.digest().copyOf(HASH_SIZE)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue