Ejemplo n.º 1
0
def process_flags_bytes(_hex_flags):
    _byte3 = int(h(_hex_flags[2]), 16)
    _byte4 = int(h(_hex_flags[3]), 16)
    
    _csbk       = bool(_byte3 & CSBK_MSK)
    _rpt_mon    = bool(_byte3 & RPT_MON_MSK)
    _con_app    = bool(_byte3 & CON_APP_MSK)
    _xnl_con    = bool(_byte4 & XNL_STAT_MSK)
    _xnl_master = bool(_byte4 & XNL_MSTR_MSK)
    _xnl_slave  = bool(_byte4 & XNL_SLAVE_MSK)
    _auth       = bool(_byte4 & PKT_AUTH_MSK)
    _data       = bool(_byte4 & DATA_CALL_MSK)
    _voice      = bool(_byte4 & VOICE_CALL_MSK)
    _master     = bool(_byte4 & MSTR_PEER_MSK)
    
    return {
        'CSBK': _csbk,
        'RCM': _rpt_mon,
        'CON_APP': _con_app,
        'XNL_CON': _xnl_con,
        'XNL_MASTER': _xnl_master,
        'XNL_SLAVE': _xnl_slave,
        'AUTH': _auth,
        'DATA': _data,
        'VOICE': _voice,
        'MASTER': _master
        } 
Ejemplo n.º 2
0
    def dumpIPSCFrame( self, _frame ):
        
        _packettype     = int_id(_frame[0:1])                 # int8  GROUP_VOICE, PVT_VOICE, GROUP_DATA, PVT_DATA, CALL_MON_STATUS, CALL_MON_RPT, CALL_MON_NACK, XCMP_XNL, RPT_WAKE_UP, DE_REG_REQ
        _peerid         = int_id(_frame[1:5])                 # int32 peer who is sending us a packet
        _ipsc_seq       = int_id(_frame[5:6])                 # int8  looks like a sequence number for a packet
        _src_sub        = int_id(_frame[6:9])                 # int32 Id of source
        _dst_sub        = int_id(_frame[9:12])                # int32 Id of destination
        _call_type      = int_id(_frame[12:13])               # int8 Priority Voice/Data
        _call_ctrl_info  = int_id(_frame[13:17])              # int32
        _call_info      = int_id(_frame[17:18])               # int8  Bits 6 and 7 defined as TS and END
        
        # parse out the RTP values
        _rtp_byte_1 = int_id(_frame[18:19])                 # Call Ctrl Src
        _rtp_byte_2 = int_id(_frame[19:20])                 # Type
        _rtp_seq    = int_id(_frame[20:22])                 # Call Seq No
        _rtp_tmstmp = int_id(_frame[22:26])                 # Timestamp
        _rtp_ssid   = int_id(_frame[26:30])                 # Sync Src Id
        
        _payload_type   = _frame[30]                       # int8  VOICE_HEAD, VOICE_TERM, SLOT1_VOICE, SLOT2_VOICE
        
        _ts             = bool(_call_info & TS_CALL_MSK)
        _end            = bool(_call_info & END_MSK)

        if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
            print('HEAD:', h(_frame))
        if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
            
            _ipsc_rssi_threshold_and_parity = int_id(_frame[31])
            _ipsc_length_to_follow = int_id(_frame[32:34])
            _ipsc_rssi_status = int_id(_frame[34])
            _ipsc_slot_type_sync = int_id(_frame[35])
            _ipsc_data_size = int_id(_frame[36:38])
            _ipsc_data = _frame[38:38+(_ipsc_length_to_follow * 2)-4]
            _ipsc_full_lc_byte1 = int_id(_frame[38])
            _ipsc_full_lc_fid = int_id(_frame[39])
            _ipsc_voice_pdu_service_options = int_id(_frame[40])
            _ipsc_voice_pdu_dst = int_id(_frame[41:44])
            _ipsc_voice_pdu_src = int_id(_frame[44:47])

            print('{} {} {} {} {} {} {} {} {} {} {}'.format(_ipsc_rssi_threshold_and_parity,_ipsc_length_to_follow,_ipsc_rssi_status,_ipsc_slot_type_sync,_ipsc_data_size,h(_ipsc_data),_ipsc_full_lc_byte1,_ipsc_full_lc_fid,_ipsc_voice_pdu_service_options,_ipsc_voice_pdu_dst,_ipsc_voice_pdu_src))
            print('TERM:', h(_frame))
        if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
            _rtp_len        = _frame[31:32]
            _ambe           = _frame[33:52]
            print('SLOT1:', h(_frame))
        if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
            _rtp_len        = _frame[31:32]
            _ambe           = _frame[33:52]
            print('SLOT2:', h(_frame))
        print("pt={:02X} pid={} seq={:02X} src={} dst={} ct={:02X} uk={} ci={} rsq={}".format(_packettype, _peerid,_ipsc_seq, _src_sub,_dst_sub,_call_type,_call_ctrl_info,_call_info,_rtp_seq))
Ejemplo n.º 3
0
def process_peer_list(_data, _network):
    # Create a temporary peer list to track who we should have in our list -- used to find old peers we should remove.
    _temp_peers = []
    # Determine the length of the peer list for the parsing iterator
    _peer_list_length = int(h(_data[5:7]), 16)
    # Record the number of peers in the data structure... we'll use it later (11 bytes per peer entry)
    NETWORK[_network]['LOCAL']['NUM_PEERS'] = _peer_list_length/11
    logger.info('(%s) Peer List Received from Master: %s peers in this IPSC', _network, _peer_list_length/11)
    
    # Iterate each peer entry in the peer list. Skip the header, then pull the next peer, the next, etc.
    for i in range(7, _peer_list_length +7, 11):
        # Extract various elements from each entry...
        _hex_radio_id = (_data[i:i+4])
        _hex_address  = (_data[i+4:i+8])
        _ip_address   = IPAddr(_hex_address)
        _hex_port     = (_data[i+8:i+10])
        _port         = int(h(_hex_port), 16)
        _hex_mode     = (_data[i+10:i+11])
     
        # Add this peer to a temporary PeerID list - used to remove any old peers no longer with us
        _temp_peers.append(_hex_radio_id)
        
        # This is done elsewhere for the master too, so we use a separate function
        _decoded_mode = process_mode_byte(_hex_mode)

        # If this entry was NOT already in our list, add it.
        if _hex_radio_id not in NETWORK[_network]['PEERS'].keys():
            NETWORK[_network]['PEERS'][_hex_radio_id] = {
                'IP':          _ip_address, 
                'PORT':        _port, 
                'MODE':        _hex_mode,            
                'MODE_DECODE': _decoded_mode,
                'FLAGS': '',
                'FLAGS_DECODE': '',
                'STATUS': {
                    'CONNECTED':               False,
                    'KEEP_ALIVES_SENT':        0,
                    'KEEP_ALIVES_MISSED':      0,
                    'KEEP_ALIVES_OUTSTANDING': 0
                    }
                }
        logger.debug('(%s) Peer Added: %s', _network, NETWORK[_network]['PEERS'][_hex_radio_id])
    
    # Finally, check to see if there's a peer already in our list that was not in this peer list
    # and if so, delete it.
    for peerid in NETWORK[_network]['PEERS'].keys():
        if peerid not in _temp_peers:
            de_register_peer(_network, peerid)
            logger.warning('(%s) Peer Deleted (not in new peer list): %s', _network, h(peerid))
Ejemplo n.º 4
0
def print_peer_list(_network):
    _peers = NETWORK[_network]['PEERS']
    
    _status = NETWORK[_network]['MASTER']['STATUS']['PEER_LIST']
    #print('Peer List Status for {}: {}' .format(_network, _status))
    
    if _status and not NETWORK[_network]['PEERS']:
        print('We are the only peer for: %s' % _network)
        print('')
        return
             
    print('Peer List for: %s' % _network)
    for peer in _peers.keys():
        _this_peer = _peers[peer]
        _this_peer_stat = _this_peer['STATUS']
        
        if peer == NETWORK[_network]['LOCAL']['RADIO_ID']:
            me = '(self)'
        else:
            me = ''
             
        print('\tRADIO ID: {} {}' .format(int(h(peer), 16), me))
        print('\t\tIP Address: {}:{}' .format(_this_peer['IP'], _this_peer['PORT']))
        if _this_peer['MODE_DECODE'] and REPORTS['PEER_REPORT_INC_MODE']:
            print('\t\tMode Values:')
            for name, value in _this_peer['MODE_DECODE'].items():
                print('\t\t\t{}: {}' .format(name, value))
        if _this_peer['FLAGS_DECODE'] and REPORTS['PEER_REPORT_INC_FLAGS']:
            print('\t\tService Flags:')
            for name, value in _this_peer['FLAGS_DECODE'].items():
                print('\t\t\t{}: {}' .format(name, value))
        print('\t\tStatus: {},  KeepAlives Sent: {},  KeepAlives Outstanding: {},  KeepAlives Missed: {}' .format(_this_peer_stat['CONNECTED'], _this_peer_stat['KEEP_ALIVES_SENT'], _this_peer_stat['KEEP_ALIVES_OUTSTANDING'], _this_peer_stat['KEEP_ALIVES_MISSED']))

    print('')
