Example #1
0
    def set_memory(self, memory):
        if memory.number < 0 or memory.number > self._upper:
            raise errors.InvalidMemoryLocation(
                "Number must be between 0 and %i" % self._upper)

        spec = self._make_mem_spec(memory)
        spec = "".join(spec)
        r1 = command(self.pipe, *self._cmd_set_memory(memory.number, spec))
        if not iserr(r1):
            memory.name = memory.name.rstrip()
            self._memcache[memory.number] = memory

            # if we're tuned to the channel, reload it
            r1 = command(self.pipe, *self._cmd_cur_memory(memory.number))
            if not iserr(r1):
                pattern = re.compile("MC([0-9]{3})")
                match = pattern.search(r1)
                if match is not None:
                    cur_mem = int(match.group(1))
                    if cur_mem == memory.number:
                        cur_mem = \
                            command(self.pipe,
                                    *self._cmd_recall_memory(memory.number))
        else:
            raise errors.InvalidDataError("Radio refused %i" % memory.number)

        # FIXME
        if memory.duplex == "split" and self._kenwood_split:
            spec = "".join(self._make_split_spec(memory))
            result = command(self.pipe,
                             *self._cmd_set_split(memory.number, spec))
            if iserr(result):
                raise errors.InvalidDataError("Radio refused %i" %
                                              memory.number)
Example #2
0
    def set_memory(self, memory):
        if memory.number < 0 or memory.number > self._upper:
            raise errors.InvalidMemoryLocation(
                "Number must be between 0 and %i" % self._upper)

        spec = self._make_mem_spec(memory)
        spec = ",".join(spec)
        r1 = command(self.pipe, *self._cmd_set_memory(memory.number, spec))
        if not iserr(r1):
            time.sleep(0.5)
            r2 = command(
                self.pipe,
                *self._cmd_set_memory_name(memory.number, memory.name))
            if not iserr(r2):
                memory.name = memory.name.rstrip()
                self._memcache[memory.number] = memory
            else:
                raise errors.InvalidDataError(
                    "Radio refused name %i: %s" %
                    (memory.number, repr(memory.name)))
        else:
            raise errors.InvalidDataError("Radio refused %i" % memory.number)

        if memory.duplex == "split" and self._kenwood_split:
            spec = ",".join(self._make_split_spec(memory))
            result = command(self.pipe,
                             *self._cmd_set_split(memory.number, spec))
            if iserr(result):
                raise errors.InvalidDataError("Radio refused %i" %
                                              memory.number)
Example #3
0
def set_call_indices(_map, mmap, urcall, r1call, r2call):
    ulist = []
    for i in range(0, 6):
        ulist.append(get_urcall(_map, i))

    rlist = []
    for i in range(0, 6):
        rlist.append(get_rptcall(_map, i))

    try:
        if not urcall:
            uindex = 0
        else:
            uindex = ulist.index(urcall)
    except ValueError:
        raise errors.InvalidDataError("Call `%s' not in URCALL list" % urcall)

    try:
        if not r1call:
            r1index = 0
        else:
            r1index = rlist.index(r1call)
    except ValueError:
        raise errors.InvalidDataError("Call `%s' not in RCALL list" % r1call)

    try:
        if not r2call:
            r2index = 0
        else:
            r2index = rlist.index(r2call)
    except ValueError:
        raise errors.InvalidDataError("Call `%s' not in RCALL list" % r2call)

    mmap[18] = (ord(mmap[18]) & 0xF0) | uindex
    mmap[19] = (r1index << 4) | r2index
Example #4
0
def send_magic(pipe):
    """Send the magic incantation to wake up an ic9x radio"""
    if pipe.getBaudrate() == 38400:
        resp = _send_magic_38400(pipe)
        if resp:
            return
        print "Switching from 38400 to 4800"
        pipe.setBaudrate(4800)
        resp = _send_magic_4800(pipe)
        pipe.setBaudrate(38400)
        if resp:
            return
        raise errors.RadioError("Radio not responding")
    elif pipe.getBaudrate() == 4800:
        resp = _send_magic_4800(pipe)
        if resp:
            return
        print "Switching from 4800 to 38400"
        pipe.setBaudrate(38400)
        resp = _send_magic_38400(pipe)
        if resp:
            return
        pipe.setBaudrate(4800)
        raise errors.RadioError("Radio not responding")
    else:
        raise errors.InvalidDataError("Radio in unknown state (%i)" % \
                                          pipe.getBaudrate())
