update to current dev a50c0d0b2d

This commit is contained in:
ericz
2026-05-20 23:20:16 +02:00
parent 9ada4ea601
commit 3fe5cdf55d
14 changed files with 583 additions and 100 deletions
+34
View File
@@ -4,6 +4,9 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart' as crypto;
import '../connector/meshcore_protocol.dart';
import 'community.dart';
enum ChannelType { public, private, hashtag, communityPublic, communityHashtag }
class Channel {
final int index;
@@ -111,5 +114,36 @@ class Channel {
return bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
}
static bool isCommunityChannel(ChannelType channelType) {
switch (channelType) {
case ChannelType.communityPublic:
case ChannelType.communityHashtag:
return true;
case ChannelType.public:
case ChannelType.private:
case ChannelType.hashtag:
return false;
}
}
static ChannelType getChannelType(
Channel channel,
CommunityPskIndex communityIndex,
) {
Community? community = communityIndex.getCommunityForChannel(channel);
if (community != null) {
if (Community.isCommunityPublicChannel(channel, community)) {
return ChannelType.communityPublic;
}
return ChannelType.communityHashtag;
}
if (channel.isPublicChannel) {
return ChannelType.public;
} else if (channel.name.startsWith('#')) {
return ChannelType.hashtag;
}
return ChannelType.private;
}
static const String publicChannelPsk = '8b3387e9c5cdea6ac9e5edbaa115cd72';
}
+33
View File
@@ -4,6 +4,8 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart' as crypto;
import 'channel.dart';
/// Represents a community with a shared secret for deriving channel PSKs.
///
/// A Community is a namespace with a shared secret K (32 random bytes),
@@ -162,6 +164,12 @@ class Community {
return hashtag.replaceFirst(RegExp(r'^#'), '').toLowerCase().trim();
}
/// Returns true if this is the community's public channel
static bool isCommunityPublicChannel(Channel channel, Community community) {
final publicPsk = community.deriveCommunityPublicPsk();
return channel.pskHex == Channel.formatPskHex(publicPsk);
}
/// Add a hashtag channel to this community's list
Community addHashtagChannel(String hashtag) {
final normalized = _normalizeCommunityHashtag(hashtag);
@@ -237,3 +245,28 @@ class Community {
@override
int get hashCode => id.hashCode;
}
class CommunityPskIndex {
// Cache of PSK hex -> Community for quick lookup
final Map<String, Community> _pskToCommunity = {};
void initialize(List<Community> communities) {
_pskToCommunity.clear();
for (final community in communities) {
// Map the community public channel PSK
final publicPsk = community.deriveCommunityPublicPsk();
_pskToCommunity[Channel.formatPskHex(publicPsk)] = community;
// Map all known hashtag channel PSKs
for (final hashtag in community.hashtagChannels) {
final hashtagPsk = community.deriveCommunityHashtagPsk(hashtag);
_pskToCommunity[Channel.formatPskHex(hashtagPsk)] = community;
}
}
}
/// Returns the community this channel belongs to, or null if not a community channel
Community? getCommunityForChannel(Channel channel) {
return _pskToCommunity[channel.pskHex];
}
}
+270
View File
@@ -181,6 +181,276 @@ class RadioSettings {
txPowerDbm: 14,
),
),
(
'Russia Artyom (VVO)',
RadioSettings(
frequencyMHz: 864.281,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_6,
txPowerDbm: 20,
),
),
(
'Russia Biysk (BSK)',
RadioSettings(
frequencyMHz: 869.000,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_5,
txPowerDbm: 20,
),
),
(
'Russia Chelyabinsk (CEK)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_6,
txPowerDbm: 20,
),
),
(
'Russia Cherepovets (CEE)',
RadioSettings(
frequencyMHz: 868.570,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Irkutsk (IKT)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Ivanovo (IWA)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Izhevsk (IJK)',
RadioSettings(
frequencyMHz: 868.732,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Kaluga (KLF)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Kazan (KZN)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_6,
txPowerDbm: 20,
),
),
(
'Russia Khabarovsk (KHV)',
RadioSettings(
frequencyMHz: 864.281,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_6,
txPowerDbm: 20,
),
),
(
'Russia Kirov (KVX)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Lipetsk (LPK)',
RadioSettings(
frequencyMHz: 868.950,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf9,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Moscow (MOW)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Nizhny Novgorod (GOJ)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_6,
txPowerDbm: 20,
),
),
(
'Russia Novosibirsk (OVB)',
RadioSettings(
frequencyMHz: 869.000,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf9,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Rostov-on-Don (ROV)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf9,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Ryazan (RZN)',
RadioSettings(
frequencyMHz: 868.880,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf9,
codingRate: LoRaCodingRate.cr4_5,
txPowerDbm: 20,
),
),
(
'Russia Samara (KUF)',
RadioSettings(
frequencyMHz: 864.281,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Saratov (GSV)',
RadioSettings(
frequencyMHz: 864.281,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia St. Petersburg (LED)',
RadioSettings(
frequencyMHz: 868.856,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Tambov (TBW)',
RadioSettings(
frequencyMHz: 868.950,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf10,
codingRate: LoRaCodingRate.cr4_5,
txPowerDbm: 20,
),
),
(
'Russia Tula (TYA)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Tver (KLD)',
RadioSettings(
frequencyMHz: 869.169,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Ufa (UFA)',
RadioSettings(
frequencyMHz: 868.732,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_8,
txPowerDbm: 20,
),
),
(
'Russia Volgograd (VOG)',
RadioSettings(
frequencyMHz: 869.525,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Russia Voronezh (VOZ)',
RadioSettings(
frequencyMHz: 868.731,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf8,
codingRate: LoRaCodingRate.cr4_6,
txPowerDbm: 20,
),
),
(
'Russia Yekaterinburg (SVX)',
RadioSettings(
frequencyMHz: 869.046,
bandwidth: LoRaBandwidth.bw62_5,
spreadingFactor: LoRaSpreadingFactor.sf7,
codingRate: LoRaCodingRate.cr4_7,
txPowerDbm: 20,
),
),
(
'Switzerland',
RadioSettings(