Ejemplo n.º 5
0
def main():
    if len(sys.argv) == 3:
        if sys.argv[1] in ("-f", "--file"):
            HA1 = hashlib.md5()
            HA2 = hashlib.md5()
            RESP = hashlib.md5()

            username = "******"
            realm = "HTTP Digest Verzeichnisschutz"
            nonce = "v0jB77mjBQA=c433c4aa74cf8815d1c96a6f6b8851bac0cde6dd"
            response = "04ffc124252aeb595bc58a3b1e6f0698"
            requesturi = "/digestAuth/"
            method = "GET"

            with open(sys.argv[2], "r", encoding='latin-1') as passwords:
                for line in passwords.readlines():
                    HA1.update(
                        (username + ":" + realm + ":" + line).encode("utf-8"))
                    HA2.update((method + ":" + requesturi).encode("utf-8"))
                    RESP.update(
                        (binascii.b2a_hex(HA1.digest()) + ":" + nonce + ":" +
                         binascii.b2a_hex(HA2.digest())).encode("utf-8"))
                    print(
                        f"PWD = { line }  HA1 = { h(HA1.digest()) }  HA2 = { h(HA2.digest()) }  RESP = { h(RESP.digest()) }"
                    )

                    if response == h(RESP.digest()):
                        print(f"[+] Found Correct Password : {line}")

        else:
            print(f"[-] Invalid Argument \"{ sys.argv[1] }\"")
    else:
        print("[-] Not enough Arguments")
Ejemplo n.º 6
0
    def parseAMBE(self, _client, _data):
        _seq = int_id(_data[4:5])
        _srcID = int_id(_data[5:8])
        _dstID = int_id(_data[8:11])
        _rptID = int_id(_data[11:15])
        _bits = int_id(
            _data[15:16]
        )  # SCDV NNNN (Slot|Call type|Data|Voice|Seq or Data type)
        _slot = 2 if _bits & 0x80 else 1
        _callType = 1 if (_bits & 0x40) else 0
        _frameType = (_bits & 0x30) >> 4
        _voiceSeq = (_bits & 0x0f)
        _streamID = int_id(_data[16:20])
        logger.debug(
            '(%s) seq: %d srcID: %d dstID: %d rptID: %d bits: %0X slot:%d callType: %d frameType:  %d voiceSeq: %d streamID: %0X',
            _client, _seq, _srcID, _dstID, _rptID, _bits, _slot, _callType,
            _frameType, _voiceSeq, _streamID)

        #logger.debug('Frame 1:(%s)', self.ByteToHex(_data))
        _dmr_frame = BitArray('0x' + h(_data[20:]))
        _ambe = _dmr_frame[0:108] + _dmr_frame[156:264]
        #_sock.sendto(_ambe.tobytes(), ("127.0.0.1", 31000))

        ambeBytes = _ambe.tobytes()
        self._sock.sendto(ambeBytes[0:9], (self._exp_ip, self._exp_port))
        self._sock.sendto(ambeBytes[9:18], (self._exp_ip, self._exp_port))
        self._sock.sendto(ambeBytes[18:27], (self._exp_ip, self._exp_port))
Ejemplo n.º 7
0
def process_mode_byte(_hex_mode):
    _mode = int(h(_hex_mode), 16)
    
    # Determine whether or not the peer is operational
    _peer_op = bool(_mode & PEER_OP_MSK)    
    # Determine whether or not timeslot 1 is linked
    _ts1 = bool(_mode & IPSC_TS1_MSK)  
    # Determine whether or not timeslot 2 is linked
    _ts2 = bool(_mode & IPSC_TS2_MSK)
     
    # Determine the operational mode of the peer
    if _mode & PEER_MODE_MSK == PEER_MODE_MSK:
        _peer_mode = 'UNKNOWN'
    elif not _mode & PEER_MODE_MSK:
        _peer_mode = 'NO_RADIO'
    elif _mode & PEER_MODE_ANALOG:
        _peer_mode = 'ANALOG'
    elif _mode & PEER_MODE_DIGITAL:
        _peer_mode = 'DIGITAL'
    
    return {
        'PEER_OP': _peer_op,
        'PEER_MODE': _peer_mode,
        'TS_1': _ts1,
        'TS_2': _ts2
        }
Ejemplo n.º 8
0
    def call_mon_status(self, _network, _data):
        if not status:
            return
        _source = _data[1:5]
        _ipsc_src = _data[5:9]
        _seq_num = _data[9:13]
        _ts = _data[13]
        _status = _data[15]  # suspect [14:16] but nothing in leading byte?
        _rf_src = _data[16:19]
        _rf_tgt = _data[19:22]
        _type = _data[22]
        _prio = _data[23]
        _sec = _data[24]

        _source = str(int_id(_source)) + ', ' + str(
            get_info(int_id(_source), peer_ids))
        _ipsc_src = str(int_id(_ipsc_src)) + ', ' + str(
            get_info(int_id(_ipsc_src), peer_ids))
        _rf_src = str(int_id(_rf_src)) + ', ' + str(
            get_info(int_id(_rf_src), subscriber_ids))

        if _type == '\x4F' or '\x51':
            _rf_tgt = 'TGID: ' + str(int_id(_rf_tgt)) + ', ' + str(
                get_info(int_id(_rf_tgt), talkgroup_ids))
        else:
            _rf_tgt = 'SID: ' + str(int_id(_rf_tgt)) + ', ' + str(
                get_info(int_id(_rf_tgt), subscriber_ids))

        print('Call Monitor - Call Status')
        print('TIME:        ',
              datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        print('DATA SOURCE: ', _source)
        print('IPSC:        ', _network)
        print('IPSC Source: ', _ipsc_src)
        print('Timeslot:    ', TS[_ts])
        try:
            print('Status:      ', STATUS[_status])
        except KeyError:
            print('Status (unknown): ', h(_status))
        try:
            print('Type:        ', TYPE[_type])
        except KeyError:
            print('Type (unknown): ', h(_type))
        print('Source Sub:  ', _rf_src)
        print('Target Sub:  ', _rf_tgt)
        print()
Ejemplo n.º 9
0
def de_register_peer(_network, _peerid):
    # Iterate for the peer in our data
    if _peerid in NETWORK[_network]['PEERS'].keys():
        del NETWORK[_network]['PEERS'][_peerid]
        logger.info('(%s) Peer De-Registration Requested for: %s', _network, h(_peerid))
        return
    else:
        logger.warning('(%s) Peer De-Registration Requested for: %s, but we don\'t have a listing for this peer', _network, h(_peerid))
        pass
Ejemplo n.º 10
0
 def readAmbeFrameFromUDP( self, _sock ):
     _ambeAll = BitArray()               # Start with an empty array
     for i in range(0, 3):
         _ambe = self.readSock(_sock,7)  # Read AMBE from the socket
         if _ambe:
             _ambe1 = BitArray('0x'+h(_ambe[0:49]))
             _ambeAll += _ambe1[0:50]    # Append the 49 bits to the string
         else:
             break
     return _ambeAll.tobytes()           # Return the 49 * 3 as an array of bytes
Ejemplo n.º 11
0
 def readAmbeFrameFromUDP(self, _sock):
     _ambeAll = BitArray()  # Start with an empty array
     for i in range(0, 3):
         _ambe = self.readSock(_sock, 7)  # Read AMBE from the socket
         if _ambe:
             _ambe1 = BitArray('0x' + h(_ambe[0:49]))
             _ambeAll += _ambe1[0:50]  # Append the 49 bits to the string
         else:
             break
     return _ambeAll.tobytes()  # Return the 49 * 3 as an array of bytes
Ejemplo n.º 12
0
 def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data):
     _bits = int_id(_data[15])
     if _call_type == 'group':
         _routed = False
         for rule in RULES[self._master]['GROUP_VOICE']:
             _target = rule['DST_NET']
             if (rule['SRC_GROUP'] == _dst_id and rule['SRC_TS'] == _slot and rule['ACTIVE'] == True):
                 if rule['SRC_TS'] != rule['DST_TS']:
                     _tmp_bits = _bits ^ 1 << 7
                 else:
                     _tmp_bits = _bits
                 _tmp_data = _data[:8] + rule['DST_GROUP'] + _data[11:15] + chr(_tmp_bits) + _data[16:]
                 print(h(_data))
                 print(h(_tmp_data))
                 systems[_target].send_system(_tmp_data)
                 _routed = True
             
                 logger.debug('(%s) Packet routed to %s system: %s', self._master, CONFIG['SYSTEMS'][_target]['MODE'], _target)
         if not _routed:
             logger.debug('(%s) Packet router no target TS/TGID %s/%s', self._master, _slot, int_id(_dst_id))
