Beispiel #1
0
    def __init__(self, old, new, overhead, maxbuff, emptychar=None):
        """
        Does the binary difference

        Args:
        * old (bytes): the reference (old) binary data
        * new (bytes): the new binary data to be compared
        * overhead (int): the size of headers associated to the bin-data
        * maxbuff (int): the maximum size of bin-data
        * emptychar (byte): the padding character if the new bin-data is
            shorter than the reference, or `None` for no padding
        """
        self.overhead = int(overhead)
        self.maxbuff = int(maxbuff)
        self.new = Byt(new)
        self.old = Byt(old)
        cutit = len(self.new)
        self.newlen = len(self.new)
        self.oldlen = len(self.old)
        # if new bin-data is shorter than old
        if cutit < len(self.old):
            # if padding is requested, pad the new bin with eptychar
            if emptychar is None:
                self.new += Byt(emptychar)[0] * (self.oldlen - self.newlen)
                self.newlen = self.oldlen
            # else, shorten the old bin-data
            else:
                self.old = self.old[:cutit]
                self.oldlen = self.newlen
        self.minlen = min(self.oldlen, self.newlen)
        self.maxlen = max(self.oldlen, self.newlen)
Beispiel #2
0
 def __init__(self, number, name, pid, desc, lparam, subsystem, param,
              subSystemKey, adcsCommandId):
     """
     Creates a self-checking command
     
     Args:
       * number (int): the unique id
       * name (str): the name (code friendly)
       * pid (str): the unique pid identity string
       * desc (str): the description
       * lparam (int): the total length of the parameters, in
         octets, or "*" for any
       * subsystem (str): the subsystem key
       * param (iterable of list): an iterable of parameter lists of
         form and order: (name, desc, rng, typ, size, unit)
       * subSystemKey (Byt[1]): the hex code of the sub-system
       * adcsCommandId (Byt[1]): the hex code command id from the ADCS
     """
     self.subSystemKey = Byt().fromHex(subSystemKey[:2])
     self.adcsCommandId = Byt().fromHex(adcsCommandId[:2])
     super(CmADCS, self).__init__(number=number,
                                  name=name,
                                  pid=pid,
                                  desc=desc,
                                  lparam=lparam,
                                  subsystem=subsystem,
                                  param=param)
Beispiel #3
0
 def process(self, key, data):
     """
     Saves the packet in the database and does 
     """
     # ignores the reporting
     if key == 'rpt':
         return
     report('receivedTM')
     if param_all.AX25ENCAPS:
         source, destination, blobish = Framer.decode_radio(data['data'])
         if source == Byt():
             report('receivedCallsignTM',
                    source=source,
                    ll=len(blobish),
                    destination=destination)
         else:
             report('junkFromRF')
     else:
         blobish = data['data']
         report('receivedRawTM', ll=len(blobish))
     blobparser = CCSDSBlob(blobish)
     start = 0
     pk = blobparser.grab_first_packet(start=start)
     while pk is not None:
         data['data'] = Byt(pk)
         process_incoming(**data)
         start += len(pk)
         pk = blobparser.grab_first_packet(start=start)
     return
