diff --git a/FreeDMR.cfg b/FreeDMR.cfg index 9dd9a97..67c5c90 100644 --- a/FreeDMR.cfg +++ b/FreeDMR.cfg @@ -61,7 +61,7 @@ SINGLE_MODE: True VOICE_IDENT: True DIAL_A_TG: True DYNAMIC_TG_ROUTING: True -NETWORK_DIRECT_DIAL_SLOT: 0 +NETWORK_DIRECT_DIAL_SLOT: 1 TS1_STATIC: TS2_STATIC: DEFAULT_DIAL_TS1: 0 diff --git a/bridge_master.py b/bridge_master.py index 3fe38a8..2f507fe 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -275,7 +275,7 @@ def activate_network_direct_dial(_dst_id, pkt_time): if CONFIG['SYSTEMS'][system]['MODE'] != 'MASTER': continue - slot = CONFIG['SYSTEMS'][system].get('NETWORK_DIRECT_DIAL_SLOT', 0) + slot = CONFIG['SYSTEMS'][system].get('NETWORK_DIRECT_DIAL_SLOT', 1) if slot not in (1, 2): continue @@ -1516,7 +1516,7 @@ def options_config(): if 'DYNAMIC_TG_ROUTING' not in _options: _options['DYNAMIC_TG_ROUTING'] = int(CONFIG['SYSTEMS'][_system].get('DYNAMIC_TG_ROUTING', True)) if 'NETWORK_DIRECT_DIAL_SLOT' not in _options: - _options['NETWORK_DIRECT_DIAL_SLOT'] = CONFIG['SYSTEMS'][_system].get('NETWORK_DIRECT_DIAL_SLOT', 0) + _options['NETWORK_DIRECT_DIAL_SLOT'] = CONFIG['SYSTEMS'][_system].get('NETWORK_DIRECT_DIAL_SLOT', 1) _default_dial_ts1 = parse_default_reflector_option(_options['DEFAULT_DIAL_TS1'], default=None) if _default_dial_ts1 is None: @@ -1590,7 +1590,7 @@ def options_config(): _network_direct_dial_slot = parse_network_direct_dial_slot(_options['NETWORK_DIRECT_DIAL_SLOT'], default=None) if _network_direct_dial_slot is None: logger.debug('(OPTIONS) %s - NETWORK_DIRECT_DIAL_SLOT is not 0, 1, or 2, ignoring',_system) - _network_direct_dial_slot = CONFIG['SYSTEMS'][_system].get('NETWORK_DIRECT_DIAL_SLOT', 0) + _network_direct_dial_slot = CONFIG['SYSTEMS'][_system].get('NETWORK_DIRECT_DIAL_SLOT', 1) if 'TS1_STATIC' not in _options or 'TS2_STATIC' not in _options or 'DEFAULT_DIAL_TS1' not in _options or 'DEFAULT_DIAL_TS2' not in _options or 'DEFAULT_UA_TIMER' not in _options: logger.debug('(OPTIONS) %s - Required field missing, ignoring',_system) @@ -1653,7 +1653,7 @@ def options_config(): if _dynamic_tg_routing != CONFIG['SYSTEMS'][_system].get('DYNAMIC_TG_ROUTING', True): logger.debug('(OPTIONS) %s DYNAMIC_TG_ROUTING changed to %s',_system,_dynamic_tg_routing) - if _network_direct_dial_slot != CONFIG['SYSTEMS'][_system].get('NETWORK_DIRECT_DIAL_SLOT', 0): + if _network_direct_dial_slot != CONFIG['SYSTEMS'][_system].get('NETWORK_DIRECT_DIAL_SLOT', 1): logger.debug('(OPTIONS) %s NETWORK_DIRECT_DIAL_SLOT changed to %s',_system,_network_direct_dial_slot) ts1 = [] diff --git a/config.py b/config.py index c29962a..5a7b942 100755 --- a/config.py +++ b/config.py @@ -49,14 +49,14 @@ logger = logging.getLogger(__name__) def config_network_direct_dial_slot(config, section): try: - slot = config.getint(section, 'NETWORK_DIRECT_DIAL_SLOT', fallback=0) + slot = config.getint(section, 'NETWORK_DIRECT_DIAL_SLOT', fallback=1) except ValueError: - logger.warning('(%s) NETWORK_DIRECT_DIAL_SLOT is not an integer, defaulting to 0', section) - return 0 + logger.warning('(%s) NETWORK_DIRECT_DIAL_SLOT is not an integer, defaulting to 1', section) + return 1 if slot not in (0, 1, 2): - logger.warning('(%s) NETWORK_DIRECT_DIAL_SLOT is not 0, 1, or 2, defaulting to 0', section) - return 0 + logger.warning('(%s) NETWORK_DIRECT_DIAL_SLOT is not 0, 1, or 2, defaulting to 1', section) + return 1 return slot def master_timer_config(config, section): diff --git a/docker-configs/freedmr.cfg b/docker-configs/freedmr.cfg index 9dd9a97..67c5c90 100644 --- a/docker-configs/freedmr.cfg +++ b/docker-configs/freedmr.cfg @@ -61,7 +61,7 @@ SINGLE_MODE: True VOICE_IDENT: True DIAL_A_TG: True DYNAMIC_TG_ROUTING: True -NETWORK_DIRECT_DIAL_SLOT: 0 +NETWORK_DIRECT_DIAL_SLOT: 1 TS1_STATIC: TS2_STATIC: DEFAULT_DIAL_TS1: 0 diff --git a/docs/options-cheatsheet.md b/docs/options-cheatsheet.md index de13b5e..892211b 100644 --- a/docs/options-cheatsheet.md +++ b/docs/options-cheatsheet.md @@ -100,7 +100,7 @@ NDD_SLOT=2 | `TS2_TG_TIMER` | Slot 2 conventional TG timeout in minutes. | | `TS1_DIAL_TIMER` | Slot 1 dial-a-TG timeout in minutes. | | `TS2_DIAL_TIMER` | Slot 2 dial-a-TG timeout in minutes. | -| `NETWORK_DIRECT_DIAL_SLOT` | Network direct dial slot. `0` disables it, `1` presents on TG9 TS1, `2` presents on TG9 TS2. | +| `NETWORK_DIRECT_DIAL_SLOT` | Network direct dial slot. Default is `1`. `0` disables it, `1` presents on TG9 TS1, `2` presents on TG9 TS2. | | `DIALTG` | Enable/disable dial-a-TG private-call control. Use `1` or `0`. | | `DYNAMIC` | Enable/disable automatic dynamic conventional TG routing. Use `1` or `0`. | | `VOICE` | Enable/disable voice ident. Use `1` or `0`. | @@ -160,7 +160,7 @@ KEY=secret;TS1=91,92;TS2=235;DIAL1=4400;DIAL2=2350;TGTO1=10;TGTO2=10;DIALTO1=30; configured slot. It does not enable general private voice routing. - Network direct dial does not override an active or hangtime user-selected dial-a-TG route. -- Invalid `NETWORK_DIRECT_DIAL_SLOT` values in server config fall back to `0` +- Invalid `NETWORK_DIRECT_DIAL_SLOT` values in server config fall back to `1` and are logged. Invalid `NDD_SLOT`/`NETWORK_DIRECT_DIAL_SLOT` values in client `OPTIONS` are ignored and the current session value remains in use. - `DEFAULT_REFLECTOR`, `DIAL`, and `StartRef` only affect the slot-2 default. diff --git a/freedmr.cfg b/freedmr.cfg index 9dd9a97..67c5c90 100644 --- a/freedmr.cfg +++ b/freedmr.cfg @@ -61,7 +61,7 @@ SINGLE_MODE: True VOICE_IDENT: True DIAL_A_TG: True DYNAMIC_TG_ROUTING: True -NETWORK_DIRECT_DIAL_SLOT: 0 +NETWORK_DIRECT_DIAL_SLOT: 1 TS1_STATIC: TS2_STATIC: DEFAULT_DIAL_TS1: 0 diff --git a/tests/harness/deterministic.py b/tests/harness/deterministic.py index abce580..f7fa21a 100644 --- a/tests/harness/deterministic.py +++ b/tests/harness/deterministic.py @@ -315,7 +315,7 @@ def minimal_config(system_names: tuple[str, ...] = ("MASTER-A", "MASTER-B")) -> "VOICE_IDENT": False, "DIAL_A_TG": True, "DYNAMIC_TG_ROUTING": True, - "NETWORK_DIRECT_DIAL_SLOT": 0, + "NETWORK_DIRECT_DIAL_SLOT": 1, "TS1_STATIC": "", "TS2_STATIC": "", "DEFAULT_DIAL_TS1": 0, diff --git a/tests/harness/udp_blackbox.py b/tests/harness/udp_blackbox.py index d34ee71..6d03f37 100644 --- a/tests/harness/udp_blackbox.py +++ b/tests/harness/udp_blackbox.py @@ -469,7 +469,7 @@ def write_bridge_master_config( ts2_static: str = "91", dial_a_tg: bool = True, dynamic_tg_routing: bool = True, - network_direct_dial_slot: int = 0, + network_direct_dial_slot: int = 1, master_extra_config: str = "", ) -> None: global_use_acl_text = "True" if global_use_acl else "False" @@ -976,7 +976,7 @@ class UdpBlackBoxScenario: ts2_static: str = "91", dial_a_tg: bool = True, dynamic_tg_routing: bool = True, - network_direct_dial_slot: int = 0, + network_direct_dial_slot: int = 1, master_extra_config: str = "", fbp_systems: dict[str, int] | None = None, fbp_proto_versions: dict[str, int] | None = None, diff --git a/tests/test_deterministic_harness.py b/tests/test_deterministic_harness.py index 633aacb..d8099d9 100644 --- a/tests/test_deterministic_harness.py +++ b/tests/test_deterministic_harness.py @@ -84,7 +84,7 @@ DEFAULT_REFLECTOR: 0 self.assertEqual(parsed["ALIASES"]["STALE_TIME"], 86400) self.assertTrue(parsed["SYSTEMS"]["MASTER-A"]["DIAL_A_TG"]) self.assertTrue(parsed["SYSTEMS"]["MASTER-A"]["DYNAMIC_TG_ROUTING"]) - self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["NETWORK_DIRECT_DIAL_SLOT"], 0) + self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["NETWORK_DIRECT_DIAL_SLOT"], 1) self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["DEFAULT_DIAL_TS1"], 0) self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["DEFAULT_DIAL_TS2"], 0) @@ -142,7 +142,7 @@ DEFAULT_DIAL_TS2: 92 self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["DEFAULT_DIAL_TS2"], 92) self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["DEFAULT_REFLECTOR"], 92) - def test_config_invalid_network_direct_dial_slot_defaults_to_disabled(self): + def test_config_invalid_network_direct_dial_slot_defaults_to_ts1(self): for value in ("3", "A"): with self.subTest(value=value): config_text = f""" @@ -168,7 +168,7 @@ NETWORK_DIRECT_DIAL_SLOT: {value} finally: os.unlink(path) - self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["NETWORK_DIRECT_DIAL_SLOT"], 0) + self.assertEqual(parsed["SYSTEMS"]["MASTER-A"]["NETWORK_DIRECT_DIAL_SLOT"], 1) self.assertIn("NETWORK_DIRECT_DIAL_SLOT", "\n".join(logs.output)) def test_set_alias_updates_bridge_master_globals_and_shared_hblink_config(self): @@ -1342,8 +1342,9 @@ NETWORK_DIRECT_DIAL_SLOT: {value} self.assertEqual(fbp_entry["TO_TYPE"], "NONE") self.assertEqual(scenario.capture.packets, []) - def test_network_direct_dial_is_disabled_by_default(self): + def test_network_direct_dial_can_be_explicitly_disabled(self): config = minimal_config(("MASTER-A",)) + config["SYSTEMS"]["MASTER-A"]["NETWORK_DIRECT_DIAL_SLOT"] = 0 add_openbridge_system(config, "OBP-1", network_id=3001) with DeterministicScenario(config=config) as scenario: @@ -1355,9 +1356,8 @@ NETWORK_DIRECT_DIAL_SLOT: {value} self.assertNotIn("#1001", scenario.bridge_state) self.assertEqual(scenario.capture.for_system("MASTER-A"), []) - def test_network_direct_dial_routes_repeater_id_to_tg9_on_configured_slot(self): + def test_network_direct_dial_routes_repeater_id_to_tg9_on_default_ts1(self): config = minimal_config(("MASTER-A",)) - config["SYSTEMS"]["MASTER-A"]["NETWORK_DIRECT_DIAL_SLOT"] = 1 add_openbridge_system(config, "OBP-1", network_id=3001) with DeterministicScenario(config=config) as scenario: