feat: network module (#1905)

This commit is contained in:
James Rich 2025-05-22 08:30:08 -05:00 committed by GitHub
parent 520d058546
commit 02bb3f02e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
80 changed files with 2165 additions and 15032 deletions

View file

@ -129,4 +129,20 @@ class Converters : Logging {
fun metadataToBytes(value: MeshProtos.DeviceMetadata): ByteArray? {
return value.toByteArray()
}
@TypeConverter
fun fromStringList(value: String?): List<String>? {
if (value == null) {
return null
}
return Json.decodeFromString<List<String>>(value)
}
@TypeConverter
fun toStringList(list: List<String>?): String? {
if (list == null) {
return null
}
return Json.encodeToString(list)
}
}

View file

@ -18,6 +18,8 @@
package com.geeksville.mesh.database
import android.app.Application
import com.geeksville.mesh.database.dao.DeviceHardwareDao
import com.geeksville.mesh.database.dao.FirmwareReleaseDao
import com.geeksville.mesh.database.dao.MeshLogDao
import com.geeksville.mesh.database.dao.NodeInfoDao
import com.geeksville.mesh.database.dao.PacketDao
@ -55,4 +57,14 @@ class DatabaseModule {
fun provideQuickChatActionDao(database: MeshtasticDatabase): QuickChatActionDao {
return database.quickChatActionDao()
}
}
@Provides
fun provideDeviceHardwareDao(database: MeshtasticDatabase): DeviceHardwareDao {
return database.deviceHardwareDao()
}
@Provides
fun provideFirmwareReleaseDao(database: MeshtasticDatabase): FirmwareReleaseDao {
return database.firmwareReleaseDao()
}
}

View file