Beispiel #4
0
 def decode_radio(self, frame):
     """
     Parses and extracts the components of an AX25+KISS-Encoded Frame
     """
     # init
     source, destination, text = Byt(), Byt(), Byt()
     if self.ISKISS:
         # parse KISS away
         frame = kissutils.strip_df_start(frame)
         # recover special codes
         frame = kissutils.recover_special_codes(frame)
     frameints = frame.ints()
     frame_len = len(frameints)
     if frame_len > 16:
         for idx, char in enumerate(frameints):
             # Is address field length correct?
             # Find the first ODD Byte followed by the next boundary:
             if (char & 0x01 and ((idx + 1) % 7) == 0):
                 i = (idx + 1) // 7
                 # Less than 2 callsigns? For frames <= 70 bytes
                 if 1 < i < 11 and frame_len >= idx + 2:
                     if (frameints[idx + 1] & 0x03 == 0x03 and
                             frameints[idx + 2] in [0xf0, 0xcf]):
                         text = frame[idx + 3:]
                         destination = Callsign(frame[:7])
                         source = Callsign(frame[7:])
                         #self._extract_kiss_path(frame, i)
                 return source, destination, text
     return source, destination, text
 def add_siggy(self, fullPacket, **kwargs):
     """
     Does surgery of the input full packet with null signature (fullPacket)
     and adds the signature into it
     Returns the packet with included signature, and the signature
     If the signature should not be used because of parametrization, the
     signature is not added to the packet and a None signature is returned
     """
     if not kwargs.pop('signit', param_all.USESIGGY)\
                             or self.mode == 'telemetry':
         return fullPacket, None
     # calculates the signature from full packet
     siggy = hmac(fullPacket)
     # apply mask
     siggy = Byt(s for idx, s in enumerate(siggy.ints())\
                     if param_all.KEYMASK[idx] == '1')
     # f**k endians
     if bincore.TWINKLETWINKLELITTLEINDIA:
         siggy = siggy[::-1]
     # grab the bounds of the siggy location, to chunk it into the packet
     startSiggy = param_ccsds.HEADER_P_KEYS.size +\
                             param_ccsds.SIGNATURE.start//8
     # return concatenated turd
     return fcts.setstr(
         fullPacket,
         slice(startSiggy, startSiggy + param_ccsds.SIGNATURE.len // 8),
         siggy), siggy
Beispiel #6
0
 def _grabCSV(self, itera):
     ll = []
     cm = None
     for line in itera:
         # is empty line ?
         if line[param_commands.CSVNAME] == "" and\
                     line[param_commands.CSVPARAMNAME] == "":
             continue
         # that's a new command, not an additional parameter
         if line[param_commands.CSVSUBSYSTEM] != "":
             if cm is not None:
                 ll.append(cm)
             cm = {
                 'number': int(line[param_commands.CSVNUMBER]),
                 'name':\
                     core.rchop(core.ustr(line[param_commands.CSVNAME])\
                                     .replace(' ', '_'), '_TM'),
                 'pid': core.ustr(line[param_commands.CSVPID]).lower(),
                 'desc': core.ustr(line[param_commands.CSVDESC]),
                 'lparam':\
                     int(0\
                         if line[param_commands.CSVLPARAM].strip() == ""\
                         else line[param_commands.CSVLPARAM])\
                     if line[param_commands.CSVLPARAM].strip() != "*"\
                     else "*",
                 'subsystem':\
                     core.ustr(line[param_commands.CSVSUBSYSTEM])\
                                             .lower().replace(' ', '_'),
                 'param': [],
                 'n_nparam':\
                     int(line[param_commands.CSVNPARAM]\
                     if line[param_commands.CSVNPARAM].strip() != ""\
                             else 0)}
             # adcs specific stuff
             if self._cmds == 'adcs':
                 cm.update({
                     'subSystemKey': Byt(int(line[\
                         param_commands.CSVSUBSYSTEMKEYADCS]\
                         .strip(), 16))[0].hex(),
                     'adcsCommandId': Byt(int(line[\
                         param_commands.CSVCOMMANDIDADCS]\
                         .strip(), 16))[0].hex()})
         # no parameter command
         if cm['n_nparam'] == 0:
             cm['lparam'] = 0
         else:  # adding parameters to the last command added
             cm['param'].append([
                     core.ustr(line[param_commands.CSVPARAMNAME])\
                                         .replace(' ', '_'),
                     core.ustr(line[param_commands.CSVPARAMDESC]),
                     core.ustr(line[param_commands.CSVPARAMRNG]),
                     core.ustr(line[param_commands.CSVPARAMTYP])\
                                         .replace('_t', ''),
                     core.ustr(line[param_commands.CSVPARAMSIZE]),
                     core.ustr(line[param_commands.CSVPARAMUNIT])\
                                         .replace(' ', '_'),
                     core.ustr(line[param_commands.CSVPARAMEX])])
     ll.append(cm)
     return ll
Beispiel #7
0
def str2hex(txt, pad=0, **kwargs):
    """
    A hexa-text '2F 3C A8' to bytes
    pad in hex chars
    type = hexadecimal
    verbose = hexa string -> hexadecimal
    """
    return padit(txt=Byt.fromHex(txt), l=pad, ch=Byt(0))
Beispiel #8
0
def test_pformat_uint():
    p = PFormat('uint', 8)
    assert p.minmax == (0, 2**8 - 1)
    assert p.is_valid(256) == False
    assert p.is_valid(255) == True
    assert p.is_valid(0) == True
    assert p.is_valid(-1) == False
    assert p._tohex(0) == Byt('\x00')
    assert p._tohex(241) == Byt('\xf1')
Beispiel #9
0
def txt2hex(txt, pad=0, **kwargs):
    """
    A display-text [32--126] to bytes
    pad in hex chars
    type = hexadecimal
    verbose = message -> hexadecimal
    """
    txt = Byt(i for i in Byt(txt).ints() if i >= 32 and i <= 126)
    return padit(txt=txt, l=pad, ch=Byt(0))
Beispiel #10
0
    def __init__(self, callsign):
        """
        Defines parts of a Callsign decoded from either ASCII or KISS

        Args:
        * callsign (str): the callsign
        """
        self.callsign = Byt()
        self.ssid = Byt('0')
        self.digi = False
        self.parse(callsign)
Beispiel #11
0
    def _extract_callsign_from_AX25_frame(self, frame):
        """
        Extracts a Callsign and SSID from a KISS-Encoded APRS Frame.

        Args:
        * frame (bytes): KISS-Encoded APRS Frame as str of octs
        """
        frame = Byt(frame[:7]).ints()
        callsign = Byt(x >> 1 for x in frame[:6])
        self.callsign = callsign.strip()
        self.ssid = Byt(str((frame[6] >> 1) & 0x0f))
Beispiel #12
0
def double2hex(v, pad=0, **kwargs):
    """
    Give a float64, returns chars
    pad in hex chars
    type = hexadecimal
    verbose = float32 -> hexadecimal
    """
    litFucInd = kwargs.get('litFucInd', TWINKLETWINKLELITTLEINDIA)
    end = '<' if litFucInd else '>'
    v = Byt(struct.pack(end + 'd', v))
    return padit(txt=v, l=pad, ch=Byt(0))
Beispiel #13
0
def test_pformat_str():
    p = PFormat('str')
    assert p.minmax == (0, 255)
    assert p.bits == 0
    assert p.typ == 'str'
    assert p.is_valid(['a']) == False
    assert p.is_valid('ab') == False
    assert p.is_valid(32) == False
    assert p.is_valid('a') == True
    assert p.is_valid('\x01') == True
    assert p._tohex('a') == Byt('a')
    assert p._tohex('\x41') == Byt('A')
Beispiel #14
0
def hmac(txt):
    """
    Calculates the HMAC-SHA256 of the ``txt`` given as input
    """
    txt = Byt(txt)
    digest = create_string_buffer(param_all.KEYLENGTH)
    if param_all.VITELACLE is not None:
        _hmacfct(param_all.VITELACLE, txt, len(txt), digest)
    else:
        print('No key found, using NULL')
        _hmacfct(Byt("\x00" * param_all.KEYLENGTH), txt, len(txt), digest)
    return Byt(digest.raw)
def test_param_str_tuple():
    p = Parameter('hop', 'blah', ftup(0, 10), 'str')
    assert p.is_valid('rt') == False
    assert p.is_valid(3) == False
    assert p.is_valid([10]) == False
    assert p.is_valid(['\x00']) == True
    assert p.is_valid('\x09') == True
    assert p.is_valid(['\x10']) == False
    assert p.is_valid('\x00\x00') == False
    assert p.is_valid(['\x10'], withvalue=True)[0] == False
    assert p.is_valid(['\x04'], withvalue=True) == (True, ['\x04'])
    assert p.tohex('\x04') == Byt('\x04')
    assert p.tohex(['\x02']) == Byt('\x02')
def test_param_uint_tuple():
    p = Parameter('hop', 'blah', ftup(0, 10), 'uint8', 1, None)
    assert p.is_valid('rt') == False
    assert p.is_valid(3) == True
    assert p.is_valid([10]) == True
    assert p.is_valid([5, 0]) == False
    assert p.is_valid([-1]) == False
    assert p.is_valid(11) == False
    assert p.is_valid([1.0]) == False
    assert p.is_valid([12.0], withvalue=True)[0] == False
    assert p.is_valid([0], withvalue=True) == (True, [0])
    assert p.tohex(3) == Byt('\x03')
    assert p.tohex(10) == Byt('\x0A')
def test_param_str_list():
    p = Parameter('hop', 'blah', [0, 1, 2, 4], 'str', 2)
    assert p._isdict == False
    assert p.is_valid(['\x01', '\x04']) == True
    assert p.is_valid(['\x01', '\x03']) == False
    assert p.is_valid(['\x02']) == False
    assert p.is_valid(['\x00', '\x01'],
                      withvalue=True) == (True, ['\x00', '\x01'])
    assert p.is_valid(['\x05', '\x02']) == False
    assert p.is_valid(['\x01', '\x02', '\x00']) == False
    assert p.is_valid(['\x03', '\x01'], withvalue=True)[0] == False
    assert p.is_valid('\x04\x00', withvalue=True) == (True, ['\x04', '\x00'])
    assert p.tohex(['\x04', '\x01']) == Byt('\x04\x01')
    assert p.tohex('\x01\x02') == Byt('\x01\x02')
Beispiel #18
0
    def encode_callsign(self):
        """
        Encodes Callsign (or Callsign-SSID) as KISS
        """
        encoded_ssid = ((int(self.ssid) << 1) | 0x60)
        callsign = Byt(self.callsign)

        if self.digi:
            encoded_ssid |= 0x80
        # Pad the callsign to 6 characters
        callsign = fcts.fillit(callsign, l=6, ch=Byt(' ')).ints()

        encoded_callsign = Byt(p << 1 for p in callsign)

        return encoded_callsign + Byt(encoded_ssid)
Beispiel #19
0
def int2hex(i, pad=0, **kwargs):
    """
    Give an int, returns chars
    pad in hex chars
    type = hexadecimal
    verbose = unsigned integer -> hexadecimal
    """
    litFucInd = kwargs.get('litFucInd', TWINKLETWINKLELITTLEINDIA)
    hx = hex(i)[2:].replace('L', '')  # replace if long int
    hx = Byt(binascii.unhexlify(('0' * (len(hx) % 2)) + hx))
    if litFucInd:
        hx = hx[::-1]
    if pad > 1:
        hx = padit(txt=hx, l=pad, ch=Byt(0))
    return hx
Beispiel #20
0
 def tohex(self, value):
     """
     Equivalent of calling the object
     """
     valid, value = self.is_valid(value, withvalue=True)
     if valid is False:
         raise cmdexception.InvalidParameterValue(self.name, value)
     ret = Byt()
     if self._isdict:
         for item in value:
             ret += Byt(self.rng[item])
     else:
         for item in value:
             ret += self.typ._tohex(item)
     return ret
def test_cm_base2():
    ee = copy.deepcopy(echo)
    ee['lparam'] = '*'
    ee['param'] = (('hop', 'blah', ftup(0, 255), 'str', ftup(1, 4)), )
    c = Cm(**ee)
    assert c.number == 1
    assert c.name == 'echo'
    assert c.desc == 'blah'
    assert c.level == 0
    assert c.subsystem == "obc"
    assert c.pid == "L0ComManager"
    assert c.lparam is None
    assert c.nparam == 1
    assert c.p_0_hop.typ.typ == 'str'
    assert c.generate_data(hop='abab')[0] == Byt('\x61\x62\x61\x62')
    assert c.generate_data(hop='a')[0] == Byt('\x61')
Beispiel #22
0
def merge_flow(datalist, trailingSplit=True):
    """
    Merges the packets if the flow mode is activated

    Args:
    * datalist (list of Byt): the packets to merge together
    * trailingSplit (bool): whether to add a trailing split character
    """
    if not param_all.FRAMESFLOW:
        raise exc.NotInFramesFlow()
    # merge CCSDS using the special split chars
    if not param_all.AX25ENCAPS:
        res = (param_all.CCSDSSPLITCHAR*2).join([
                    Byt(item).replace(param_all.CCSDSSPLITCHAR,
                                      param_all.CCSDSESCAPEDSPLIT)\
                        for item in datalist\
                            if len(item) > 0])
        if trailingSplit:
            res += param_all.CCSDSSPLITCHAR * 2
        return res
    # merge KISS using the special split chars
    elif param_all.KISSENCAPS:
        raise exc.NotImplemented("Frames-FLow with KISS")
    else:
        raise exc.NotImplemented("Unknown mode")
Beispiel #23
0
    def unpack_data(self, packet, hds, hdx):
        """
        Unpacks the data of the packet, returns a dictionary

        Args:
          * packet (byts): the string that contains the full packet
          * hds (dict): the packet headers
          * hdx (dict): the packet auxiliary headers
        """
        data = {'all': Byt(), 'unpacked': {}}
        start = param_ccsds.HEADER_P_KEYS.size
        if self.mode == 'telemetry':
            start += param_ccsds.HEADER_S_KEYS_TELEMETRY.size
        else:
            start += param_ccsds.HEADER_S_KEYS_TELECOMMAND.size
        catnum = int(hds[param_ccsds.PACKETCATEGORY.name])
        pld = int(hds[param_ccsds.PAYLOADFLAG.name])
        # aux header size
        cat = param_category.CATEGORIES[pld][catnum]
        start += cat.aux_size
        data['all'] = packet[start:]
        if cat.data_trousseau is not None:
            # pass tc id in case of tcanswer category
            data['unpacked'] = cat.data_trousseau.unpack(data=data['all'],
                                                         hds=hds, hdx=hdx)
        return data
Beispiel #24
0
 def process(self, key, data):
     """
     Checks for feedback from listen
     """
     # ignores anything but dic and rpt if key is sentTC
     if key != 'dic' and key != 'rpt':
         return
     if 'data' not in data.keys():
         return
     blobish = data['data']
     # strip AX25 if need be
     if param_all.AX25ENCAPS:
         source, destination, blobish = Framer.decode_radio(blobish)
     # case of the RFCheckoutBox returning garbage
     if len(blobish) == 0:
         return
     # if report type message, gotta check if report_key is sentTC
     if key == 'rpt':
         # case of getting the TC back, update time_sent in DB
         if str(data[param_sys.REPORTKEY]) == 'sentTC'\
                                     and param_all.SAVETC:
             res = TCUnPacker.unpack_primHeader(blobish)
             pkid = res[param_ccsds.PACKETID.name]
             db.update_sent_TC_time(pkid, data['t'])
     elif key == 'dic':
         blobparser = CCSDSBlob(blobish)
         start = 0
         pk = blobparser.grab_first_packet(start=start)
         while pk is not None:
             data['data'] = Byt(pk)
             process_incoming(**data)
             start += len(pk)
             pk = blobparser.grab_first_packet(start=start)
def test_param_uint_list():
    p = Parameter('hop', 'blah', [0, 1, 2, 4], 'uint8', ftup(2, 3), None)
    assert p._isdict == False
    assert p.is_valid('rt') == False
    assert p.is_valid(1) == False
    assert p.is_valid([2]) == False
    assert p.is_valid([0, 1], withvalue=True) == (True, [0, 1])
    assert p.is_valid([4, 2]) == True
    assert p.is_valid([1.0, 2]) == False
    assert p.is_valid([1, 2, 0]) == True
    assert p.is_valid([1, 2, 0, 0]) == False
    assert p.is_valid([0, 3]) == False
    assert p.is_valid([2.0, 1], withvalue=True)[0] == False
    assert p.is_valid([4, 0], withvalue=True) == (True, [4, 0])
    assert p.tohex([4, 1]) == Byt('\x04\x01')
    assert p.tohex([1, 0]) == Byt('\x01\x00')
Beispiel #26
0
 def generate_slices(self, slices):
     """
     Returns the list of data blocks
     """
     blocks = {}
     for sl in slices:
         blocks[sl.s] = Byt(self.new[sl.slice()])
     return blocks
Beispiel #27
0
def hex2hex(v, pad=0, **kwargs):
    """
    Give some hex, get some hex
    pad in hex chars
    type = hexadecimal
    verbose = Kept as hexadecimal
    """
    return padit(txt=v, l=pad, ch=Byt(0))
    def pack_data(self, values, header, retvalues=False):
        """
        Encodes the values into a CCSDS auxiliary header, returns hex
        string and encoded values

        Args:
          * values (dict): the values to pack
          * header (dict): 
          * retvalues (bool): if ``True``, returns the encoded values
        """
        if self.mode != 'telemetry':
            return (Byt(), {}) if retvalues else Byt()
        # encode the data here TBD
        if retvalues:
            return Byt(), {}
        else:
            return Byt()
Beispiel #29
0
def crc32(message, crc=None):
    """
    Give a message, returns a CRC on 4 octet using
    basecrc as crc start-value (if given)
    """
    crc = 0xffffffff if crc is None else int(crc)
    for byte in Byt(message).iterInts():
        crc = (crc >> 8) ^ CRC32TABLE[(crc ^ byte) & 0xFF]
    return two_comp_uint(crc, 32)
Beispiel #30
0
def process_report(inputs):
    global PIDS
    key = str(inputs.get(param_sys.REPORTKEY))
    broadcast(key, **inputs)
    if key == 'myPID':
        who = inputs['who']
        if who in PIDS.keys():
            killit = PIDS.pop(who)
            killit.stop()
        # restart watchdog PID with new PID number
        PIDS[who] = PIDWatchDog(name=who,
                                pid=inputs['pid'],
                                timeout=param_all.PROCESSTIMEOUT,
                                whenDead=revive_process,
                                whenAlive=say_hi,
                                who=who)
    elif key == 'broadcastTC':
        pass
    elif key == 'GotBlob':
        blobish = Byt(inputs['blob'])
        try:
            # strip AX25 if need be
            if param_all.AX25ENCAPS:
                source, destination, blobish = Framer.decode_radio(blobish)
                # case of the RFCheckoutBox returning garbage
                if len(blobish) == 0:
                    print('That was junk from RFCheckoutBox')
                    return
            if len(blobish) == 0:
                print("Can't unpack empty packet")
                return
            hd, hdx, dd = TMUnPacker.unpack(blobish)
        except:
            print('Tried to unpack.. but an error occurred: {}'\
                    .format(sys.exc_info()[0]))
            return
        inpacket = dict(hd)
        inpacket.update(hdx)
        inpacket['_all_data'] = dd['all']
        inpacket['_sz_blobish'] = len(blobish)
        WATCH_TRANS.tell_key('tmf', **inpacket)
        pldflag = int(hd[param_ccsds.PAYLOADFLAG.name])
        catnum = int(hd[param_ccsds.PACKETCATEGORY.name])
        # print Header Prim
        print(param_ccsds.HEADER_P_KEYS.disp(dict(hd)))
        # print Header Sec TM
        print(param_ccsds.HEADER_S_KEYS_TELEMETRY.disp(dict(hd)))
        # print Header Aux if any
        cat = param_category.CATEGORIES[pldflag][catnum]
        if cat.aux_size > 0:
            print(cat.aux_trousseau.disp(dict(hdx)))
        # print data if any
        if cat.data_trousseau is not None:
            print(cat.data_trousseau.disp(dd['unpacked'], hds=hd, hdx=hdx))
    else:
        pass