Calculate the ICAO address from an Mode-S message
    with DF4, DF5, DF20, DF21

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        String: ICAO address in 6 bytes hexadecimal string
184333
def icao(msg):
    

    DF = df(msg)

    if DF in (11, 17, 18):
        addr = msg[2:8]
    elif DF in (0, 4, 5, 16, 20, 21):
        c0 = bin2int(crc(msg, encode=True))
        c1 = hex2int(msg[-6:])
        addr = '%06X' % (c0 ^ c1)
    else:
        addr = None

    return addr
642558
def gs50(msg):
    
    d = hex2bin(data(msg))

    if d[23] == '0':
        return None

    spd = bin2int(d[24:34]) * 2    # kts
    return spd
487271
def ic45(msg):
    
    d = hex2bin(data(msg))
    if d[9] == '0':
        return None

    ic = bin2int(d[10:12])
    return ic
715537
def recv_msg(sock):
    
    data = recv(sock, struct.calcsize(METHOD_STRUCT_FORMAT))
    method, = struct.unpack(METHOD_STRUCT_FORMAT, data)
    data = recv(sock, struct.calcsize(SIZE_STRUCT_FORMAT))
    size, = struct.unpack(SIZE_STRUCT_FORMAT, data)
    data = recv(sock, size)
    msg = pickle.loads(data)
    return method, msg
1148775
def temp45(msg):
    
    d = hex2bin(data(msg))

    sign = int(d[16])
    value = bin2int(d[17:26])

    if sign:
        value = value - 512

    temp = value * 0.25   # celsius
    temp = round(temp, 1)

    return temp
1338062
def nic_s(msg):
    
    tc = typecode(msg)

    if tc != 31:
        raise RuntimeError("%s: Not a status operation message, expecting TC = 31" % msg)

    msgbin = common.hex2bin(msg)
    nic_s = int(msgbin[75])

    return nic_s
60228
def _extract_msg(args, kwargs, msg_idx, default_msg, non_msg_params):
    '''
    '''
    rem_args = []
    if 'msg' in kwargs:
        msg = kwargs.pop('msg')
    elif len(args) > non_msg_params and msg_idx < len(args):
        msg = args[msg_idx]
        if 0 <= msg_idx:
            rem_args = args[msg_idx + 1:]
        args = args[:msg_idx]
    else:
        msg = default_msg
    return msg, args, rem_args, kwargs
373663
def ws45(msg):
    
    d = hex2bin(data(msg))
    if d[3] == '0':
        return None

    ws = bin2int(d[4:6])
    return ws
402241
def encodeMsg(self, mesg):
        ''''''

        fmt = self.locs.get('log:fmt')
        if fmt == 'jsonl':
            s = json.dumps(mesg, sort_keys=True) + '\n'
            buf = s.encode()
            return buf

        elif fmt == 'mpk':
            buf = s_msgpack.en(mesg)
            return buf

        mesg = f'Unknown encoding format: {fmt}'
        raise s_exc.SynErr(mesg=mesg)
1370434
def __convertIp6PrefixStringToIp6Address(self, strIp6Prefix):
        
        prefix1 = strIp6Prefix.rstrip('L')
        prefix2 = prefix1.lstrip("0x")
        hexPrefix = str(prefix2).ljust(16,'0')
        hexIter = iter(hexPrefix)
        finalMac = ':'.join(a + b + c + d for a,b,c,d in zip(hexIter, hexIter,hexIter,hexIter))
        prefix = str(finalMac)
        strIp6Prefix = prefix[:20]
        return strIp6Prefix +':'
