Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package chirp for openSUSE:Factory checked 
in at 2026-05-23 23:26:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/chirp (Old)
 and      /work/SRC/openSUSE:Factory/.chirp.new.2084 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "chirp"

Sat May 23 23:26:48 2026 rev:71 rq:1354869 version:20260522

Changes:
--------
--- /work/SRC/openSUSE:Factory/chirp/chirp.changes      2026-05-15 
23:58:48.806207257 +0200
+++ /work/SRC/openSUSE:Factory/.chirp.new.2084/chirp.changes    2026-05-23 
23:28:39.379844803 +0200
@@ -1,0 +2,9 @@
+Sat May 23 17:13:36 UTC 2026 - Andreas Stieger <[email protected]>
+
+- Update to version 20260522:
+  * tdh8: Fix loading out-of-range group code values
+  * baofeng_uv17Pro: Fix uploading over BLE for supported models
+  * Add BLE serial detection
+  * mp31: Add support for Baofeng MP31
+
+-------------------------------------------------------------------

Old:
----
  chirp-20260515.obscpio

New:
----
  chirp-20260522.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ chirp.spec ++++++
--- /var/tmp/diff_new_pack.6cFdra/_old  2026-05-23 23:28:40.227879423 +0200
+++ /var/tmp/diff_new_pack.6cFdra/_new  2026-05-23 23:28:40.231879586 +0200
@@ -20,7 +20,7 @@
 
 %define pythons python3
 Name:           chirp
-Version:        20260515
+Version:        20260522
 Release:        0
 Summary:        Tool for programming amateur radio sets
 License:        GPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.6cFdra/_old  2026-05-23 23:28:40.259880729 +0200
+++ /var/tmp/diff_new_pack.6cFdra/_new  2026-05-23 23:28:40.263880892 +0200
@@ -4,8 +4,8 @@
     <param name="scm">git</param>
     <param name="changesgenerate">enable</param>
     <param name="filename">chirp</param>
-    <param name="versionformat">20260515</param>
-    <param name="revision">cb0e19f55fbd17b9485fcb7696fb9cd4863ccf58</param>
+    <param name="versionformat">20260522</param>
+    <param name="revision">c04781671024a690082f4a979287f96404ce9ad2</param>
   </service>
   <service mode="manual" name="set_version"/>
   <service name="tar" mode="buildtime"/>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.6cFdra/_old  2026-05-23 23:28:40.283881709 +0200
+++ /var/tmp/diff_new_pack.6cFdra/_new  2026-05-23 23:28:40.287881872 +0200
@@ -1,7 +1,7 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">https://github.com/kk7ds/chirp.git</param>
-    <param 
name="changesrevision">cb0e19f55fbd17b9485fcb7696fb9cd4863ccf58</param>
+    <param 
name="changesrevision">c04781671024a690082f4a979287f96404ce9ad2</param>
   </service>
 </servicedata>
 (No newline at EOF)

++++++ chirp-20260515.obscpio -> chirp-20260522.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/.gitignore 
new/chirp-20260522/.gitignore
--- old/chirp-20260515/.gitignore       2026-05-12 02:16:08.000000000 +0200
+++ new/chirp-20260522/.gitignore       2026-05-21 04:59:22.000000000 +0200
@@ -40,3 +40,4 @@
 result/
 # for nvim editor
 .nvim.lua
+.DS_Store
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/chirp/drivers/baofeng_uv17Pro.py 
new/chirp-20260522/chirp/drivers/baofeng_uv17Pro.py
--- old/chirp-20260515/chirp/drivers/baofeng_uv17Pro.py 2026-05-12 
02:16:08.000000000 +0200
+++ new/chirp-20260522/chirp/drivers/baofeng_uv17Pro.py 2026-05-21 
04:59:22.000000000 +0200
@@ -19,6 +19,7 @@
 from chirp.drivers import baofeng_common as bfc
 from chirp import chirp_common, directory, memmap, bandplan_na
 from chirp import bitwise
+from chirp import platform
 from chirp.settings import RadioSetting, \
     RadioSettingValueBoolean, RadioSettingValueList, \
     RadioSettingValueString, \
@@ -158,7 +159,7 @@
                           radio.BLOCK_SIZE):
             frame = radio._make_read_frame(addr, radio.BLOCK_SIZE)
 
-            radio.pipe.log('Sending request for %04x' % addr)
+            radio.pipe.log('Sending request for 0x%04x' % addr)
             bfc._rawsend(radio, frame)
 
             d = bfc._rawrecv(radio, radio.BLOCK_SIZE + 4)
