Addressing bug #5275.

1. Rename field 'unknown' to 'empty'
   This field is used to detect if a channel is empty or not. This was known and 
   used before but the field name was never adapted until now.

2. Replace #seekto instructions with unknown fields
   Using #seekto for the parts of the memory struct that are yet unknown leads
   to the problem that is described in bug #5275. Instead of not touching those
   fields, we should fill them with the values used and set by the official
   Alinco software. Being able to address the fields with unknown1 .. unknown4
   is a precondition for this.

3. Set unknown fields to "default" values as described above in set_memory()

4. When clearing a channel, we fill the memory with 0xff instead of just setting
   the flag indicating that the channel is empty. It is unclear whether that is
   really necessary but doing it the same way as the official programming
   software can't harm.

5. Since previous versions of the code have not touched the unknown fields,
   those fields keept the byte values of an empty channel (0xff) when the channel
   was put to use with chirp. As a consequence, there are now images with those
   stale 0xff byte values in active channels. As explaiend in the bug description,
   the radio seems to be OK with that but the Alinco programming software fails to
   read a radio that is programmed in this manner. A log warning is emitted if such
   a condition is encountered such that the user can rectify the situation.

6. Previously, 0x00 was stored in the empty field of an empty channel and 0x02
   otherwise. Investigating bug #5275 revealed that 0x01 is actually used for a
   channel that can only be received in the sub-band. The radio hides such
   channels from the main band. New code was added to implement this in chirp.


diff -r 81d929aaee0f chirp/drivers/alinco.py
--- a/chirp/drivers/alinco.py	Thu Oct 19 12:02:09 2017 -0700
+++ b/chirp/drivers/alinco.py	Fri Nov 03 10:13:57 2017 +0100
@@ -577,7 +577,7 @@
 ul16 special_bank[7];
 #seekto 0x1200;
 struct {
-    u8   unknown;
+    u8   empty;
     ul32 freq;
     u8   mode;
     u8   step;
@@ -587,9 +587,11 @@
     u8   tx_tone;
     u8   rx_tone;
     u8   dcs;
-#seek 3;
+    ul24 unknown1;
     u8   skip;
-#seek 12;
+    ul32 unknown2;
+    ul32 unknown3;
+    ul32 unknown4;
     char name[32];
 } memory[1000];
 """
@@ -740,14 +742,43 @@
                 status.msg = "Uploading to radio"
                 self.status_fn(status)
 
+    def _get_empty_flag(self, freq):
+        if     (freq >=  136000000 and freq <  174000000) or \
+               (freq >=  400000000 and freq <  470000000) or \
+               (freq >= 1240000000 and freq < 1300000000):
+            return 0x02
+        else:
+            return 0x01
+
+    def _check_channel_consistency(self, number):
+        _mem = self._memobj.memory[number]
+        if _mem.empty != 0x00:
+            if _mem.unknown1 == 0xffffff:
+                # Previous versions of this code have skipped the unknown
+                # fields. They contain bytes of value if the channel is empty and
+                # thus those bytes remain 0xff when the channel is put to use.
+                # The radio is totally fine with this but the Alinco programming
+                # software is not (see #5275). Here, we check for this and
+                # report if it is encountered.
+                LOG.warning("Channel %d is inconsistent: Found 0xff in non-empty channel. Touch channel to fix." % number)
+
+            if _mem.empty != self._get_empty_flag(_mem.freq):
+                LOG.warning("Channel %d is inconsistent: Found out of band frequency. Touch channel to fix." % number)
+
     def process_mmap(self):
         self._memobj = bitwise.parse(DJG7EG_MEM_FORMAT, self._mmap)
+        # We check all channels for corruption (see bug #5275) but we don't fix
+        # it automatically because it would be unpolite to modify something on a
+        # read operation. A log message is emitted though for the user to take
+        # actions.
+        for number in range(len(self._memobj.memory)):
+            self._check_channel_consistency(number)
 
     def get_memory(self, number):
         _mem = self._memobj.memory[number]
         mem = chirp_common.Memory()
         mem.number = number
-        if _mem.unknown == 0:
+        if _mem.empty == 0:
             mem.empty = True
         else:
             mem.freq = int(_mem.freq)
@@ -774,9 +805,10 @@
         # Get a low-level memory object mapped to the image
         _mem = self._memobj.memory[mem.number]
         if mem.empty:
-            _mem.unknown = 0x00  # Maybe 0 is empty, 2 is used?
+            _mem.set_raw("\xff" * (_mem.size()/8))
+            _mem.empty = 0x00
         else:
-            _mem.unknown = 0x02
+            _mem.empty = self._get_empty_flag(mem.freq)
             _mem.freq = mem.freq
             _mem.mode = self.MODES.index(mem.mode)
             _mem.step = self.STEPS.index(mem.tuning_step)
@@ -819,3 +851,7 @@
             _mem.dcs = DCS_CODES[self.VENDOR].index(mem.dtcs)
             _mem.skip = (mem.skip == "S")
             _mem.name = "\x00".join(mem.name).ljust(32, "\x00")
+            _mem.unknown1 = 0x3e001c
+            _mem.unknown2 = 0x0000000a
+            _mem.unknown3 = 0x00000000
+            _mem.unknown4 = 0x00000000