Example #5
0
    def send(self, pipe, verbose=False):
        rframes = ic9x_send(pipe, self.get_raw())

        if len(rframes) == 0:
            raise errors.InvalidDataError("No response from radio")

        return rframes
Example #6
0
def fix_rounded_step(freq):
    """Some radios imply the last bit of 12.5kHz and 6.25kHz step
    frequencies. Take the base @freq and return the corrected one"""
    try:
        required_step(freq)
        return freq
    except errors.InvalidDataError:
        pass

    try:
        required_step(freq + 500)
        return freq + 500
    except errors.InvalidDataError:
        pass

    try:
        required_step(freq + 250)
        return freq + 250
    except errors.InvalidDataError:
        pass

    try:
        required_step(freq + 750)
        return float(freq + 750)
    except errors.InvalidDataError:
        pass

    raise errors.InvalidDataError("Unable to correct rounded frequency " +
                                  format_freq(freq))
Example #7
0
 def set_skip(self, number, skip):
     if skip == "S":
         self.memobj.tv_channel_skip[number] = 2
     elif skip == "":
         self.memobj.tv_channel_skip[number] = 0
     else:
         raise errors.InvalidDataError("skip '%s' not supported" % skip)
Example #8
0
def send_magic(pipe):
    """Send the magic incantation to wake up an ic9x radio"""
    if pipe.baudrate == 38400:
        resp = _send_magic_38400(pipe)
        if resp:
            return
        LOG.info("Switching from 38400 to 4800")
        pipe.baudrate = 4800
        resp = _send_magic_4800(pipe)
        pipe.baudrate = 38400
        if resp:
            return
        raise errors.RadioError("Radio not responding")
    elif pipe.baudrate == 4800:
        resp = _send_magic_4800(pipe)
        if resp:
            return
        LOG.info("Switching from 4800 to 38400")
        pipe.baudrate = 38400
        resp = _send_magic_38400(pipe)
        if resp:
            return
        pipe.baudrate = 4800
        raise errors.RadioError("Radio not responding")
    else:
        raise errors.InvalidDataError("Radio in unknown state (%i)" %
                                      pipe.baudrate)
Example #9
0
    def _ic9x_set_banks(self, banks):

        if len(banks) != len(self.__bankcache.keys()):
            raise errors.InvalidDataError(
                "Invalid bank list length (%i:%i)" %
                (len(banks), len(self.__bankcache.keys())))

        cached_names = [
            str(self.__bankcache[x]) for x in sorted(self.__bankcache.keys())
        ]

        need_update = False
        for i in range(0, 26):
            if banks[i] != cached_names[i]:
                need_update = True
                self.__bankcache[i] = banks[i]
                LOG.dbeug("Updating %s: %s -> %s" %
                          (chr(i + ord("A")), cached_names[i], banks[i]))

        if need_update:
            self._lock.acquire()
            try:
                self._maybe_send_magic()
                ic9x_ll.set_banks(self.pipe, self.vfo, banks)
            except:
                self._lock.release()
                raise

            self._lock.release()
Example #10
0
    def _process_frames(self):
        if not self.data.startswith("\xFE\xFE"):
            raise errors.InvalidDataError("Out of sync with radio")
        elif len(self.data) < 5:
            return []  # Not enough data for a full frame

        frames = []

        while self.data:
            try:
                cmd = ord(self.data[4])
            except IndexError:
                break  # Out of data

            try:
                frame, rest = parse_frame_generic(self.data)
                if not frame:
                    break
                elif frame.src == 0xEE and frame.dst == 0xEF:
                    # PC echo, ignore
                    pass
                else:
                    frames.append(frame)

                self.data = rest
            except errors.InvalidDataError, e:
                LOG.error("Failed to parse frame (cmd=%i): %s" % (cmd, e))
                return []
Example #11
0
def get_mycall(mmap, index):
    if index > 5:
        raise errors.InvalidDataError("MYCALL index %i must be <= 5" % index)

    start = call_location(POS_MYCALL, index)

    return mmap[start:start + 8].rstrip()
