# HG changeset patch # User Richard Cochran ag6qr@sonic.net # Date 1426824504 25200 # Thu Mar 19 21:08:24 2015 -0700 # Node ID 4a118c9afda7f5fc4781be63d630fca1dbeaa570 # Parent 5c8ac5597f34af143915667c51ed5882e97e30f7 [ft2900] Fix cross tone when channel entered via Radio panel (#2445) This submission makes FT-2900 cross tone support more robust, and protects against a problem where the radio would sometimes use the high order bit of the tone and/or DTCS code field as a bit flag. The code had been using the entire byte as an index into the TONES or DTCS_CODES array, and when the high order bit was set, the value was too high by 128, resulting an array bounds error. Fix is to alter MEM_FORMAT to separate the high order bit flags from the lower 7 bit tone and code fields. This also adds some error checking via a "try" block to catch any remaining array bounds errors (though none are expected). And it adds code which attempts to set those bit flags the way the radio would have set them, even though the flags seem to have no effect on the way the radio transmits or receives.
Thanks to Chris Fosnight for finding and reporting the problem.
diff -r 5c8ac5597f34 -r 4a118c9afda7 chirp/drivers/ft2900.py --- a/chirp/drivers/ft2900.py Mon Mar 16 21:00:42 2015 -0700 +++ b/chirp/drivers/ft2900.py Thu Mar 19 21:08:24 2015 -0700 @@ -205,11 +205,15 @@ tmode:3; u8 name[6]; bbcd offset[3]; - u8 ctone; - u8 rx_dtcs; + u8 ctonesplitflag:1, + ctone:7; + u8 rx_dtcssplitflag:1, + rx_dtcs:7; u8 unknown5; - u8 rtone; - u8 dtcs; + u8 rtonesplitflag:1, + rtone:7; + u8 dtcssplitflag:1, + dtcs:7; } memory[200];
""" @@ -229,6 +233,24 @@ STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0]
+def _decode_tone(radiotone): + try: + chirptone = chirp_common.TONES[radiotone] + except IndexError: + chirptone = 100 + LOG.debug("found invalid radio tone: %i\n" % radiotone) + return chirptone + + +def _decode_dtcs(radiodtcs): + try: + chirpdtcs = chirp_common.DTCS_CODES[radiodtcs] + except IndexError: + chirpdtcs = 23 + LOG.debug("found invalid radio dtcs code: %i\n" % radiodtcs) + return chirpdtcs + + def _decode_name(mem): name = "" for i in mem: @@ -359,17 +381,19 @@ else: mem.tmode = "Cross" mem.cross_mode = CROSS_MODES[_mem.tmode - TMODES.index("Cross")] - mem.rtone = chirp_common.TONES[_mem.rtone] - mem.ctone = chirp_common.TONES[_mem.ctone] + + mem.rtone = _decode_tone(_mem.rtone) + mem.ctone = _decode_tone(_mem.ctone)
# check for unequal ctone/rtone in TSQL mode. map it as a # cross tone mode - if mem.rtone != mem.ctone and mem.tmode == "TSQL": + if mem.rtone != mem.ctone and (mem.tmode == "TSQL" or + mem.tmode == "Tone"): mem.tmode = "Cross" mem.cross_mode = "Tone->Tone"
- mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] - mem.rx_dtcs = chirp_common.DTCS_CODES[_mem.rx_dtcs] + mem.dtcs = _decode_dtcs(_mem.dtcs) + mem.rx_dtcs = _decode_dtcs(_mem.rx_dtcs)
# check for unequal dtcs/rx_dtcs in DTCS mode. map it as a # cross tone mode @@ -434,14 +458,16 @@ _mem.rx_dtcs = chirp_common.DTCS_CODES.index(mem.rx_dtcs) if mem.cross_mode == "Tone->Tone": # tone->tone cross mode is treated as - # TSQL, but with separate tones for + # Tone, but with separate tones for # send and receive - _mem.tmode = TMODES.index("TSQL") + _mem.tmode = TMODES.index("Tone") + _mem.rtonesplitflag = 1 elif mem.cross_mode == "DTCS->DTCS": # DTCS->DTCS cross mode is treated as # DTCS, but with separate codes for # send and receive _mem.tmode = TMODES.index("DTCS") + _mem.dtcssplitflag = 1 else: _mem.tmode = TMODES.index("Cross") + \ CROSS_MODES.index(mem.cross_mode)