Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/components/configuration/constants.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, it, expect } from 'vitest';
import { REGION_OPTIONS } from './constants';

// Guards against RegionCode drift from meshtastic/protobufs config.proto (#3927).
// When upstream adds a RegionCode value, extend REGION_OPTIONS and bump the max here.
describe('REGION_OPTIONS', () => {
const HIGHEST_REGION_CODE = 37; // ITU2_125CM — keep in sync with config.proto enum RegionCode

it('covers contiguous RegionCode values 0..HIGHEST_REGION_CODE with no gaps or dupes', () => {
const values = REGION_OPTIONS.map((o) => o.value).sort((a, b) => a - b);
expect(values).toEqual(Array.from({ length: HIGHEST_REGION_CODE + 1 }, (_, i) => i));
});

it('every option has a non-empty "NAME - description" label', () => {
for (const o of REGION_OPTIONS) {
expect(o.label).toMatch(/^\S+ - .+/);
}
});

it('uses the upstream enum name ITU2_2M for value 28 (not the old ITU23_2M)', () => {
const v28 = REGION_OPTIONS.find((o) => o.value === 28);
expect(v28?.label.startsWith('ITU2_2M -')).toBe(true);
});

it('includes the ITU amateur regions 33-37 added in #3927', () => {
const byValue = new Map(REGION_OPTIONS.map((o) => [o.value, o.label]));
expect(byValue.get(33)?.startsWith('ITU3_2M')).toBe(true);
expect(byValue.get(34)?.startsWith('ITU1_70CM')).toBe(true);
expect(byValue.get(35)?.startsWith('ITU2_70CM')).toBe(true);
expect(byValue.get(36)?.startsWith('ITU3_70CM')).toBe(true);
expect(byValue.get(37)?.startsWith('ITU2_125CM')).toBe(true);
});
});
9 changes: 7 additions & 2 deletions src/components/configuration/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,16 @@ export const REGION_OPTIONS: RegionOption[] = [
{ value: 25, label: 'NP_865 - Nepal 865MHz' },
{ value: 26, label: 'BR_902 - Brazil 902MHz' },
{ value: 27, label: 'ITU1_2M - ITU Region 1 Amateur 2m (144-146 MHz)' },
{ value: 28, label: 'ITU23_2M - ITU Region 2/3 Amateur 2m (144-148 MHz)' },
{ value: 28, label: 'ITU2_2M - ITU Region 2 Amateur 2m (144-148 MHz)' },
{ value: 29, label: 'EU_866 - European Union 866MHz SRD' },
{ value: 30, label: 'EU_874 - European Union 874MHz SRD' },
{ value: 31, label: 'EU_917 - European Union 917MHz SRD' },
{ value: 32, label: 'EU_N_868 - European Union 868MHz Narrow' }
{ value: 32, label: 'EU_N_868 - European Union 868MHz Narrow' },
{ value: 33, label: 'ITU3_2M - ITU Region 3 Amateur 2m (144-148 MHz)' },
{ value: 34, label: 'ITU1_70CM - ITU Region 1 Amateur 70cm (430-440 MHz)' },
{ value: 35, label: 'ITU2_70CM - ITU Region 2 Amateur 70cm (420-450 MHz, check local law)' },
{ value: 36, label: 'ITU3_70CM - ITU Region 3 Amateur 70cm (430-450 MHz, check local law)' },
{ value: 37, label: 'ITU2_125CM - ITU Region 2 Amateur 1.25m (220-225 MHz, check local law)' }
];

// Config.LoRaConfig.FEM_LNA_Mode (firmware >= v2.7.20, meshtastic/firmware#9809).
Expand Down
13 changes: 12 additions & 1 deletion src/server/services/deviceBackupService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,18 @@ const EnumMappings: Record<string, Record<number, string>> = {
23: 'KZ_433',
24: 'KZ_863',
25: 'NP_865',
26: 'BR_902'
26: 'BR_902',
27: 'ITU1_2M',
28: 'ITU2_2M',
29: 'EU_866',
30: 'EU_874',
31: 'EU_917',
32: 'EU_N_868',
33: 'ITU3_2M',
34: 'ITU1_70CM',
35: 'ITU2_70CM',
36: 'ITU3_70CM',
37: 'ITU2_125CM'
},
DetectionTriggerType: {
0: 'NONE',
Expand Down
20 changes: 20 additions & 0 deletions src/utils/loraFrequency.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,26 @@ describe('calculateLoRaFrequency', () => {
});
});

describe('ITU amateur regions added in RegionCode 33-37 (#3927)', () => {
// freqStart from firmware RadioInterface.cpp (develop / firmware#10627).
// Slot 0 at 250 kHz = freqStart + 0.125 MHz.
it('ITU3_2M (region 33): freqStart 144.0 → slot 0 = 144.125 MHz', () => {
expect(calculateLoRaFrequency(33, 1, 0, 0)).toBe('144.125 MHz');
});
it('ITU1_70CM (region 34): freqStart 430.0 → slot 0 = 430.125 MHz', () => {
expect(calculateLoRaFrequency(34, 1, 0, 0)).toBe('430.125 MHz');
});
it('ITU2_70CM (region 35): freqStart 420.0 → slot 0 = 420.125 MHz', () => {
expect(calculateLoRaFrequency(35, 1, 0, 0)).toBe('420.125 MHz');
});
it('ITU3_70CM (region 36): freqStart 430.0 → slot 0 = 430.125 MHz', () => {
expect(calculateLoRaFrequency(36, 1, 0, 0)).toBe('430.125 MHz');
});
it('ITU2_125CM (region 37): freqStart 220.0 → slot 0 = 220.125 MHz', () => {
expect(calculateLoRaFrequency(37, 1, 0, 0)).toBe('220.125 MHz');
});
});

describe('Override frequency', () => {
it('should use override frequency when set', () => {
const result = calculateLoRaFrequency(1, 21, 915.0, 0);
Expand Down
9 changes: 7 additions & 2 deletions src/utils/loraFrequency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,16 @@ export function calculateLoRaFrequency(
25: [865.0, 868.0], // NP_865: 865-868 MHz
26: [902.0, 907.5], // BR_902: 902-907.5 MHz
27: [144.0, 146.0], // ITU1_2M: ITU Region 1 Amateur 2m
28: [144.0, 148.0], // ITU23_2M: ITU Region 2/3 Amateur 2m
28: [144.0, 148.0], // ITU2_2M: ITU Region 2 Amateur 2m
29: [865.6, 867.6], // EU_866: EU 866MHz SRD (2.5% duty)
30: [873.4, 876.0], // EU_874: EU 874MHz SRD (Decision 2022/172 Band 1, awaiting firmware)
31: [917.4, 919.4], // EU_917: EU 917MHz SRD (Decision 2022/172 Band 4, awaiting firmware)
32: [869.4, 869.65] // EU_N_868: EU 868MHz Narrow (mandates LITE/NARROW preset)
32: [869.4, 869.65], // EU_N_868: EU 868MHz Narrow (mandates LITE/NARROW preset)
33: [144.0, 148.0], // ITU3_2M: ITU Region 3 Amateur 2m (firmware#10627, on develop / awaiting release)
34: [430.0, 440.0], // ITU1_70CM: ITU Region 1 Amateur 70cm (firmware#10627, on develop / awaiting release)
35: [420.0, 450.0], // ITU2_70CM: ITU Region 2 Amateur 70cm (firmware#10627, on develop / awaiting release)
36: [430.0, 450.0], // ITU3_70CM: ITU Region 3 Amateur 70cm (firmware#10627, on develop / awaiting release)
37: [220.0, 225.0] // ITU2_125CM: ITU Region 2 Amateur 1.25m (on develop / awaiting release)
};

if (!region || region === 0) {
Expand Down
Loading