Ejemplo n.º 13
0
def E(S):
    w().prec = b(e(o(S) * 2.40823996531)) + 1
    a = (lambda: [
        D(O(48) + O(46) + j((lambda: X(h(S), 4 + 4 * 4 - 4))
                            ())) * Q - Q / D(2),
        j(v(D(5.2)) + S) + v(U(z(j(e(2.71)))))
    ][0])()
    return j((lambda P: U(
        X(
            v((D(1) - s(a) * s(a + D(1) - D(7 - 5) + D(3) - D(6 - 4))).sqrt())[
                2:])))(lambda: [-2, X(j(v(1)), 13)][1]))[2:-1]
Ejemplo n.º 14
0
def E(S):
    getcontext().prec = b(e(o(S) * 2.40823996531)) + 1
    a = (lambda: [
        Decimal(O(48) + O(46) + j((lambda: long(h(S), 4 + 4 * 4 - 4))
                                  ())) * Q - Q / Decimal(2),
        j(v(Decimal(5.2)) + S) + v(U(z(j(e(2.71)))))
    ][0])()
    return j((lambda P: U(
        long(
            v((Decimal(1) - s(a) * s(a + Decimal(1) - Decimal(7 - 5) + Decimal(
                3) - Decimal(6 - 4))).sqrt())[2:]))
              )(lambda: [-2, long(j(v(1)), 13)][1]))[2:-1]
Ejemplo n.º 15
0
 def call_mon_status(self, _network, _data):
     if not status:
         return
     _source =   _data[1:5]
     _ipsc_src = _data[5:9]
     _seq_num =  _data[9:13]
     _ts =       _data[13]
     _status =   _data[15] # suspect [14:16] but nothing in leading byte?
     _rf_src =   _data[16:19]
     _rf_tgt =   _data[19:22]
     _type =     _data[22]
     _prio =     _data[23]
     _sec =      _data[24]
     
     _source = get_info(int_id(_source), peer_ids)
     _ipsc_src = get_info(int_id(_ipsc_src), peer_ids)
     _rf_src = get_info(int_id(_rf_src), subscriber_ids)
     
     if _type == '\x4F' or '\x51':
         _rf_tgt = get_info(int_id(_rf_tgt), talkgroup_ids)
     else:
         _rf_tgt = get_info(int_id(_rf_tgt), subscriber_ids)
     
     print('Call Monitor - Call Status')
     print('TIME:        ', datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
     print('DATA SOURCE: ', _source)
     print('IPSC:        ', _network)
     print('IPSC Source: ', _ipsc_src)
     print('Timeslot:    ', TS[_ts])
     try:
         print('Status:      ', STATUS[_status])
     except KeyError:
         print('Status (unknown): ', h(status))
     try:
         print('Type:        ', TYPE[_type])
     except KeyError:
         print('Type (unknown): ', h(_type))
     print('Source Sub:  ', _rf_src)
     print('Target Sub:  ', _rf_tgt)
     print()
Ejemplo n.º 16
0
def print_master(_network):
    _master = NETWORK[_network]['MASTER']
    print('Master for %s' % _network)
    print('\tRADIO ID: {}' .format(int(h(_master['RADIO_ID']), 16)))
    if _master['MODE_DECODE'] and REPORTS['PEER_REPORT_INC_MODE']:
        print('\t\tMode Values:')
        for name, value in _master['MODE_DECODE'].items():
            print('\t\t\t{}: {}' .format(name, value))
    if _master['FLAGS_DECODE'] and REPORTS['PEER_REPORT_INC_FLAGS']:
        print('\t\tService Flags:')
        for name, value in _master['FLAGS_DECODE'].items():
            print('\t\t\t{}: {}' .format(name, value))
    print('\t\tStatus: {},  KeepAlives Sent: {},  KeepAlives Outstanding: {},  KeepAlives Missed: {}' .format(_master['STATUS']['CONNECTED'], _master['STATUS']['KEEP_ALIVES_SENT'], _master['STATUS']['KEEP_ALIVES_OUTSTANDING'], _master['STATUS']['KEEP_ALIVES_MISSED']))
Ejemplo n.º 17
0
 def call_mon_rpt(self, _network, _data):
     if not rpt:
         return
     _source    = _data[1:5]
     _ts1_state = _data[5]
     _ts2_state = _data[6]
     
     _source = get_info(int_id(_source), peer_ids)
     
     print('Call Monitor - Repeater State')
     print('TIME:         ', datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
     print('DATA SOURCE:  ', _source)
  
     try:
         print('TS1 State:    ', REPEAT[_ts1_state])
     except KeyError:
         print('TS1 State (unknown): ', h(_ts1_state))
     try:
         print('TS2 State:    ', REPEAT[_ts2_state])
     except KeyError:
         print('TS2 State (unknown): ', h(_ts2_state))
     print()
Ejemplo n.º 18
0
    def call_mon_rpt(self, _network, _data):
        if not rpt:
            return
        _source = _data[1:5]
        _ts1_state = _data[5]
        _ts2_state = _data[6]

        _source = get_info(int_id(_source), peer_ids)

        print('Call Monitor - Repeater State')
        print('TIME:         ',
              datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        print('DATA SOURCE:  ', _source)

        try:
            print('TS1 State:    ', REPEAT[_ts1_state])
        except KeyError:
            print('TS1 State (unknown): ', h(_ts1_state))
        try:
            print('TS2 State:    ', REPEAT[_ts2_state])
        except KeyError:
            print('TS2 State (unknown): ', h(_ts2_state))
        print()
Ejemplo n.º 19
0
    def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid,
                    _data):
        # THIS FUNCTION IS NOT COMPLETE!!!!
        _payload_type = _data[30:31]
        # _ambe_frames = _data[33:52]
        _ambe_frames = BitArray('0x' + h(_data[33:52]))
        _ambe_frame1 = _ambe_frames[0:49]
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]

        _tg_id = int_id(_dst_sub)
        if _tg_id in self._tg_filter:  #All TGs
            _dst_sub = get_info(int_id(_dst_sub), talkgroup_ids)
            if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
                if self._currentTG == self._no_tg:
                    _src_sub = get_info(int_id(_src_sub), subscriber_ids)
                    print(
                        'Voice Transmission Start on TS {} and TG {} ({}) from {}'
                        .format("2" if _ts else "1", _dst_sub, _tg_id,
                                _src_sub))
                    self._currentTG = _tg_id
                    self._transmitStartTime = time()
                else:
                    if self._currentTG != _tg_id:
                        if time() > self.lastPacketTimeout:
                            self._currentTG = self._no_tg  #looks like we never saw an EOT from the last stream
                            print('EOT timeout')
                        else:
                            print(
                                'Transmission in progress, will not decode stream on TG {}'
                                .format(_tg_id))
            if self._currentTG == _tg_id:
                if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
                    print('Voice Transmission End %.2f seconds' %
                          (time() - self._transmitStartTime))
                    self._currentTG = self._no_tg
                if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2,
                                      _ambe_frame3)
                if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2,
                                      _ambe_frame3)
                self.lastPacketTimeout = time() + 10

        else:
            if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
                _dst_sub = get_info(int_id(_dst_sub), talkgroup_ids)
                print('Ignored Voice Transmission Start on TS {} and TG {}'.
                      format("2" if _ts else "1", _dst_sub))