@ -25,11 +25,15 @@ import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.AutoMigrationSpec
import com.geeksville.mesh.database.dao.PacketDao
import com.geeksville.mesh.database.dao.DeviceHardwareDao
import com.geeksville.mesh.database.dao.FirmwareReleaseDao
import com.geeksville.mesh.database.dao.MeshLogDao
import com.geeksville.mesh.database.dao.NodeInfoDao
import com.geeksville.mesh.database.dao.PacketDao
import com.geeksville.mesh.database.dao.QuickChatActionDao
import com.geeksville.mesh.database.entity.ContactSettings
import com.geeksville.mesh.database.entity.DeviceHardwareEntity
import com.geeksville.mesh.database.entity.FirmwareReleaseEntity
import com.geeksville.mesh.database.entity.MeshLog
import com.geeksville.mesh.database.entity.MetadataEntity
import com.geeksville.mesh.database.entity.MyNodeEntity
@ -48,6 +52,8 @@ import com.geeksville.mesh.database.entity.ReactionEntity
QuickChatAction::class,
ReactionEntity::class,
MetadataEntity::class,
DeviceHardwareEntity::class,
FirmwareReleaseEntity::class,
],
autoMigrations = [
AutoMigration(from = 3, to = 4),
@ -63,8 +69,9 @@ import com.geeksville.mesh.database.entity.ReactionEntity
AutoMigration(from = 13, to = 14),
AutoMigration(from = 14, to = 15),
AutoMigration(from = 15, to = 16),
AutoMigration(from = 16, to = 17),
],
version = 16,
version = 17,
exportSchema = true,
)
@TypeConverters(Converters::class)
@ -73,6 +80,8 @@ abstract class MeshtasticDatabase : RoomDatabase() {
abstract fun packetDao(): PacketDao
abstract fun meshLogDao(): MeshLogDao
abstract fun quickChatActionDao(): QuickChatActionDao
abstract fun deviceHardwareDao(): DeviceHardwareDao
abstract fun firmwareReleaseDao(): FirmwareReleaseDao
companion object {
fun getDatabase(context: Context): MeshtasticDatabase {
@ -82,7 +91,7 @@ abstract class MeshtasticDatabase : RoomDatabase() {
MeshtasticDatabase::class.java,
"meshtastic_database"
)
.fallbackToDestructiveMigration()
.fallbackToDestructiveMigration(false)
.build()
}
}

View file

@ -0,0 +1,36 @@
/*
* 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 com.geeksville.mesh.database.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.geeksville.mesh.database.entity.DeviceHardwareEntity
@Dao
interface DeviceHardwareDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(deviceHardware: DeviceHardwareEntity)
@Query("SELECT * FROM device_hardware WHERE hwModel = :hwModel")
suspend fun getByHwModel(hwModel: Int): DeviceHardwareEntity?
@Query("DELETE FROM device_hardware")
suspend fun deleteAll()
}

View file

@ -0,0 +1,40 @@
/*
* 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 com.geeksville.mesh.database.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.geeksville.mesh.database.entity.FirmwareReleaseEntity
import com.geeksville.mesh.database.entity.FirmwareReleaseType
@Dao
interface FirmwareReleaseDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(firmwareReleaseEntity: FirmwareReleaseEntity)
@Query("DELETE FROM firmware_release")
suspend fun deleteAll()
@Query("SELECT * FROM firmware_release")
suspend fun getAllReleases(): List<FirmwareReleaseEntity>?
@Query("SELECT * FROM firmware_release WHERE release_type = :releaseType")
suspend fun getReleasesByType(releaseType: FirmwareReleaseType): List<FirmwareReleaseEntity>?
}

View file

@ -0,0 +1,77 @@
/*
* 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 com.geeksville.mesh.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.geeksville.mesh.model.DeviceHardware
import com.geeksville.mesh.network.model.NetworkDeviceHardware
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "device_hardware")
data class DeviceHardwareEntity(
@ColumnInfo(name = "actively_supported") val activelySupported: Boolean,
val architecture: String,
@ColumnInfo(name = "display_name") val displayName: String,
@ColumnInfo(name = "has_ink_hud") val hasInkHud: Boolean? = null,
@ColumnInfo(name = "has_mui") val hasMui: Boolean? = null,
@PrimaryKey val hwModel: Int,
@ColumnInfo(name = "hw_model_slug") val hwModelSlug: String,
val images: List<String>?,
@ColumnInfo(name = "last_updated") val lastUpdated: Long = System.currentTimeMillis(),
@ColumnInfo(name = "partition_scheme") val partitionScheme: String? = null,
@ColumnInfo(name = "platformio_target") val platformioTarget: String,
@ColumnInfo(name = "requires_dfu") val requiresDfu: Boolean?,
@ColumnInfo(name = "support_level") val supportLevel: Int?,
val tags: List<String>?,
)
fun NetworkDeviceHardware.asEntity() = DeviceHardwareEntity(
activelySupported = activelySupported,
architecture = architecture,
displayName = displayName,
hasInkHud = hasInkHud,
hasMui = hasMui,
hwModel = hwModel,
hwModelSlug = hwModelSlug,
images = images,
lastUpdated = System.currentTimeMillis(),
partitionScheme = partitionScheme,
platformioTarget = platformioTarget,
requiresDfu = requiresDfu,
supportLevel = supportLevel,
tags = tags,
)
fun DeviceHardwareEntity.asExternalModel() = DeviceHardware(
activelySupported = activelySupported,
architecture = architecture,
displayName = displayName,
hasInkHud = hasInkHud,
hasMui = hasMui,
hwModel = hwModel,
hwModelSlug = hwModelSlug,
images = images,
partitionScheme = partitionScheme,
platformioTarget = platformioTarget,
requiresDfu = requiresDfu,
supportLevel = supportLevel,
tags = tags,
)

View file

@ -0,0 +1,79 @@
/*
* 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 com.geeksville.mesh.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.geeksville.mesh.network.model.NetworkFirmwareRelease
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "firmware_release")
data class FirmwareReleaseEntity(
@PrimaryKey
@ColumnInfo(name = "id")
val id: String = "",
@ColumnInfo(name = "page_url")
val pageUrl: String = "",
@ColumnInfo(name = "release_notes")
val releaseNotes: String = "",
@ColumnInfo(name = "title")
val title: String = "",
@ColumnInfo(name = "zip_url")
val zipUrl: String = "",
@ColumnInfo(name = "last_updated")
val lastUpdated: Long = System.currentTimeMillis(),
@ColumnInfo(name = "release_type")
val releaseType: FirmwareReleaseType = FirmwareReleaseType.STABLE,
)
fun NetworkFirmwareRelease.asEntity(releaseType: FirmwareReleaseType) = FirmwareReleaseEntity(
id = id,
pageUrl = pageUrl,
releaseNotes = releaseNotes,
title = title,
zipUrl = zipUrl,
lastUpdated = System.currentTimeMillis(),
releaseType = releaseType,
)
fun FirmwareReleaseEntity.asExternalModel() = FirmwareRelease(
id = id,
pageUrl = pageUrl,
releaseNotes = releaseNotes,
title = title,
zipUrl = zipUrl,
lastUpdated = lastUpdated,
releaseType = releaseType,
)
data class FirmwareRelease(
val id: String = "",
val pageUrl: String = "",
val releaseNotes: String = "",
val title: String = "",
val zipUrl: String = "",
val lastUpdated: Long = System.currentTimeMillis(),
val releaseType: FirmwareReleaseType = FirmwareReleaseType.STABLE,
)
enum class FirmwareReleaseType {
STABLE,
ALPHA
}

View file

@ -34,6 +34,7 @@ data class MyNodeEntity(
val minAppVersion: Int,
val maxChannels: Int,
val hasWifi: Boolean,
val deviceId: String? = "unknown",
) {
/** A human readable description of the software/hardware version */
val firmwareString: String get() = "$model $firmwareVersion"
@ -52,5 +53,6 @@ data class MyNodeEntity(
hasWifi = hasWifi,
channelUtilization = 0f,
airUtilTx = 0f,
deviceId = deviceId,
)
}