Example #12
0
    def _encode_tone(self, memtone, meminv, mode, tone, pol):
        """Parse the tone data to encode from UI to mem"""

        if mode == '' or mode is None:
            memtone.set_value(0)
            meminv.set_value(0)
        elif mode == 'Tone':
            # caching errors for analog tones.
            try:
                memtone.set_value(TONES.index(tone) + 1)
                meminv.set_value(0)
            except:
                msg = "TCSS Tone '%d' is not supported" % tone
                LOG.error(msg)
                raise errors.RadioError(msg)

        elif mode == 'DTCS':
            # caching errors for digital tones.
            try:
                memtone.set_value(DTCS.index(tone) + 51)
                if pol == "R":
                    meminv.set_value(True)
                else:
                    meminv.set_value(False)
            except:
                msg = "Digital Tone '%d' is not supported" % tone
                LOG.error(msg)
                raise errors.RadioError(msg)
        else:
            msg = "Internal error: invalid mode '%s'" % mode
            LOG.error(msg)
            raise errors.InvalidDataError(msg)
Example #13
0
def erase_memory(pipe, vfo, number):
    """Erase memory @number on @vfo via @pipe"""
    frame = IC92MemClearFrame(number)
    frame.set_vfo(vfo)

    rframe = frame.send(pipe)
    if rframe.get_raw()[2] != "\xfb":
        raise errors.InvalidDataError("Radio reported error")
Example #14
0
def set_mycall(mmap, index, call):
    if index > 5:
        raise errors.InvalidDataError("MYCALL index %i must be <= 5" % index)

    start = call_location(POS_MYCALL, index)

    mmap[start] = call.ljust(12)

    return mmap
Example #15
0
    def load(self, filename=None):
        if filename is None and self._filename is None:
            raise errors.RadioError("Need a location to load from")

        if filename:
            self._filename = filename

        self._blank()

        f = open(self._filename, "r")
        for line in f:
            if line.strip() == "// Memory Channels":
                break

        reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"')

        good = 0
        lineno = 0
        for line in reader:
            lineno += 1
            if lineno == 1:
                header = line
                continue

            if len(header) > len(line):
                LOG.debug("Line %i has %i columns, expected %i" %
                          (lineno, len(line), len(header)))
                self.errors.append("Column number mismatch on line %i" %
                                   lineno)
                continue

            # hmk stores Tx Freq. in its own field, but Chirp expects the Tx
            # Freq. for odd-split channels to be in the Offset field.
            # If channel is odd-split, copy Tx Freq. field to Offset field.
            if line[header.index('Shift/Split')] == "S":
                line[header.index('Offset')] = line[header.index('Tx Freq.')]

            # fix EU decimal
            line = [i.replace(',', '.') for i in line]

            try:
                mem = self._parse_csv_data_line(header, line)
                if mem.number is None:
                    raise Exception("Invalid Location field" % lineno)
            except Exception as e:
                LOG.error("Line %i: %s" % (lineno, e))
                self.errors.append("Line %i: %s" % (lineno, e))
                continue

            self._grow(mem.number)
            self.memories[mem.number] = mem
            good += 1

        if not good:
            for e in errors:
                LOG.error("kenwood_hmk: %s", e)
            raise errors.InvalidDataError("No channels found")
Example #16
0
    def set_memory(self, mem):
        _mem = self._memobj.memory[mem.number - 1]
        _flg = self._memobj.flags[mem.number - 1]

        _flg.empty = mem.empty
        if mem.empty:
            self._set_bank(mem.number, None)
            return

        mult = chirp_common.is_fractional_step(mem.freq) and 6250 or 5000
        _mem.mult_flag = mult == 6250
        _mem.freq = mem.freq / mult
        _mem.offset = mem.offset / 5000
        _mem.duplex = DUPLEX.index(mem.duplex)
        _mem.mode = MODES.index(mem.mode)
        _mem.tmode = TMODES.index(mem.tmode)
        _mem.rtone = chirp_common.TONES.index(mem.rtone)
        _mem.ctone = chirp_common.TONES.index(mem.ctone)
        _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs)
        _mem.dtcs_polarity = DTCS_POL.index(mem.dtcs_polarity)
        _mem.tuning_step = STEPS.index(mem.tuning_step)
        set_name(_mem, mem.name)

        _flg.pskip = mem.skip == "P"
        _flg.skip = mem.skip == "S"

        if mem.mode == "DV":
            urcalls = self.get_urcall_list()
            rptcalls = self.get_repeater_call_list()
            if not isinstance(mem, chirp_common.DVMemory):
                raise errors.InvalidDataError("DV mode is not a DVMemory!")
            try:
                err = mem.dv_urcall
                _mem.urcall = urcalls.index(mem.dv_urcall)
                err = mem.dv_rpt1call
                _mem.rpt1call = rptcalls.index(mem.dv_rpt1call)
                err = mem.dv_rpt2call
                _mem.rpt2call = rptcalls.index(mem.dv_rpt2call)
            except IndexError:
                raise errors.InvalidDataError("DV Call %s not in list" % err)
        else:
            _mem.urcall = 0
            _mem.rpt1call = 0
            _mem.rpt2call = 0