Ejemplo n.º 20
0
 def call_mon_nack(self, _network, _data):
     if not nack:
         return
     _source = _data[1:5]
     _nack =   _data[5]
     
     _source = get_info(int_id(_source), peer_ids)
     
     print('Call Monitor - Transmission NACK')
     print('TIME:        ', datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
     print('DATA SOURCE: ', _source)
     try:
         print('NACK Cause:  ', NACK[_nack])
     except KeyError:
         print('NACK Cause (unknown): ', h(_nack))
     print()
Ejemplo n.º 21
0
    def call_mon_nack(self, _network, _data):
        if not nack:
            return
        _source = _data[1:5]
        _nack = _data[5]

        _source = get_info(int_id(_source), peer_ids)

        print('Call Monitor - Transmission NACK')
        print('TIME:        ',
              datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        print('DATA SOURCE: ', _source)
        try:
            print('NACK Cause:  ', NACK[_nack])
        except KeyError:
            print('NACK Cause (unknown): ', h(_nack))
        print()
Ejemplo n.º 22
0
    def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
        # THIS FUNCTION IS NOT COMPLETE!!!!
        _payload_type = _data[30:31]
        # _ambe_frames = _data[33:52]
        _ambe_frames = BitArray("0x" + h(_data[33:52]))
        _ambe_frame1 = _ambe_frames[0:49]
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]

        _tg_id = int_id(_dst_sub)
        if _tg_id in self._tg_filter:  # All TGs
            _dst_sub = get_info(int_id(_dst_sub), talkgroup_ids)
            if _payload_type == BURST_DATA_TYPE["VOICE_HEAD"]:
                if self._currentTG == self._no_tg:
                    _src_sub = get_info(int_id(_src_sub), subscriber_ids)
                    print(
                        "Voice Transmission Start on TS {} and TG {} ({}) from {}".format(
                            "2" if _ts else "1", _dst_sub, _tg_id, _src_sub
                        )
                    )
                    self._currentTG = _tg_id
                    self._transmitStartTime = time()
                else:
                    if self._currentTG != _tg_id:
                        if time() > self.lastPacketTimeout:
                            self._currentTG = self._no_tg  # looks like we never saw an EOT from the last stream
                            print("EOT timeout")
                        else:
                            print("Transmission in progress, will not decode stream on TG {}".format(_tg_id))
            if self._currentTG == _tg_id:
                if _payload_type == BURST_DATA_TYPE["VOICE_TERM"]:
                    print("Voice Transmission End %.2f seconds" % (time() - self._transmitStartTime))
                    self._currentTG = self._no_tg
                if _payload_type == BURST_DATA_TYPE["SLOT1_VOICE"]:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2, _ambe_frame3)
                if _payload_type == BURST_DATA_TYPE["SLOT2_VOICE"]:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2, _ambe_frame3)
                self.lastPacketTimeout = time() + 10

        else:
            if _payload_type == BURST_DATA_TYPE["VOICE_HEAD"]:
                _dst_sub = get_info(int_id(_dst_sub), talkgroup_ids)
                print("Ignored Voice Transmission Start on TS {} and TG {}".format("2" if _ts else "1", _dst_sub))
Ejemplo n.º 23
0
    def parseAMBE(self, _client, _data):
        _seq = int_id(_data[4:5])
        _srcID = int_id(_data[5:8])
        _dstID = int_id(_data[8:11])
        _rptID = int_id(_data[11:15])
        _bits = int_id(_data[15:16])       # SCDV NNNN (Slot|Call type|Data|Voice|Seq or Data type)
        _slot = 2 if _bits & 0x80 else 1
        _callType = 1 if (_bits & 0x40) else 0
        _frameType = (_bits & 0x30) >> 4
        _voiceSeq = (_bits & 0x0f)
        _streamID = int_id(_data[16:20])
        logger.debug('(%s) seq: %d srcID: %d dstID: %d rptID: %d bits: %0X slot:%d callType: %d frameType:  %d voiceSeq: %d streamID: %0X',
        _client, _seq, _srcID, _dstID, _rptID, _bits, _slot, _callType, _frameType, _voiceSeq, _streamID )

        #logger.debug('Frame 1:(%s)', self.ByteToHex(_data))
        _dmr_frame = BitArray('0x'+h(_data[20:]))
        _ambe = _dmr_frame[0:108] + _dmr_frame[156:264]
        #_sock.sendto(_ambe.tobytes(), ("127.0.0.1", 31000))

        ambeBytes = _ambe.tobytes()
        self._sock.sendto(ambeBytes[0:9], (self._exp_ip, self._exp_port))
        self._sock.sendto(ambeBytes[9:18], (self._exp_ip, self._exp_port))
        self._sock.sendto(ambeBytes[18:27], (self._exp_ip, self._exp_port))
Ejemplo n.º 24
0
 def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
     # THIS FUNCTION IS NOT COMPLETE!!!!
     _payload_type = _data[30:31]
     # _ambe_frames = _data[33:52]
     _ambe_frames = BitArray('0x'+h(_data[33:52]))
     _ambe_frame1 = _ambe_frames[0:49]
     _ambe_frame2 = _ambe_frames[50:99]
     _ambe_frame3 = _ambe_frames[100:149]
     
     if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
         print('Voice Transmission Start')
     if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
         print('Voice Transmission End')
     if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
         print(_ambe_frames)
         print('Frame 1:', _ambe_frame1.bytes)
         print('Frame 2:', _ambe_frame2.bytes)
         print('Frame 3:', _ambe_frame3.bytes)
     if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
         print(_ambe_frames)
         print('Frame 1:', _ambe_frame1.bytes)
         print('Frame 2:', _ambe_frame2.bytes)
         print('Frame 3:', _ambe_frame3.bytes)
Ejemplo n.º 25
0
    def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid,
                    _data):
        # THIS FUNCTION IS NOT COMPLETE!!!!
        _payload_type = _data[30:31]
        # _ambe_frames = _data[33:52]
        _ambe_frames = BitArray('0x' + h(_data[33:52]))
        _ambe_frame1 = _ambe_frames[0:49]
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]

        if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
            print('Voice Transmission Start')
        if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
            print('Voice Transmission End')
        if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
            print(_ambe_frames)
            print('Frame 1:', _ambe_frame1.bytes)
            print('Frame 2:', _ambe_frame2.bytes)
            print('Frame 3:', _ambe_frame3.bytes)
        if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
            print(_ambe_frames)
            print('Frame 1:', _ambe_frame1.bytes)
            print('Frame 2:', _ambe_frame2.bytes)
            print('Frame 3:', _ambe_frame3.bytes)
Ejemplo n.º 26
0
def int_id(_hex_string):
    return int(h(_hex_string), 16)
