2021-02-27 13:43:55 +08:00
|
|
|
package com.geeksville.mesh.model
|
|
|
|
|
|
2023-07-18 22:28:16 -03:00
|
|
|
import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig
|
2022-09-18 18:35:13 -03:00
|
|
|
import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig.ModemPreset
|
2023-07-18 22:28:16 -03:00
|
|
|
import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig.RegionCode
|
2021-02-27 13:43:55 +08:00
|
|
|
import com.geeksville.mesh.R
|
|
|
|
|
|
2024-01-10 05:33:19 -03:00
|
|
|
/**
|
|
|
|
|
* hash a string into an integer using the djb2 algorithm by Dan Bernstein
|
|
|
|
|
* http://www.cse.yorku.ca/~oz/hash.html
|
|
|
|
|
*/
|
|
|
|
|
private fun hash(name: String): UInt { // using UInt instead of Long to match RadioInterface.cpp results
|
|
|
|
|
var hash: UInt = 5381u
|
|
|
|
|
for (c in name) {
|
|
|
|
|
hash += (hash shl 5) + c.code.toUInt()
|
|
|
|
|
}
|
|
|
|
|
return hash
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val ModemPreset.bandwidth: Float
|
|
|
|
|
get() {
|
|
|
|
|
for (option in ChannelOption.entries) {
|
|
|
|
|
if (option.modemPreset == this) return option.bandwidth
|
|
|
|
|
}
|
|
|
|
|
return 0f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun LoRaConfig.bandwidth() = if (usePreset) {
|
2023-07-18 22:28:16 -03:00
|
|
|
val wideLora = region == RegionCode.LORA_24
|
2024-01-10 05:33:19 -03:00
|
|
|
modemPreset.bandwidth * if (wideLora) 3.25f else 1f
|
2023-07-18 22:28:16 -03:00
|
|
|
} else when (bandwidth) {
|
|
|
|
|
31 -> .03125f
|
|
|
|
|
62 -> .0625f
|
|
|
|
|
200 -> .203125f
|
|
|
|
|
400 -> .40625f
|
|
|
|
|
800 -> .8125f
|
|
|
|
|
1600 -> 1.6250f
|
|
|
|
|
else -> bandwidth / 1000f
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-10 05:33:19 -03:00
|
|
|
val LoRaConfig.numChannels: Int get() {
|
|
|
|
|
for (option in RegionInfo.entries) {
|
2024-10-13 23:02:05 -03:00
|
|
|
if (option.regionCode == region) {
|
2024-01-10 05:33:19 -03:00
|
|
|
return ((option.freqEnd - option.freqStart) / bandwidth()).toInt()
|
2024-10-13 23:02:05 -03:00
|
|
|
}
|
2024-01-10 05:33:19 -03:00
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 18:19:42 -03:00
|
|
|
internal fun LoRaConfig.channelNum(primaryName: String): Int = when {
|
|
|
|
|
channelNum != 0 -> channelNum
|
|
|
|
|
numChannels == 0 -> 0
|
|
|
|
|
else -> (hash(primaryName) % numChannels.toUInt()).toInt() + 1
|
2024-01-10 05:33:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal fun LoRaConfig.radioFreq(channelNum: Int): Float {
|
|
|
|
|
if (overrideFrequency != 0f) return overrideFrequency + frequencyOffset
|
|
|
|
|
for (option in RegionInfo.entries) {
|
2024-10-13 23:02:05 -03:00
|
|
|
if (option.regionCode == region) {
|
2024-01-10 05:33:19 -03:00
|
|
|
return (option.freqStart + bandwidth() / 2) + (channelNum - 1) * bandwidth()
|
2024-10-13 23:02:05 -03:00
|
|
|
}
|
2024-01-10 05:33:19 -03:00
|
|
|
}
|
|
|
|
|
return 0f
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-25 10:41:43 -03:00
|
|
|
@Suppress("MagicNumber")
|
2023-07-18 22:28:16 -03:00
|
|
|
enum class RegionInfo(
|
|
|
|
|
val regionCode: RegionCode,
|
2024-10-09 16:43:05 -03:00
|
|
|
val description: String,
|
2023-07-18 22:28:16 -03:00
|
|
|
val freqStart: Float,
|
|
|
|
|
val freqEnd: Float,
|
|
|
|
|
) {
|
2024-10-09 16:43:05 -03:00
|
|
|
UNSET(RegionCode.UNSET, "Please set a region", 902.0f, 928.0f),
|
|
|
|
|
US(RegionCode.US, "United States", 902.0f, 928.0f),
|
|
|
|
|
EU_433(RegionCode.EU_433, "European Union 433MHz", 433.0f, 434.0f),
|
|
|
|
|
EU_868(RegionCode.EU_868, "European Union 868MHz", 869.4f, 869.65f),
|
|
|
|
|
CN(RegionCode.CN, "China", 470.0f, 510.0f),
|
|
|
|
|
JP(RegionCode.JP, "Japan", 920.5f, 923.5f),
|
|
|
|
|
ANZ(RegionCode.ANZ, "Australia / New Zealand", 915.0f, 928.0f),
|
|
|
|
|
KR(RegionCode.KR, "Korea", 920.0f, 923.0f),
|
|
|
|
|
TW(RegionCode.TW, "Taiwan", 920.0f, 925.0f),
|
|
|
|
|
RU(RegionCode.RU, "Russia", 868.7f, 869.2f),
|
|
|
|
|
IN(RegionCode.IN, "India", 865.0f, 867.0f),
|
|
|
|
|
NZ_865(RegionCode.NZ_865, "New Zealand 865MHz", 864.0f, 868.0f),
|
|
|
|
|
TH(RegionCode.TH, "Thailand", 920.0f, 925.0f),
|
|
|
|
|
UA_433(RegionCode.UA_433, "Ukraine 433MHz", 433.0f, 434.7f),
|
|
|
|
|
UA_868(RegionCode.UA_868, "Ukraine 868MHz", 868.0f, 868.6f),
|
|
|
|
|
MY_433(RegionCode.MY_433, "Malaysia 433MHz", 433.0f, 435.0f),
|
|
|
|
|
MY_919(RegionCode.MY_919, "Malaysia 919MHz", 919.0f, 924.0f),
|
|
|
|
|
SG_923(RegionCode.SG_923, "Singapore 923MHz", 917.0f, 925.0f),
|
|
|
|
|
LORA_24(RegionCode.LORA_24, "2.4 GHz", 2400.0f, 2483.5f),
|
2023-07-18 22:28:16 -03:00
|
|
|
}
|
|
|
|
|
|
2021-03-29 20:33:06 +08:00
|
|
|
enum class ChannelOption(
|
2022-09-18 18:35:13 -03:00
|
|
|
val modemPreset: ModemPreset,
|
2021-03-29 20:33:06 +08:00
|
|
|
val configRes: Int,
|
2023-07-18 22:28:16 -03:00
|
|
|
val bandwidth: Float,
|
2021-03-29 20:33:06 +08:00
|
|
|
) {
|
2024-08-25 09:54:32 -03:00
|
|
|
SHORT_TURBO(ModemPreset.SHORT_TURBO, R.string.modem_config_turbo, bandwidth = .500f),
|
2023-07-18 22:28:16 -03:00
|
|
|
SHORT_FAST(ModemPreset.SHORT_FAST, R.string.modem_config_short, .250f),
|
2023-09-08 16:37:41 -03:00
|
|
|
SHORT_SLOW(ModemPreset.SHORT_SLOW, R.string.modem_config_slow_short, .250f),
|
|
|
|
|
MEDIUM_FAST(ModemPreset.MEDIUM_FAST, R.string.modem_config_medium, .250f),
|
|
|
|
|
MEDIUM_SLOW(ModemPreset.MEDIUM_SLOW, R.string.modem_config_slow_medium, .250f),
|
|
|
|
|
LONG_FAST(ModemPreset.LONG_FAST, R.string.modem_config_long, .250f),
|
2023-07-18 22:28:16 -03:00
|
|
|
LONG_MODERATE(ModemPreset.LONG_MODERATE, R.string.modem_config_mod_long, .125f),
|
2023-09-08 16:37:41 -03:00
|
|
|
LONG_SLOW(ModemPreset.LONG_SLOW, R.string.modem_config_slow_long, .125f),
|
2024-09-13 00:20:08 -03:00
|
|
|
VERY_LONG_SLOW(ModemPreset.VERY_LONG_SLOW, R.string.modem_config_very_long, .0625f),
|
2023-07-18 22:28:16 -03:00
|
|
|
}
|