Example #17
0
def set_skip(mmap, number, skip):
    if skip == "P":
        raise errors.InvalidDataError("PSKIP not supported by this model")

    val = struct.unpack("B", mmap[POS_FLAGS_START + number])[0] & 0xEF

    if skip == "S":
        val |= 0x10

    mmap[POS_FLAGS_START + number] = val
Example #18
0
    def load(self, filename=None):
        if filename is None and self._filename is None:
            raise errors.RadioError("Need a location to load from")

        if filename:
            self._filename = filename

        self._blank()

        f = file(self._filename, "r")
        for line in f:
            if line.strip() == "// Conventional Data":
                break

        reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"')

        good = 0
        lineno = 0
        for line in reader:
            lineno += 1
            if lineno == 1:
                header = line
                continue

            if len(line) == 0:
                # End of channel data
                break

            if len(header) > len(line):
                LOG.error("Line %i has %i columns, expected %i" %
                          (lineno, len(line), len(header)))
                self.errors.append("Column number mismatch on line %i" %
                                   lineno)
                continue

            # fix EU decimal
            line = [i.replace(',', '.') for i in line]

            try:
                mem = self._parse_csv_data_line(header, line)
                if mem.number is None:
                    raise Exception("Invalid Location field" % lineno)
            except Exception as e:
                LOG.error("Line %i: %s" % (lineno, e))
                self.errors.append("Line %i: %s" % (lineno, e))
                continue

            self._grow(mem.number)
            self.memories[mem.number] = mem
            good += 1

        if not good:
            for e in errors:
                LOG.error("kenwood_itm: %s", e)
            raise errors.InvalidDataError("No channels found")
Example #19
0
    def send(self, pipe, verbose=False):
        """Send the frame to the radio via @pipe"""
        if verbose:
            print "Sending:\n%s" % util.hexprint(self.get_raw())

        response = ic9x_send(pipe, self.get_raw())

        if len(response) == 0:
            raise errors.InvalidDataError("No response from radio")

        return response[0]
Example #20
0
def set_banks(pipe, vfo, banks):
    """Set banks for @vfo via @pipe"""
    for i in range(0, 26):
        bframe = IC92BankFrame()
        bframe.set_vfo(vfo)
        bframe.set_identifier(chr(i + ord("A")))
        bframe.set_name(banks[i])

        rframe = bframe.send(pipe)
        if rframe.get_payload() != "\xfb":
            raise errors.InvalidDataError("Radio reported error")
Example #21
0
def get_tune_step(mmap):
    tsidx = struct.unpack("B", mmap[POS_TUNE_STEP])[0] & 0xF0
    tsidx >>= 4
    icx8x_ts = list(chirp_common.TUNING_STEPS)
    del icx8x_ts[1]

    try:
        return icx8x_ts[tsidx]
    except IndexError:
        raise errors.InvalidDataError("TS index %i out of range (%i)" %
                                      (tsidx, len(icx8x_ts)))
Example #22
0
def set_bank(mmap, number, bank):
    if bank is not None and bank > 9:
        raise errors.InvalidDataError("Invalid bank number %i" % bank)

    if bank is None:
        index = 0x0A
    else:
        index = bank

    val = ord(mmap[POS_FLAGS_START + number]) & 0xF0
    val |= index
    mmap[POS_FLAGS_START + number] = val
Example #23
0
 def set_skip(self, number, skip):
     bank_item = self.memobj.banks[number]
     if skip == "P":
         bank_item.prog_skip = 1
         bank_item.mem_skip = 1
     elif skip == "S":
         bank_item.prog_skip = 0
         bank_item.mem_skip = 1
     elif skip == "":
         bank_item.prog_skip = 0
         bank_item.mem_skip = 0
     else:
         raise errors.InvalidDataError("skip '%s' not supported" % skip)