Ejemplo n.º 27
0
    def group_voice(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):

        #self.dumpIPSCFrame(_data)

        # THIS FUNCTION IS NOT COMPLETE!!!!
        _payload_type = _data[30:31]
        # _ambe_frames = _data[33:52]
        _ambe_frames = BitArray('0x' + h(_data[33:52]))
        _ambe_frame1 = _ambe_frames[0:49]
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]

        _tg_id = int_id(_dst_sub)

        self._busy_slots[_ts] = time()

        ###### DEBUGDEBUGDEBUG
        #        if _tg_id == 2:
        #            __iLen = len(_data)
        #            self._d.write(struct.pack("i", __iLen))
        #            self._d.write(_data)
        #        else:
        #            self.rewriteFrame(_data, 1, 9)
        ###### DEBUGDEBUGDEBUG

        if _tg_id in self._tg_filter:  #All TGs
            _dst_sub = get_alias(_dst_sub, talkgroup_ids)
            if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
                if self._currentTG == self._no_tg:
                    _src_sub = get_subscriber_info(_src_sub)
                    logger.info(
                        'Voice Transmission Start on TS {} and TG {} ({}) from {}'
                        .format(_ts, _dst_sub, _tg_id, _src_sub))
                    self._sock.sendto(
                        'reply log2 {} {}'.format(_src_sub, _tg_id),
                        (self._dmrgui, 34003))

                    self._currentTG = _tg_id
                    self._transmitStartTime = time()
                    self._start_seq = int_id(_data[20:22])
                    self._packet_count = 0
                else:
                    if self._currentTG != _tg_id:
                        if time() > self.lastPacketTimeout:
                            self._currentTG = self._no_tg  #looks like we never saw an EOT from the last stream
                            logger.warning('EOT timeout')
                        else:
                            logger.warning(
                                'Transmission in progress, will not decode stream on TG {}'
                                .format(_tg_id))
            if self._currentTG == _tg_id:
                if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
                    _source_packets = (
                        int_id(_data[20:22]) - self._start_seq
                    ) - 3  # the 3 is because  the start and end are not part of the voice but counted in the RTP
                    if self._packet_count > _source_packets:
                        self._packet_count = _source_packets
                    if _source_packets > 0:
                        _lost_percentage = 100.0 - (
                            (self._packet_count / float(_source_packets)) *
                            100.0)
                    else:
                        _lost_percentage = 0.0
                    _duration = (time() - self._transmitStartTime)
                    logger.info(
                        'Voice Transmission End {:.2f} seconds loss rate: {:.2f}% ({}/{})'
                        .format(_duration, _lost_percentage,
                                _source_packets - self._packet_count,
                                _source_packets))
                    self._sock.sendto(
                        "reply log" +
                        strftime(" %m/%d/%y %H:%M:%S",
                                 localtime(self._transmitStartTime)) +
                        ' {} {} "{}"'.format(get_subscriber_info(_src_sub),
                                             _ts, _dst_sub) +
                        ' {:.2f}%'.format(_lost_percentage) +
                        ' {:.2f}s'.format(_duration), (self._dmrgui, 34003))
                    self._currentTG = self._no_tg
                if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2,
                                      _ambe_frame3)
                    self._packet_count += 1
                if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2,
                                      _ambe_frame3)
                    self._packet_count += 1
                self.lastPacketTimeout = time() + 10

        else:
            if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
                _dst_sub = get_alias(_dst_sub, talkgroup_ids)
                logger.warning(
                    'Ignored Voice Transmission Start on TS {} and TG {}'.
                    format(_ts, _dst_sub))
Ejemplo n.º 28
0
def s(x):
    w().prec += 5
    i, L, s, f, n, S = 1, 0, x, 1, x, 1
    while s != L:
        L = s
        i += 2
        f *= i * (i - 1)
        n *= x * x
        S *= -1
        s += n / f * S
    w().prec -= 5
    return +s


def E(S):
    w().prec = b(e(o(S) * 2.40823996531)) + 1
    a = (lambda: [
        D(O(48) + O(46) + j((lambda: X(h(S), 4 + 4 * 4 - 4))
                            ())) * Q - Q / D(2),
        j(v(D(5.2)) + S) + v(U(z(j(e(2.71)))))
    ][0])()
    return j((lambda P: U(
        X(
            v((D(1) - s(a) * s(a + D(1) - D(7 - 5) + D(3) - D(6 - 4))).sqrt())[
                2:])))(lambda: [-2, X(j(v(1)), 13)][1]))[2:-1]


A = h("Usage: " + y[0] + " <string>") if o(y) != 2 else E(y[1])
f = open("out.txt", O(b('7' + '7', (4**4) / 4 / 4)))
f.write(u(A[:-1] if z(A) % 2 == 1 else A))
f.close()
Ejemplo n.º 29
0
                          encryption._SHA1AES256)
    if session_key.enctype == encryption.Enctype.AES128:
        return GSSAPI_AES(session_key, encryption._AES128CTS,
                          encryption._SHA1AES128)
    elif session_key.enctype == encryption.Enctype.RC4:
        return GSSAPI_RC4(session_key)
    else:
        raise Exception('Unsupported etype %s' % session_key.enctype)