871144
def mode_string_v09(msg):
    ''''''
    mode = msg.mode
    nav_mode = msg.nav_mode

    MAV_MODE_UNINIT = 0
    MAV_MODE_MANUAL = 2
    MAV_MODE_GUIDED = 3
    MAV_MODE_AUTO = 4
    MAV_MODE_TEST1 = 5
    MAV_MODE_TEST2 = 6
    MAV_MODE_TEST3 = 7

    MAV_NAV_GROUNDED = 0
    MAV_NAV_LIFTOFF = 1
    MAV_NAV_HOLD = 2
    MAV_NAV_WAYPOINT = 3
    MAV_NAV_VECTOR = 4
    MAV_NAV_RETURNING = 5
    MAV_NAV_LANDING = 6
    MAV_NAV_LOST = 7
    MAV_NAV_LOITER = 8
    
    cmode = (mode, nav_mode)
    mapping = {
        (MAV_MODE_UNINIT, MAV_NAV_GROUNDED)  : "INITIALISING",
        (MAV_MODE_MANUAL, MAV_NAV_VECTOR)    : "MANUAL",
        (MAV_MODE_TEST3,  MAV_NAV_VECTOR)    : "CIRCLE",
        (MAV_MODE_GUIDED, MAV_NAV_VECTOR)    : "GUIDED",
        (MAV_MODE_TEST1,  MAV_NAV_VECTOR)    : "STABILIZE",
        (MAV_MODE_TEST2,  MAV_NAV_LIFTOFF)   : "FBWA",
        (MAV_MODE_AUTO,   MAV_NAV_WAYPOINT)  : "AUTO",
        (MAV_MODE_AUTO,   MAV_NAV_RETURNING) : "RTL",
        (MAV_MODE_AUTO,   MAV_NAV_LOITER)    : "LOITER",
        (MAV_MODE_AUTO,   MAV_NAV_LIFTOFF)   : "TAKEOFF",
        (MAV_MODE_AUTO,   MAV_NAV_LANDING)   : "LANDING",
        (MAV_MODE_AUTO,   MAV_NAV_HOLD)      : "LOITER",
        (MAV_MODE_GUIDED, MAV_NAV_VECTOR)    : "GUIDED",
        (MAV_MODE_GUIDED, MAV_NAV_WAYPOINT)  : "GUIDED",
        (100,             MAV_NAV_VECTOR)    : "STABILIZE",
        (101,             MAV_NAV_VECTOR)    : "ACRO",
        (102,             MAV_NAV_VECTOR)    : "ALT_HOLD",
        (107,             MAV_NAV_VECTOR)    : "CIRCLE",
        (109,             MAV_NAV_VECTOR)    : "LAND",
        }
    if cmode in mapping:
        return mapping[cmode]
    return "Mode(%s,%s)" % cmode
477699
def convert_msg(self, msg):
        
        source = msg.msgid
        if not source:
            # don't translate empty string
            return

        plural = msg.msgid_plural
        if plural:
            # translate singular and plural
            foreign_single = self.convert(source)
            foreign_plural = self.convert(plural)
            plural = {
                '0': self.final_newline(source, foreign_single),
                '1': self.final_newline(plural, foreign_plural),
            }
            msg.msgstr_plural = plural
        else:
            foreign = self.convert(source)
            msg.msgstr = self.final_newline(source, foreign)
347134
def mach53(msg):
    
    d = hex2bin(data(msg))

    if d[23] == '0':
        return None

    mach = bin2int(d[24:33]) * 0.008
    return round(mach, 3)
1349350
def _checksum(self, msg):
        
        def carry_around_add(a, b):
            c = a + b
            return (c & 0xffff) + (c >> 16)

        s = 0
        for i in range(0, len(msg), 2):
            w = (msg[i] << 8) + msg[i + 1]
            s = carry_around_add(s, w)
        s = ~s & 0xffff

        return s
96394
def alt40fms(msg):
    
    d = hex2bin(data(msg))

    if d[13] == '0':
        return None

    alt = bin2int(d[14:26]) * 16    # ft
    return alt
495010
def _ic_decode(self, msg):
        """"""
        code = msg[4:16]
        if re.match(r'(0\d){6}', code):
            code = re.sub(r'0(\d)', r'\1', code)
        return {'code': code, 'user': int(msg[16:19])-1,
                'keypad': int(msg[19:21])-1}
1206699
def pprint(msg):
    msg_class = msg.__class__.__name__
    msg_size = msg.ByteSize()
    
    if isinstance(msg, proto.FirmwareUpload):
        return "<%s> (%d bytes):\n" % (msg_class, msg_size)
    else:
        return "<%s> (%d bytes):\n%s" % (msg_class, msg_size, msg)