Example #24
0
 def map_dtmf_chirp2icom(self, item):
     item = str(item).upper()
     if item == "*":
         item = "E"
     elif item == "#":
         item = "F"
     elif item == " ":
         return 0xff
     try:
         ret = int(item, 16)
     except ValueError:
         raise errors.InvalidDataError("invalid DTMF number '%s'" % item)
     return ret
Example #25
0
    def set_memory(self, memory):
        if memory.number < 0 or memory.number > self._upper:
            raise errors.InvalidMemoryLocation(
                "Number must be between 0 and %i" % self._upper)

        if memory.number > 90:
            if memory.duplex == TS850_DUPLEX[0]:
                memory.duplex = TS850_DUPLEX[1]
                memory.offset = memory.freq
            else:
                if memory.freq > memory.offset:
                    temp = memory.freq
                    memory.freq = memory.offset
                    memory.offset = temp

        # Clear out memory contents to prevent errors
        spec = self._make_base_spec(memory, 0)
        spec = "".join(spec)
        result = command(self.pipe, *self._cmd_set_memory(memory.number, spec))

        if iserr(result):
            raise errors.InvalidDataError("Radio refused %i" %
                                          memory.number)

        # If we have a split set the transmit frequency first.
        if memory.duplex == TS850_DUPLEX[1]:
            spec = "".join(self._make_split_spec(memory))
            result = command(self.pipe, *self._cmd_set_split(memory.number,
                                                             spec))
            if iserr(result):
                raise errors.InvalidDataError("Radio refused %i" %
                                              memory.number)

        spec = self._make_mem_spec(memory)
        spec = "".join(spec)
        result = command(self.pipe, *self._cmd_set_memory(memory.number, spec))
        if iserr(result):
            raise errors.InvalidDataError("Radio refused %i" % memory.number)
Example #26
0
def set_freq(pipe, freq):
    """Set the frequency of the radio on @pipe to @freq"""
    freqbcd = util.bcd_encode(freq, bigendian=False, width=9)
    buf = "\x01\x7f\x05" + freqbcd

    drain(pipe)
    send_magic(pipe)
    resp = send(pipe, buf)
    for frame in resp:
        if len(frame) == 6:
            if frame[4] == "\xfb":
                return True

    raise errors.InvalidDataError("Repeater reported error")
Example #27
0
def set_memory(pipe, vfo, memory):
    """Set memory @memory on @vfo via @pipe"""
    frame = IC92MemoryFrame()
    frame.set_memory(memory)
    frame.set_vfo(vfo)

    #print "Sending (%i):" % (len(frame.get_raw()))
    #print util.hexprint(frame.get_raw())

    rframe = frame.send(pipe)

    if rframe.get_raw()[2] != "\xfb":
        raise errors.InvalidDataError("Radio reported error:\n%s" %\
                                          util.hexprint(rframe.get_payload()))
Example #28
0
def required_step(freq):
    """Returns the simplest tuning step that is required to reach @freq"""
    if is_5_0(freq):
        return 5.0
    elif is_12_5(freq):
        return 12.5
    elif is_6_25(freq):
        return 6.25
    elif is_2_5(freq):
        return 2.5
    else:
        raise errors.InvalidDataError("Unable to calculate the required " +
                                      "tuning step for %i.%5i" %
                                      (freq / 1000000, freq % 1000000))
Example #29
0
def unescape_raw_bytes(escaped_data):
    """Unescapes raw bytes from the radio."""
    data = b""
    i = 0
    while i < len(escaped_data):
        byte = escaped_data[i]
        if byte == 0xff:
            if i + 1 >= len(escaped_data):
                raise errors.InvalidDataError(
                    "Unexpected escape character at end of data")
            i += 1
            byte = 0xf0 | escaped_data[i]
        data += bytes([byte])
        i += 1
    return data
Example #30
0
def unescape_raw_bytes(escaped_data):
    """Unescapes raw bytes from the radio."""
    data = ""
    i = 0
    while i < len(escaped_data):
        byte = escaped_data[i]
        if byte == '\xff':
            if i + 1 >= len(escaped_data):
                raise errors.InvalidDataError(
                    "Unexpected escape character at end of data")
            i += 1
            byte = chr(0xf0 | ord(escaped_data[i]))
        data += byte
        i += 1
    return data