if __name__ == '__main__':
    from binascii import unhexlify as h
    from minikerberos.utils import as_hex

    data_padded = h('810e00001a204de2d64fd111a3da0000f875ae0d1c45000034000000'
                    '34000000008040050000000000000000000000000000000000000000'
                    '000000000000000000000000000000000000000000000000ffffffff'
                    'ffffffffffffffffffffffff')

    token_1 = h('050406ff000c00000000000000000000')
    cipherText_1 = h(
        '0880ed78d6196dde3f3fb23eeea650bc4ae025fa2a9c337c75c024d9d'
        '8f0186c75a4a9060e2a40a9ad024317bf5df6a86cb4a764a9ca36843f'
        '8fa4f99c03e2bde46f5a29aafc83dacdf9f0a5677446b5d910417142d'
        'c7b7ba7ded76cddc4acf9bf7ed44008cb9850e5701f2f9285dad6463c'
        'a8d0e365d4f1700f3d054e242ebcde2f3146ddd411a627af7486')

    cipherText_2 = h(
        '08cb9850e5701f2f9285dad6463ca8d0e365d4f1700f3d054e242ebcde2'
        'f3146ddd411a627af74860880ed78d6196dde3f3fb23eeea650bc4ae025'
        'fa2a9c337c75c024d9d8f0186c75a4a9060e2a40a9ad024317bf5df6a86'
        'cb4a764a9ca36843f8fa4f99c03e2bde46f5a29aafc83dacdf9f0a56774'
Ejemplo n.º 30
0
 def call_mon_rpt(self, _network, _data):
     logger.debug('(%s) Repeater Call Monitor Repeating Packet Received: %s', _network, h(_data))
Ejemplo n.º 31
0
def int_id(_hex_string):
    return int(h(_hex_string), 16)
Ejemplo n.º 32
0
class HBMASTER(DatagramProtocol):
    def __init__(self, *args, **kwargs):
        if len(args) == 1:
            # Define a few shortcuts to make the rest of the class more readable
            self._master = args[0]
            self._system = self._master
            self._config = CONFIG['SYSTEMS'][self._master]
            self._clients = CONFIG['SYSTEMS'][self._master]['CLIENTS']

            # Configure for AMBE audio export if enabled
            if self._config['EXPORT_AMBE']:
                self._ambe = AMBE()
        else:
            # If we didn't get called correctly, log it and quit.
            logger.error(
                '(%s) HBMASTER was not called with an argument. Terminating',
                self._master)
            sys.exit()

    def startProtocol(self):
        # Set up periodic loop for tracking pings from clients. Run every 'PING_TIME' seconds
        self._master_maintenance = task.LoopingCall(
            self.master_maintenance_loop)
        self._master_maintenance_loop = self._master_maintenance.start(
            CONFIG['GLOBAL']['PING_TIME'])

    def master_maintenance_loop(self):
        logger.debug('(%s) Master maintenance loop started', self._master)
        for client in self._clients:
            _this_client = self._clients[client]
            # Check to see if any of the clients have been quiet (no ping) longer than allowed
            if _this_client['LAST_PING'] + CONFIG['GLOBAL'][
                    'PING_TIME'] * CONFIG['GLOBAL']['MAX_MISSED'] < time():
                logger.info('(%s) Client %s (%s) has timed out', self._master,
                            _this_client['CALLSIGN'], _this_client['RADIO_ID'])
                # Remove any timed out clients from the configuration
                del CONFIG['SYSTEMS'][self._master]['CLIENTS'][client]

    def send_clients(self, _packet):
        for _client in self._clients:
            self.send_client(_client, _packet)
            #logger.debug('(%s) Packet sent to client %s', self._master, self._clients[_client]['RADIO_ID'])

    def send_client(self, _client, _packet):
        _ip = self._clients[_client]['IP']
        _port = self._clients[_client]['PORT']
        self.transport.write(_packet, (_ip, _port))
        # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
        #logger.debug('(%s) TX Packet to %s on port %s: %s', self._clients[_client]['RADIO_ID'], self._clients[_client]['IP'], self._clients[_client]['PORT'], h(_packet))

    # Alias for other programs to use a common name to send a packet
    # regardless of the system type (MASTER or CLIENT)
    send_system = send_clients

    def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _slot,
                      _call_type, _frame_type, _stream_id, _data):
        pass

    def datagramReceived(self, _data, (_host, _port)):
        # Keep This Line Commented Unless HEAVILY Debugging!
        #logger.debug('(%s) RX packet from %s:%s -- %s', self._master, _host, _port, h(_data))

        # Extract the command, which is various length, all but one 4 significant characters -- RPTCL
        _command = _data[:4]

        if _command == 'DMRD':  # DMRData -- encapsulated DMR data frame
            _radio_id = _data[11:15]
            if _radio_id in self._clients \
                        and self._clients[_radio_id]['CONNECTION'] == 'YES' \
                        and self._clients[_radio_id]['IP'] == _host \
                        and self._clients[_radio_id]['PORT'] == _port:
                _seq = _data[4]
                _rf_src = _data[5:8]
                _dst_id = _data[8:11]
                _bits = int_id(_data[15])
                _slot = 2 if (_bits & 0x80) else 1
                _call_type = 'unit' if (_bits & 0x40) else 'group'
                _raw_frame_type = (_bits & 0x30) >> 4
                if _raw_frame_type == 0b00:
                    _frame_type = 'voice'
                elif _raw_frame_type == 0b01:
                    _frame_type = 'voice_sync'
                elif _raw_frame_type == 0b10:
                    _frame_type = 'data_sync'
                else:
                    _frame_type = 'none'
                _stream_id = _data[16:20]
                #logger.debug('(%s) DMRD - Seqence: %s, RF Source: %s, Destination ID: %s', self._master, int_id(_seq), int_id(_rf_src), int_id(_dst_id))

                # If AMBE audio exporting is configured...
                if self._config['EXPORT_AMBE']:
                    self._ambe.parseAMBE(self._master, _data)

                # The basic purpose of a master is to repeat to the clients
                if self._config['REPEAT'] == True:
                    for _client in self._clients:
                        if _client != _radio_id:
                            self.send_client(_client, _data)
                            logger.debug(
                                '(%s) Packet on TS%s from %s (%s) for destination ID %s repeated to client: %s (%s) [Stream ID: %s]',
                                self._master, _slot,
                                self._clients[_radio_id]['CALLSIGN'],
                                int_id(_radio_id), int_id(_dst_id),
                                self._clients[_client]['CALLSIGN'],
                                int_id(_client), int_id(_stream_id))

                # Userland actions -- typically this is the function you subclass for an application
                self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot,
                                   _call_type, _frame_type, _stream_id, _data)

        elif _command == 'RPTL':  # RPTLogin -- a repeater wants to login
            _radio_id = _data[4:8]
            if _radio_id:  # Future check here for valid Radio ID
                self._clients.update({_radio_id: {      # Build the configuration data strcuture for the client
                    'CONNECTION': 'RPTL-RECEIVED',
                    'PINGS_RECEIVED': 0,
                    'LAST_PING': time(),
                    'IP': _host,
                    'PORT': _port,
                    'SALT': randint(0,0xFFFFFFFF),
                    'RADIO_ID': str(int(h(_radio_id), 16)),
                    'CALLSIGN': '',
                    'RX_FREQ': '',
                    'TX_FREQ': '',
                    'TX_POWER': '',
                    'COLORCODE': '',
                    'LATITUDE': '',
                    'LONGITUDE': '',
                    'HEIGHT': '',
                    'LOCATION': '',
                    'DESCRIPTION': '',
                    'SLOTS': '',
                    'URL': '',
                    'SOFTWARE_ID': '',
                    'PACKAGE_ID': '',
                }})
                logger.info(
                    '(%s) Repeater Logging in with Radio ID: %s, %s:%s',
                    self._master, int_id(_radio_id), _host, _port)
                _salt_str = hex_str_4(self._clients[_radio_id]['SALT'])
                self.send_client(_radio_id, 'RPTACK' + _salt_str)
                self._clients[_radio_id]['CONNECTION'] = 'CHALLENGE_SENT'
                logger.info('(%s) Sent Challenge Response to %s for login: %s',
                            self._master, int_id(_radio_id),
                            self._clients[_radio_id]['SALT'])
            else:
                self.transport.write('MSTNAK' + _radio_id, (_host, _port))
                logger.warning('(%s) Invalid Login from Radio ID: %s',
                               self._master, int_id(_radio_id))

        elif _command == 'RPTK':  # Repeater has answered our login challenge
            _radio_id = _data[4:8]
            if _radio_id in self._clients \
                        and self._clients[_radio_id]['CONNECTION'] == 'CHALLENGE_SENT' \
                        and self._clients[_radio_id]['IP'] == _host \
                        and self._clients[_radio_id]['PORT'] == _port:
                _this_client = self._clients[_radio_id]
                _this_client['LAST_PING'] = time()
                _sent_hash = _data[8:]
                _salt_str = hex_str_4(_this_client['SALT'])
                _calc_hash = a(
                    sha256(_salt_str + self._config['PASSPHRASE']).hexdigest())
                if _sent_hash == _calc_hash:
                    _this_client['CONNECTION'] = 'WAITING_CONFIG'
                    self.send_client(_radio_id, 'RPTACK' + _radio_id)
                    logger.info(
                        '(%s) Client %s has completed the login exchange successfully',
                        self._master, _this_client['RADIO_ID'])
                else:
                    logger.info(
                        '(%s) Client %s has FAILED the login exchange successfully',
                        self._master, _this_client['RADIO_ID'])
                    self.transport.write('MSTNAK' + _radio_id, (_host, _port))
                    del self._clients[_radio_id]
            else:
                self.transport.write('MSTNAK' + _radio_id, (_host, _port))
                logger.warning(
                    '(%s) Login challenge from Radio ID that has not logged in: %s',
                    self._master, int_id(_radio_id))

        elif _command == 'RPTC':  # Repeater is sending it's configuraiton OR disconnecting
            if _data[:5] == 'RPTCL':  # Disconnect command
                _radio_id = _data[5:9]
                if _radio_id in self._clients \
                            and self._clients[_radio_id]['CONNECTION'] == 'YES' \
                            and self._clients[_radio_id]['IP'] == _host \
                            and self._clients[_radio_id]['PORT'] == _port:
                    logger.info('(%s) Client is closing down: %s (%s)',
                                self._master,
                                self._clients[_radio_id]['CALLSIGN'],
                                int_id(_radio_id))
                    self.transport.write('MSTNAK' + _radio_id, (_host, _port))
                    del self._clients[_radio_id]
            else:
                _radio_id = _data[4:8]  # Configure Command
                if _radio_id in self._clients \
                            and self._clients[_radio_id]['CONNECTION'] == 'WAITING_CONFIG' \
                            and self._clients[_radio_id]['IP'] == _host \
                            and self._clients[_radio_id]['PORT'] == _port:
                    _this_client = self._clients[_radio_id]
                    _this_client['CONNECTION'] = 'YES'
                    _this_client['LAST_PING'] = time()
                    _this_client['CALLSIGN'] = _data[8:16]
                    _this_client['RX_FREQ'] = _data[16:25]
                    _this_client['TX_FREQ'] = _data[25:34]
                    _this_client['TX_POWER'] = _data[34:36]
                    _this_client['COLORCODE'] = _data[36:38]
                    _this_client['LATITUDE'] = _data[38:47]
                    _this_client['LONGITUDE'] = _data[47:57]
                    _this_client['HEIGHT'] = _data[57:60]
                    _this_client['LOCATION'] = _data[60:80]
                    _this_client['DESCRIPTION'] = _data[80:99]
                    _this_client['SLOTS'] = _data[99:100]
                    _this_client['URL'] = _data[100:224]
                    _this_client['SOFTWARE_ID'] = _data[224:264]
                    _this_client['PACKAGE_ID'] = _data[264:304]

                    self.send_client(_radio_id, 'RPTACK' + _radio_id)
                    logger.info(
                        '(%s) Client %s (%s) has sent repeater configuration',
                        self._master, _this_client['CALLSIGN'],
                        _this_client['RADIO_ID'])
                else:
                    self.transport.write('MSTNAK' + _radio_id, (_host, _port))
                    logger.warning(
                        '(%s) Client info from Radio ID that has not logged in: %s',
                        self._master, int_id(_radio_id))

        elif _command == 'RPTP':  # RPTPing -- client is pinging us
            _radio_id = _data[7:11]
            if _radio_id in self._clients \
                        and self._clients[_radio_id]['CONNECTION'] == "YES" \
                        and self._clients[_radio_id]['IP'] == _host \
                        and self._clients[_radio_id]['PORT'] == _port:
                self._clients[_radio_id]['LAST_PING'] = time()
                self.send_client(_radio_id, 'MSTPONG' + _radio_id)
                logger.debug(
                    '(%s) Received and answered RPTPING from client %s (%s)',
                    self._master, self._clients[_radio_id]['CALLSIGN'],
                    int_id(_radio_id))
            else:
                self.transport.write('MSTNAK' + _radio_id, (_host, _port))
                logger.warning(
                    '(%s) Client info from Radio ID that has not logged in: %s',
                    self._master, int_id(_radio_id))

        else:
            logger.error('(%s) Unrecognized command from: %s. Packet: %s',
                         self._master, int_id(_radio_id), h(_data))