@@ -173,7 +174,6 @@
 
             # UI Update
             status.cur = len(data) // radio.BLOCK_SIZE
-            status.msg = "Cloning from radio..."
             radio.status_fn(status)
     return data
 
@@ -494,7 +494,7 @@
 
     def _make_frame(self, cmd, addr, length, data=""):
         """Pack the info in the header format"""
-        frame = cmd + struct.pack(">i", addr)[2:] + struct.pack("b", length)
+        frame = cmd + struct.pack(">i", addr)[2:] + struct.pack("B", length)
         # add the data if set
         if len(data) != 0:
             frame += data
@@ -2358,7 +2358,10 @@
 
     MEM_TOTAL = 0x8240
 
+    _is_on_ble = False
+
     _has_support_for_banknames = False
+    _has_bt = True  # allow BT setting
 
     _idents = [MSTRING_UV17PROGPS]
     _mem_size = MEM_TOTAL
@@ -2385,6 +2388,81 @@
                    _uhf_rx2_range]
     MODES = UV17Pro.MODES + ['AM']
 
+    BLE_UP_BLOCK_SIZE = 0x80  # uploading to radio over BLE uses 0x80 blocksize
+
+    def sync_in(self):
+        self._is_on_ble = platform.get_platform().is_ble_serial(self.pipe)
+        LOG.debug('Detected BLE: %s' % self._is_on_ble)
+        return super().sync_in()
+
+    def sync_out(self):
+        self._is_on_ble = platform.get_platform().is_ble_serial(self.pipe)
+        LOG.debug('Detected BLE: %s' % self._is_on_ble)
+        return super().sync_out()
+
+    def _upload(radio):
+        """Upload to UV5R Mini (over BLE or USB/Serial)"""
+        # Put radio in program mode and identify it and
+        # determine if on BLE or USB/Serial connection
+        _do_ident(radio)
+
+        if radio._is_on_ble:  # BLE upload needs a diff blocksize
+            _blocksize = radio.BLE_UP_BLOCK_SIZE
+        else:
+            _blocksize = radio.BLOCK_SIZE
+
+        data = b""
+
+        # UI progress
+        status = chirp_common.Status()
+        status.cur = 0
+        status.max = radio.MEM_TOTAL // _blocksize
+        status.msg = "Cloning to radio on %s/Serial..." % \
+            ('BLE' if radio._is_on_ble else 'USB')
+        radio.status_fn(status)
+
+        data_addr = 0x00
+        radio_mem = radio.get_mmap()
+        radio.pipe.log('Uploading to radio using block size of 0x%04x'
+                       % _blocksize)
+        for i in range(len(radio.MEM_SIZES)):
+            MEM_SIZE = radio.MEM_SIZES[i]
+            MEM_START = radio.MEM_STARTS[i]
+            for addr in range(MEM_START, MEM_START + MEM_SIZE,
+                              _blocksize):
+                # calc min byte count to keep from reading too many bytes
+                byte_count = min(_blocksize, (MEM_START + MEM_SIZE) - addr)
+                data = radio_mem[data_addr:data_addr + byte_count]
+
+                if byte_count < _blocksize:  # does block need padding?
+                    radio.pipe.log('Padding partial block with \xff '
+                                   'by 0x%02x bytes' %
+                                   (_blocksize - len(data)))
+                    # pad partial block with \xff
+                    data += (b'\xff' * (_blocksize - len(data)))
+
+                if radio._uses_encr:
+                    data = _crypt(radio._encrsym, data)
+
+                data_addr += byte_count  # advance read pointer
+
+                frame = radio._make_frame(b"W", addr, _blocksize, data)
+                radio.pipe.log('Sending address %04x' % addr)
+                bfc._rawsend(radio, frame)
+
+                ack = bfc._rawrecv(radio, 1)
+                if ack != b"\x06":
+                    msg = "Bad ack writing block %04x" % addr
+                    raise errors.RadioError(msg)
+
+                # UI Update
+                status.cur = data_addr // _blocksize
+                radio.status_fn(status)
+
+        return data
+
+    upload_function = _upload
+
     _end_fmt = """
     // #seekto 0x8220;
     struct {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/chirp/drivers/h777.py 
new/chirp-20260522/chirp/drivers/h777.py
--- old/chirp-20260515/chirp/drivers/h777.py    2026-05-12 02:16:08.000000000 
+0200
+++ new/chirp-20260522/chirp/drivers/h777.py    2026-05-21 04:59:22.000000000 
+0200
@@ -27,6 +27,22 @@
 
 LOG = logging.getLogger(__name__)
 
+MEM_FORMAT_SETTINGS = """
+#seekto 0x02B0;
+struct {
+    u8 voiceprompt;
+    u8 voicelanguage;
+    u8 scan;
+    u8 vox;
+    u8 voxlevel;
+    u8 voxinhibitonrx;
+    u8 lowvolinhibittx;
+    u8 highvolinhibittx;
+    u8 alarm;
+    u8 fmradio;
+} settings;
+"""
+
 MEM_FORMAT = """
 #seekto 0x0010;
 struct {
@@ -44,20 +60,7 @@
        bcl:1;
     u8 unknown4[3];
 } memory[16];
