Relocate proto utils (#3621)

This commit is contained in:
Phil Oliver 2025-11-05 03:27:13 -05:00 committed by GitHub
parent 8b83273a4f
commit c170ff6a4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 9 additions and 44 deletions

View file

@ -1,52 +0,0 @@
/*
* Copyright (c) 2025 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.proto
import org.meshtastic.proto.MeshProtos
import timber.log.Timber
/**
* Safely extracts the hardware model number from a HardwareModel enum.
*
* This function handles unknown enum values gracefully by catching IllegalArgumentException and returning a fallback
* value. This prevents crashes when the app receives data from devices with hardware models not yet defined in the
* current protobuf version.
*
* @param fallbackValue The value to return if the enum is unknown (defaults to 0 for UNSET)
* @return The hardware model number, or the fallback value if the enum is unknown
*/
@Suppress("detekt:SwallowedException")
fun MeshProtos.HardwareModel.safeNumber(fallbackValue: Int = -1): Int = try {
this.number
} catch (e: IllegalArgumentException) {
Timber.w("Unknown hardware model enum value: $this, using fallback value: $fallbackValue")
fallbackValue
}
/**
* Checks if the hardware model is a known/supported value.
*
* @return true if the hardware model is known and supported, false otherwise
*/
@Suppress("detekt:SwallowedException")
fun MeshProtos.HardwareModel.isKnown(): Boolean = try {
this.number
true
} catch (e: IllegalArgumentException) {
false
}

View file

@ -1,80 +0,0 @@
/*
* Copyright (c) 2025 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.proto
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.meshtastic.proto.ChannelProtos
import org.meshtastic.proto.ChannelProtos.ChannelSettings
import org.meshtastic.proto.MeshProtos
import org.meshtastic.proto.MeshProtos.MeshPacket
import org.meshtastic.proto.MeshProtos.Position
import org.meshtastic.proto.channel
import org.meshtastic.proto.channelSettings
import java.text.DateFormat
import kotlin.time.Duration.Companion.days
import org.meshtastic.core.strings.R as Res
private const val SECONDS_TO_MILLIS = 1000L
@Composable
fun MeshProtos.Position.formatPositionTime(dateFormat: DateFormat): String {
val currentTime = System.currentTimeMillis()
val sixMonthsAgo = currentTime - 180.days.inWholeMilliseconds
val isOlderThanSixMonths = time * SECONDS_TO_MILLIS < sixMonthsAgo
val timeText =
if (isOlderThanSixMonths) {
stringResource(Res.string.unknown_age)
} else {
dateFormat.format(time * SECONDS_TO_MILLIS)
}
return timeText
}
fun MeshPacket.toPosition(): Position? = if (!decoded.wantResponse) {
runCatching { Position.parseFrom(decoded.payload) }.getOrNull()
} else {
null
}
/**
* Builds a [Channel] list from the difference between two [ChannelSettings] lists. Only changes are included in the
* resulting list.
*
* @param new The updated [ChannelSettings] list.
* @param old The current [ChannelSettings] list (required when disabling unused channels).
* @return A [Channel] list containing only the modified channels.
*/
fun getChannelList(new: List<ChannelSettings>, old: List<ChannelSettings>): List<ChannelProtos.Channel> = buildList {
for (i in 0..maxOf(old.lastIndex, new.lastIndex)) {
if (old.getOrNull(i) != new.getOrNull(i)) {
add(
channel {
role =
when (i) {
0 -> ChannelProtos.Channel.Role.PRIMARY
in 1..new.lastIndex -> ChannelProtos.Channel.Role.SECONDARY
else -> ChannelProtos.Channel.Role.DISABLED
}
index = i
settings = new.getOrNull(i) ?: channelSettings {}
},
)
}
}
}