Ejemplo n.º 33
0
 def unknown_message(self, _network, _packettype, _peerid, _data):
     _packettype = h(_packettype)
     _peerid = get_info(int_id(_peerid), peer_ids)
     logger.error('(%s) Unknown message type encountered\n\tPacket Type: %s\n\tFrom: %s\n\tPacket: %s', _network, _packettype, _peerid, h(_data))
Ejemplo n.º 34
0
 def repeater_wake_up(self, _network, _data):
     logger.debug('(%s) Repeater Wake-Up Packet Received: %s', _network, h(_data))
Ejemplo n.º 35
0
 def xcmp_xnl(self, _network, _data):
     logger.debug('(%s) XCMP/XNL Packet Received: %s', _network, h(_data))
Ejemplo n.º 36
0
 def call_mon_nack(self, _network, _data):
     logger.debug('(%s) Repeater Call Monitor NACK Packet Received: %s', _network, h(_data))
Ejemplo n.º 37
0
class HBCLIENT(DatagramProtocol):
    def __init__(self, *args, **kwargs):
        if len(args) == 1:
            self._client = args[0]
            self._system = self._client
            self._config = CONFIG['SYSTEMS'][self._client]
            self._stats = self._config['STATS']

            # Configure for AMBE audio export if enabled
            if self._config['EXPORT_AMBE']:
                self._ambe = AMBE()
        else:
            # If we didn't get called correctly, log it!
            logger.error(
                '(%s) HBCLIENT was not called with an argument. Terminating',
                self._client)
            sys.exit()

    def startProtocol(self):
        # Set up periodic loop for sending pings to the master. Run every 'PING_TIME' seconds
        self._client_maintenance = task.LoopingCall(
            self.client_maintenance_loop)
        self._client_maintenance_loop = self._client_maintenance.start(
            CONFIG['GLOBAL']['PING_TIME'])

    def client_maintenance_loop(self):
        logger.debug('(%s) Client maintenance loop started', self._client)
        # If we're not connected, zero out the stats and send a login request RPTL
        if self._stats['CONNECTION'] == 'NO' or self._stats[
                'CONNECTION'] == 'RTPL_SENT':
            self._stats['PINGS_SENT'] = 0
            self._stats['PINGS_ACKD'] = 0
            self._stats['CONNECTION'] = 'RTPL_SENT'
            self.send_master('RPTL' + self._config['RADIO_ID'])
            logger.info('(%s) Sending login request to master %s:%s',
                        self._client, self._config['MASTER_IP'],
                        self._config['MASTER_PORT'])
        # If we are connected, sent a ping to the master and increment the counter
        if self._stats['CONNECTION'] == 'YES':
            self.send_master('RPTPING' + self._config['RADIO_ID'])
            self._stats['PINGS_SENT'] += 1
            logger.debug(
                '(%s) RPTPING Sent to Master. Pings Since Connected: %s',
                self._client, self._stats['PINGS_SENT'])

    def send_master(self, _packet):
        self.transport.write(
            _packet, (self._config['MASTER_IP'], self._config['MASTER_PORT']))
        # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
        #logger.debug('(%s) TX Packet to %s:%s -- %s', self._client, self._config['MASTER_IP'], self._config['MASTER_PORT'], h(_packet))

    # Alias for other programs to use a common name to send a packet
    # regardless of the system type (MASTER or CLIENT)
    send_system = send_master

    def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _slot,
                      _call_type, _frame_type, _stream_id, _data):
        pass

    def datagramReceived(self, _data, (_host, _port)):
        # Keep This Line Commented Unless HEAVILY Debugging!
        # logger.debug('(%s) RX packet from %s:%s -- %s', self._client, _host, _port, h(_data))

        # Validate that we receveived this packet from the master - security check!
        if self._config['MASTER_IP'] == _host and self._config[
                'MASTER_PORT'] == _port:
            # Extract the command, which is various length, but only 4 significant characters
            _command = _data[:4]
            if _command == 'DMRD':  # DMRData -- encapsulated DMR data frame
                _radio_id = _data[11:15]
                if _radio_id == self._config[
                        'RADIO_ID']:  # Validate the source and intended target
                    _seq = _data[4:5]
                    _rf_src = _data[5:8]
                    _dst_id = _data[8:11]
                    _bits = int_id(_data[15])
                    _slot = 2 if (_bits & 0x80) else 1
                    _call_type = 'unit' if (_bits & 0x40) else 'group'
                    _raw_frame_type = (_bits & 0x30) >> 4
                    if _raw_frame_type == 0b00:
                        _frame_type = 'voice'
                    elif _raw_frame_type == 0b01:
                        _frame_type = 'voice_sync'
                    elif _raw_frame_type == 0b10:
                        _frame_type = 'data_sync'
                    else:
                        _frame_type = 'none'
                    _stream_id = _data[16:20]

                    #logger.debug('(%s) DMRD - Seqence: %s, RF Source: %s, Destination ID: %s', self._client, h(_seq), int_id(_rf_src), int_id(_dst_id))

                    # If AMBE audio exporting is configured...
                    if self._config['EXPORT_AMBE']:
                        self._ambe.parseAMBE(self._client, _data)

                    # Userland actions -- typically this is the function you subclass for an application
                    self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq,
                                       _slot, _call_type, _frame_type,
                                       _stream_id, _data)

            elif _command == 'MSTN':  # Actually MSTNAK -- a NACK from the master
                _radio_id = _data[4:8]
                if _radio_id == self._config[
                        'RADIO_ID']:  # Validate the source and intended target
                    logger.warning('(%s) MSTNAK Received', self._client)
                    self._stats[
                        'CONNECTION'] = 'NO'  # Disconnect ourselves and re-register

            elif _command == 'RPTA':  # Actually RPTACK -- an ACK from the master
                # Depending on the state, an RPTACK means different things, in each clause, we check and/or set the state
                if self._stats[
                        'CONNECTION'] == 'RTPL_SENT':  # If we've sent a login request...
                    _login_int32 = _data[6:10]
                    logger.info(
                        '(%s) Repeater Login ACK Received with 32bit ID: %s',
                        self._client, int_id(_login_int32))
                    _pass_hash = sha256(
                        _login_int32 + self._config['PASSPHRASE']).hexdigest()
                    _pass_hash = a(_pass_hash)
                    self.send_master('RPTK' + self._config['RADIO_ID'] +
                                     _pass_hash)
                    self._stats['CONNECTION'] = 'AUTHENTICATED'

                elif self._stats[
                        'CONNECTION'] == 'AUTHENTICATED':  # If we've sent the login challenge...
                    if _data[6:10] == self._config['RADIO_ID']:
                        logger.info('(%s) Repeater Authentication Accepted',
                                    self._client)
                        _config_packet =  self._config['RADIO_ID']+\
                                          self._config['CALLSIGN']+\
                                          self._config['RX_FREQ']+\
                                          self._config['TX_FREQ']+\
                                          self._config['TX_POWER']+\
                                          self._config['COLORCODE']+\
                                          self._config['LATITUDE']+\
                                          self._config['LONGITUDE']+\
                                          self._config['HEIGHT']+\
                                          self._config['LOCATION']+\
                                          self._config['DESCRIPTION']+\
                                          self._config['SLOTS']+\
                                          self._config['URL']+\
                                          self._config['SOFTWARE_ID']+\
                                          self._config['PACKAGE_ID']

                        self.send_master('RPTC' + _config_packet)
                        self._stats['CONNECTION'] = 'CONFIG-SENT'
                        logger.info('(%s) Repeater Configuration Sent',
                                    self._client)
                    else:
                        self._stats['CONNECTION'] = 'NO'
                        logger.error(
                            '(%s) Master ACK Contained wrong ID - Connection Reset',
                            self._client)

                elif self._stats[
                        'CONNECTION'] == 'CONFIG-SENT':  # If we've sent out configuration to the master
                    if _data[6:10] == self._config['RADIO_ID']:
                        logger.info('(%s) Repeater Configuration Accepted',
                                    self._client)
                        self._stats['CONNECTION'] = 'YES'
                        logger.info('(%s) Connection to Master Completed',
                                    self._client)
                    else:
                        self._stats['CONNECTION'] = 'NO'
                        logger.error(
                            '(%s) Master ACK Contained wrong ID - Connection Reset',
                            self._client)

            elif _command == 'MSTP':  # Actually MSTPONG -- a reply to RPTPING (send by client)
                if _data[7:11] == self._config['RADIO_ID']:
                    self._stats['PINGS_ACKD'] += 1
                    logger.debug(
                        '(%s) MSTPONG Received. Pongs Since Connected: %s',
                        self._client, self._stats['PINGS_ACKD'])

            elif _command == 'MSTC':  # Actually MSTCL -- notify us the master is closing down
                if _data[5:9] == self._config['RADIO_ID']:
                    self._stats['CONNECTION'] = 'NO'
                    logger.info('(%s) MSTCL Recieved', self._client)

            else:
                logger.error('(%s) Received an invalid command in packet: %s',
                             self._client, h(_data))