-#seekto 0x02B0;
-struct {
-    u8 voiceprompt;
-    u8 voicelanguage;
-    u8 scan;
-    u8 vox;
-    u8 voxlevel;
-    u8 voxinhibitonrx;
-    u8 lowvolinhibittx;
-    u8 highvolinhibittx;
-    u8 alarm;
-    u8 fmradio;
-} settings;
-"""
+""" + MEM_FORMAT_SETTINGS
 
 H777_SETTINGS2 = """
 #seekto 0x03C0;
@@ -656,6 +659,65 @@
         return False
 
 
+MP31_MEM_FORMAT = """
+#seekto 0x0000;
+struct {
+    lbcd rxfreq[4];
+    lbcd txfreq[4];
+    lbcd rxtone[2];
+    lbcd txtone[2];
+    u8 unknown3:1,
+       unknown2:1,
+       unknown1:1,
+       skip:1,
+       highpower:1,
+       narrow:1,
+       beatshift:1,
+       bcl:1;
+    u8 unknown4[3];
+} memory[38];
+"""
+
+MP31_SETTINGS2 = """
+#seekto 0x026B;
+struct {
+    u8 squelchlevel;
+    u8 batterysaver;
+    u8 voxdelay;
+    u8 timeouttimer;
+    u8 scanmode;
+    u8 beep;
+    u8 sidekey;
+    u8 rxemergency;
+} settings2;
+"""
+
+
[email protected]
+class MP31Radio(H777Radio):
+    """Baofeng MP31"""
+    VENDOR = "Baofeng"
+    MODEL = "MP31"
+    IDENT = [b"P3107\xf7\x00\x00"]
+    _ranges = [(0x0000, 0x0400)]
+    _memsize = 0x0400
+    _has_sidekey = False
+    ALIASES = []
+
+    def process_mmap(self):
+        self._memobj = bitwise.parse(
+            MP31_MEM_FORMAT + MP31_SETTINGS2 + MEM_FORMAT_SETTINGS, self._mmap)
+
+    def get_features(self):
+        rf = super().get_features()
+        rf.memory_bounds = (1, 38)
+        return rf
+
+    @classmethod
+    def match_model(cls, filedata, filename):
+        return False
+
+
 class H777TestCase(unittest.TestCase):
 
     def setUp(self):
@@ -703,6 +765,23 @@
         self.driver._encode_tone(self.testdata.foo, '', 67.0, 'N')
         self.assertEqual(16665, int(self.testdata.foo))
 
+    def test_mp31_38_channels(self):
+        radio = MP31Radio(None)
+        rf = radio.get_features()
+        self.assertEqual(rf.memory_bounds, (1, 38))
+
+    def test_mp31_memsize(self):
+        radio = MP31Radio(None)
+        self.assertEqual(radio._memsize, 0x0400)
+
+    def test_mp31_ranges(self):
+        radio = MP31Radio(None)
+        self.assertEqual(radio._ranges, [(0x0000, 0x0400)])
+
+    def test_mp31_ident(self):
+        radio = MP31Radio(None)
+        self.assertIn(b"P3107\xf7\x00\x00", radio.IDENT)
+
 
 @directory.register
 class ROGA2SRadio(H777Radio):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/chirp/drivers/tdh8.py 
new/chirp-20260522/chirp/drivers/tdh8.py
--- old/chirp-20260515/chirp/drivers/tdh8.py    2026-05-12 02:16:08.000000000 
+0200
+++ new/chirp-20260522/chirp/drivers/tdh8.py    2026-05-21 04:59:22.000000000 
+0200
@@ -1965,11 +1965,15 @@
                 gcode_val = ""
             else:
                 gcode_val = gcode_val[1]
+            try:
+                cur = GROUPCODE.index(gcode_val)
+            except ValueError:
+                cur = len(GROUPCODE)
             rs = RadioSetting(
                     "gcode", "Group Code",
                     RadioSettingValueList(
                         GROUPCODE,
-                        current_index=GROUPCODE.index(gcode_val)))
+                        current_index=cur))
             dtmf.append(rs)
 
             icode_list = self._memobj.icode.idcode
@@ -2156,8 +2160,8 @@
     def get_settings(self):
         try:
             return self._get_settings()
-        except Exception:
-            raise InvalidValueError("Setting Failed!")
+        except Exception as e:
+            raise InvalidValueError("Setting Failed!") from e
 
     def set_settings(self, settings):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/chirp/platform.py 
new/chirp-20260522/chirp/platform.py
--- old/chirp-20260515/chirp/platform.py        2026-05-12 02:16:08.000000000 
+0200
+++ new/chirp-20260522/chirp/platform.py        2026-05-21 04:59:22.000000000 
+0200
@@ -182,6 +182,9 @@
 
         return ver
 
+    def is_ble_serial(self, serial):
+        return serial.port.startswith('/tmp/ttyBLE')
+
 
 class Win32Platform(Platform):
     """A platform module suitable for Windows systems"""
@@ -230,6 +233,48 @@
         return vers.get(pform,
                         "Win32 (Unknown %i.%i:%i)" % (pform, sub, build))
 
+    def is_ble_serial(self, serial):
+        import winreg
+
+        max_ports = 255
+        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
+                             r'HARDWARE\DEVICEMAP\SERIALCOMM')
+        devices = {}
+        for i in range(max_ports):
+            try:
+                # device is something like \Device\com0com24
+                # name is something like COM12
+                device, name, _ = winreg.EnumValue(key, i)
+                devices[name] = device
+            except EnvironmentError:
+                break
+
+        LOG.debug('All device/name pairs: %s' % devices)
+
+        try:
+            # ble-serial names its device BLE, so find it
+            ble_device = devices.get('BLE')
+        except KeyError:
+            LOG.debug('No BLE device found')
+            sys.exit(1)
+
+        # The pair device appears to always be \Device\com0com14 if
+        # the BLE device is \Device\com0com24
+        pair_device = list(ble_device)
+        # Change 2 to 1 to get the first device of the pair
+        pair_device[-2] = '1'
+        pair_device = ''.join(pair_device)
+        LOG.debug('Found BLE device %s, guessing pair is %s' % (
+            device, pair_device))
+        try:
+            pair_name = dict(((v, k) for k, v in devices.items()))[pair_device]
+        except KeyError:
+            LOG.debug('Pair device not found!')
+        else:
+            LOG.info('BLE pair device is %s' % pair_name)
+
+        return serial.port == pair_name
+
 
 def _get_platform(basepath):
     if os.name == "nt":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/chirp/share/model_alias_map.yaml 
new/chirp-20260522/chirp/share/model_alias_map.yaml
--- old/chirp-20260515/chirp/share/model_alias_map.yaml 2026-05-12 
02:16:08.000000000 +0200
+++ new/chirp-20260522/chirp/share/model_alias_map.yaml 2026-05-21 
04:59:22.000000000 +0200
@@ -376,3 +376,6 @@
 Powerful:
 - alt: Quansheng UV-K5
   model: UV-S5
+Pxton:
+- alt: Baofeng MP31
+  model: 999S
Binary files old/chirp-20260515/tests/images/Baofeng_MP31.img and 
new/chirp-20260522/tests/images/Baofeng_MP31.img differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260515/tests/test_clone.py 
new/chirp-20260522/tests/test_clone.py
--- old/chirp-20260515/tests/test_clone.py      2026-05-12 02:16:08.000000000 
+0200
+++ new/chirp-20260522/tests/test_clone.py      2026-05-21 04:59:22.000000000 
+0200
@@ -16,6 +16,10 @@
 
 
 class SerialNone(serialtrace.SerialTrace):
+    def __init__(self, *a, **k):
+        super().__init__(*a, **k)
+        self.port = '/dev/ttyUSB0'
+
     def flush(self):
         pass
 

++++++ chirp.obsinfo ++++++
--- /var/tmp/diff_new_pack.6cFdra/_old  2026-05-23 23:28:41.535932822 +0200
+++ /var/tmp/diff_new_pack.6cFdra/_new  2026-05-23 23:28:41.535932822 +0200
@@ -1,5 +1,5 @@
 name: chirp
-version: 20260515
-mtime: 1778544968
-commit: cb0e19f55fbd17b9485fcb7696fb9cd4863ccf58
+version: 20260522
+mtime: 1779332362
+commit: c04781671024a690082f4a979287f96404ce9ad2
 

Reply via email to