Ejemplo n.º 38
0
    def group_voice(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
        
        #self.dumpIPSCFrame(_data)
        
        # THIS FUNCTION IS NOT COMPLETE!!!!
        _payload_type = _data[30:31]
        # _ambe_frames = _data[33:52]
        _ambe_frames = BitArray('0x'+h(_data[33:52])) 
        _ambe_frame1 = _ambe_frames[0:49]
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]
        
        _tg_id = int_id(_dst_sub)
        
        self._busy_slots[_ts] = time()
        
        ###### DEBUGDEBUGDEBUG
#        if _tg_id == 2:
#            __iLen = len(_data)
#            self._d.write(struct.pack("i", __iLen))
#            self._d.write(_data)
#        else:
#            self.rewriteFrame(_data, self._system, 1, 9)
        ###### DEBUGDEBUGDEBUG
       
        
        if _tg_id in self._tg_filter:    #All TGs
            _dst_sub    = get_alias(_dst_sub, talkgroup_ids)
            if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
                if self._currentTG == self._no_tg:
                    _src_sub    = get_subscriber_info(_src_sub)
                    logger.info('Voice Transmission Start on TS {} and TG {} ({}) from {}'.format(_ts, _dst_sub, _tg_id, _src_sub))
                    self._sock.sendto('reply log2 {} {}'.format(_src_sub, _tg_id), (self._dmrgui, 34003))

                    self._currentTG = _tg_id
                    self._transmitStartTime = time()
                    self._start_seq = int_id(_data[20:22])
                    self._packet_count = 0
                else:
                    if self._currentTG != _tg_id:
                        if time() > self.lastPacketTimeout:
                            self._currentTG = self._no_tg    #looks like we never saw an EOT from the last stream
                            logger.warning('EOT timeout')
                        else:
                            logger.warning('Transmission in progress, will not decode stream on TG {}'.format(_tg_id))
            if self._currentTG == _tg_id:
                if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
                    _source_packets = ( int_id(_data[20:22]) - self._start_seq ) - 3 # the 3 is because  the start and end are not part of the voice but counted in the RTP
                    if self._packet_count > _source_packets:
                        self._packet_count = _source_packets
                    if _source_packets > 0:
                        _lost_percentage = 100.0 - ((self._packet_count / float(_source_packets)) * 100.0)
                    else:
                        _lost_percentage = 0.0
                    _duration = (time() - self._transmitStartTime)
                    logger.info('Voice Transmission End {:.2f} seconds loss rate: {:.2f}% ({}/{})'.format(_duration, _lost_percentage, _source_packets - self._packet_count, _source_packets))
                    self._sock.sendto("reply log" +
                                      strftime(" %m/%d/%y %H:%M:%S", localtime(self._transmitStartTime)) +
                                      ' {} {} "{}"'.format(get_subscriber_info(_src_sub), _ts, _dst_sub) +
                                      ' {:.2f}%'.format(_lost_percentage) +
                                      ' {:.2f}s'.format(_duration), (self._dmrgui, 34003))
                    self._currentTG = self._no_tg
                if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2, _ambe_frame3)
                    self._packet_count += 1
                if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                    self.outputFrames(_ambe_frames, _ambe_frame1, _ambe_frame2, _ambe_frame3)
                    self._packet_count += 1
                self.lastPacketTimeout = time() + 10
    
        else:
            if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
                _dst_sub    = get_alias(_dst_sub, talkgroup_ids)
                logger.warning('Ignored Voice Transmission Start on TS {} and TG {}'.format(_ts, _dst_sub))
Ejemplo n.º 39
0
    def dumpIPSCFrame(self, _frame):

        _packettype = int_id(
            _frame[0:1]
        )  # int8  GROUP_VOICE, PVT_VOICE, GROUP_DATA, PVT_DATA, CALL_MON_STATUS, CALL_MON_RPT, CALL_MON_NACK, XCMP_XNL, RPT_WAKE_UP, DE_REG_REQ
        _peerid = int_id(_frame[1:5])  # int32 peer who is sending us a packet
        _ipsc_seq = int_id(
            _frame[5:6])  # int8  looks like a sequence number for a packet
        _src_sub = int_id(_frame[6:9])  # int32 Id of source
        _dst_sub = int_id(_frame[9:12])  # int32 Id of destination
        _call_type = int_id(_frame[12:13])  # int8 Priority Voice/Data
        _call_ctrl_info = int_id(_frame[13:17])  # int32
        _call_info = int_id(
            _frame[17:18])  # int8  Bits 6 and 7 defined as TS and END

        # parse out the RTP values
        _rtp_byte_1 = int_id(_frame[18:19])  # Call Ctrl Src
        _rtp_byte_2 = int_id(_frame[19:20])  # Type
        _rtp_seq = int_id(_frame[20:22])  # Call Seq No
        _rtp_tmstmp = int_id(_frame[22:26])  # Timestamp
        _rtp_ssid = int_id(_frame[26:30])  # Sync Src Id

        _payload_type = _frame[
            30]  # int8  VOICE_HEAD, VOICE_TERM, SLOT1_VOICE, SLOT2_VOICE

        _ts = bool(_call_info & TS_CALL_MSK)
        _end = bool(_call_info & END_MSK)

        if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
            print('HEAD:', h(_frame))
        if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:

            _ipsc_rssi_threshold_and_parity = int_id(_frame[31])
            _ipsc_length_to_follow = int_id(_frame[32:34])
            _ipsc_rssi_status = int_id(_frame[34])
            _ipsc_slot_type_sync = int_id(_frame[35])
            _ipsc_data_size = int_id(_frame[36:38])
            _ipsc_data = _frame[38:38 + (_ipsc_length_to_follow * 2) - 4]
            _ipsc_full_lc_byte1 = int_id(_frame[38])
            _ipsc_full_lc_fid = int_id(_frame[39])
            _ipsc_voice_pdu_service_options = int_id(_frame[40])
            _ipsc_voice_pdu_dst = int_id(_frame[41:44])
            _ipsc_voice_pdu_src = int_id(_frame[44:47])

            print('{} {} {} {} {} {} {} {} {} {} {}'.format(
                _ipsc_rssi_threshold_and_parity, _ipsc_length_to_follow,
                _ipsc_rssi_status, _ipsc_slot_type_sync, _ipsc_data_size,
                h(_ipsc_data), _ipsc_full_lc_byte1, _ipsc_full_lc_fid,
                _ipsc_voice_pdu_service_options, _ipsc_voice_pdu_dst,
                _ipsc_voice_pdu_src))
            print('TERM:', h(_frame))
        if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
            _rtp_len = _frame[31:32]
            _ambe = _frame[33:52]
            print('SLOT1:', h(_frame))
        if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
            _rtp_len = _frame[31:32]
            _ambe = _frame[33:52]
            print('SLOT2:', h(_frame))
        print(
            "pt={:02X} pid={} seq={:02X} src={} dst={} ct={:02X} uk={} ci={} rsq={}"
            .format(_packettype, _peerid, _ipsc_seq, _src_sub, _dst_sub,
                    _call_type, _call_ctrl_info, _call_info, _rtp_seq))
Ejemplo n.º 40
0
 def call_mon_origin(self, _network, _data):
     logger.debug('(%s) Repeater Call Monitor Origin Packet Received: %s',_network, h(_data))