Esempio n. 1
0
    def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _slot,
                      _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])

        if _call_type == 'group':

            # Is this is a new call stream?
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                self.STATUS['RX_START'] = pkt_time
                self._logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_radio_id, peer_ids), int_id(_radio_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)

            for _target in self._CONFIG['SYSTEMS']:
                if _target != self._system:
                    systems[_target].send_system(_data)
                    self._logger.debug('(%s) Packet routed to system: %s',
                                       self._system, _target)

            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC
                ) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (
                    self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                self._logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_radio_id, peer_ids), int_id(_radio_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)

            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS'] = _rf_src
            self.STATUS[_slot]['RX_TYPE'] = _dtype_vseq
            self.STATUS[_slot]['RX_TGID'] = _dst_id
            self.STATUS[_slot]['RX_TIME'] = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
Esempio n. 2
0
    def begin_call(self, _slot, _src_id, _dst_id, _repeater_id, _cc, _seq,
                   _stream_id):
        subscriber_ids, talkgroup_ids, peer_ids = self._parent.get_globals()
        _src_alias = get_alias(_src_id, subscriber_ids)
        metadata = _src_id[0:3] + _repeater_id[0:4] + _dst_id[
            0:3] + struct.pack("b", _slot) + struct.pack("b", _cc)
        self.send_tlv(TAG_BEGIN_TX, metadata)  # start transmission
        self._sock.sendto(
            'reply log2 {} {}'.format(_src_alias, int_id(_dst_id)),
            (self._dmrgui, 34003))
        self._logger.info(
            'Voice Transmission Start on TS {} and TG {} ({}) from {}'.format(
                _slot, get_alias(_dst_id, talkgroup_ids), int_id(_dst_id),
                _src_alias))

        _tx_slot = self.tx[_slot]
        _tx_slot.slot = _slot
        _tx_slot.rf_src = _src_id
        _tx_slot.repeater_id = _repeater_id
        _tx_slot.dst_id = _dst_id
        _tx_slot.cc = _cc
        _tx_slot.stream_id = _stream_id

        _tx_slot.start_time = time()
        _tx_slot.frame_count = 0
        _tx_slot.lostFrame = 0
        _tx_slot.lastSeq = _seq
Esempio n. 3
0
 def group_voice(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
     if (_ts not in self.ACTIVE_CALLS) or _end:
         _time       = time.strftime('%m/%d/%y %H:%M:%S')
         _dst_sub    = get_alias(_dst_sub, talkgroup_ids)
         _peerid     = get_alias(_peerid, peer_ids)
         _src_sub    = get_alias(_src_sub, subscriber_ids)
         if not _end:    self.ACTIVE_CALLS.append(_ts)
         if _end:        self.ACTIVE_CALLS.remove(_ts)
         if _end:    _end = 'END'
         else:       _end = 'START'
     
         print('{} ({}) Call {} Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t{}' .format(_time, self._system, _end, _peerid, _src_sub, _dst_sub, _ts))
Esempio n. 4
0
    def group_voice(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
        if (_ts not in self.ACTIVE_CALLS) or _end:
            _time = time.strftime('%m/%d/%y %H:%M:%S')
            _dst_sub = get_alias(_dst_sub, talkgroup_ids)
            _peerid = get_alias(_peerid, peer_ids)
            _src_sub = get_alias(_src_sub, subscriber_ids)
            if not _end: self.ACTIVE_CALLS.append(_ts)
            if _end: self.ACTIVE_CALLS.remove(_ts)
            if _end: _end = 'END'
            else: _end = 'START'

            print(
                '{} ({}) Call {} Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t{}'
                .format(_time, self._system, _end, _peerid, _src_sub, _dst_sub,
                        _ts))
Esempio n. 5
0
    def call_mon_status(self, _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_alias(_source, peer_ids))
        _ipsc_src = str(int_id(_ipsc_src)) + ', ' + str(
            get_alias(_ipsc_src, peer_ids))
        _rf_src = str(int_id(_rf_src)) + ', ' + str(
            get_alias(_rf_src, subscriber_ids))

        if _type == '\x4F' or '\x51':
            _rf_tgt = 'TGID: ' + str(int_id(_rf_tgt)) + ', ' + str(
                get_alias(_rf_tgt, talkgroup_ids))
        else:
            _rf_tgt = 'SID: ' + str(int_id(_rf_tgt)) + ', ' + str(
                get_alias(_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:        ', self._system)
        print('IPSC Source: ', _ipsc_src)
        print('Timeslot:    ', TS[_ts])
        try:
            print('Status:      ', STATUS[_status])
        except KeyError:
            print('Status (unknown): ', ahex(_status))
        try:
            print('Type:        ', TYPE[_type])
        except KeyError:
            print('Type (unknown): ', ahex(_type))
        print('Source Sub:  ', _rf_src)
        print('Target Sub:  ', _rf_tgt)
        print()
Esempio n. 6
0
def alias_string(_id, _dict):
    alias = get_alias(_id, _dict, 'CALLSIGN', 'CITY', 'STATE')
    if type(alias) == list:
        for x, item in enumerate(alias):
            if item == None:
                alias.pop(x)
        return ', '.join(alias)
    else:
        return alias
Esempio n. 7
0
def alias_call(_id, _dict):
    alias = get_alias(_id, _dict, 'CALLSIGN')
    if type(alias) == list:
        for x,item in enumerate(alias):
            if item == None:
                alias.pop(x)
        return ', '.join(alias)
    else:
        return str(alias)
Esempio n. 8
0
    def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _slot,
                      _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])

        if _call_type == 'group':

            # Is this is a new call stream?
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                self.STATUS['RX_START'] = pkt_time
                self._logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', \
                                  self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_radio_id, peer_ids), int_id(_radio_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)

            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC
                ) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (
                    self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                self._logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                                  self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_radio_id, peer_ids), int_id(_radio_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
                self.CALL_DATA.append(_data)
                sleep(2)
                logger.info(
                    '(%s) Playing back transmission from subscriber: %s',
                    self._system, int_id(_rf_src))
                for i in self.CALL_DATA:
                    self.send_system(i)
                    sleep(0.06)
                self.CALL_DATA = []

            else:
                if not self.CALL_DATA:
                    logger.info(
                        '(%s) Receiving transmission to be played back from subscriber: %s',
                        self._system, int_id(_rf_src))
                self.CALL_DATA.append(_data)

            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS'] = _rf_src
            self.STATUS[_slot]['RX_TYPE'] = _dtype_vseq
            self.STATUS[_slot]['RX_TGID'] = _dst_id
            self.STATUS[_slot]['RX_TIME'] = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
Esempio n. 9
0
 def end_call(self, _tx_slot):
     subscriber_ids, talkgroup_ids, peer_ids = self._parent.get_globals()
     self.send_tlv(TAG_END_TX, struct.pack("b",_tx_slot.slot))   # end transmission
     call_duration = time() - _tx_slot.start_time
     _lost_percentage = ((_tx_slot.lostFrame / float(_tx_slot.frame_count)) * 100.0) if _tx_slot.frame_count > 0 else 0.0
     self._sock.sendto("reply log" +
                       strftime(" %m/%d/%y %H:%M:%S", localtime(_tx_slot.start_time)) +
                       ' {} {} "{}"'.format(get_alias(_tx_slot.rf_src, subscriber_ids), _tx_slot.slot, get_alias(_tx_slot.dst_id, talkgroup_ids)) +
                       ' {:.2f}%'.format(_lost_percentage) +
                       ' {:.2f}s'.format(call_duration), (self._dmrgui, 34003))
     self._logger.info('Voice Transmission End {:.2f} seconds loss rate: {:.2f}% ({}/{})'.format(call_duration, _lost_percentage, _tx_slot.frame_count - _tx_slot.lostFrame, _tx_slot.frame_count))
Esempio n. 10
0
 def call_mon_status(self, _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_alias(_source, peer_ids))
     _ipsc_src = str(int_id(_ipsc_src)) + ', ' + str(get_alias(_ipsc_src, peer_ids))
     _rf_src = str(int_id(_rf_src)) + ', ' + str(get_alias(_rf_src, subscriber_ids))
     
     if _type == '\x4F' or '\x51':
         _rf_tgt = 'TGID: ' + str(int_id(_rf_tgt)) + ', ' + str(get_alias(_rf_tgt, talkgroup_ids))
     else:
         _rf_tgt = 'SID: ' + str(int_id(_rf_tgt)) + ', ' + str(get_alias(_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:        ', self._system)
     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()
Esempio n. 11
0
    def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])
        if _call_type == 'group':

            # Is this is a new call stream?
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                self.STATUS['RX_START'] = pkt_time
                logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', \
                                  self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)


            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                                  self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
                self.CALL_DATA.append(_data)
                sleep(2)
                logger.info('(%s) Playing back transmission from subscriber: %s', self._system, int_id(_rf_src))
                for i in self.CALL_DATA:
                    self.send_system(i)
                    sleep(0.06)
                self.CALL_DATA = []

            else:
                if not self.CALL_DATA:
                    logger.info('(%s) Receiving transmission to be played back from subscriber: %s', self._system, int_id(_rf_src))
                self.CALL_DATA.append(_data)


            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS']       = _rf_src
            self.STATUS[_slot]['RX_TYPE']      = _dtype_vseq
            self.STATUS[_slot]['RX_TGID']      = _dst_id
            self.STATUS[_slot]['RX_TIME']      = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
Esempio n. 12
0
 def call_mon_nack(self, _data):
     if not nack:
         return
     _source = _data[1:5]
     _nack =   _data[5]
     
     _source = get_alias(_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()
Esempio n. 13
0
    def call_mon_nack(self, _data):
        if not nack:
            return
        _source = _data[1:5]
        _nack = _data[5]

        _source = get_alias(_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): ', ahex(_nack))
        print()
Esempio n. 14
0
 def call_mon_rpt(self, _data):
     if not rpt:
         return
     _source    = _data[1:5]
     _ts1_state = _data[5]
     _ts2_state = _data[6]
     
     _source = str(int_id(_source)) + ', ' + str(get_alias(_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()
Esempio n. 15
0
    def call_mon_rpt(self, _data):
        if not rpt:
            return
        _source = _data[1:5]
        _ts1_state = _data[5]
        _ts2_state = _data[6]

        _source = str(int_id(_source)) + ', ' + str(
            get_alias(_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): ', ahex(_ts1_state))
        try:
            print('TS2 State:    ', REPEAT[_ts2_state])
        except KeyError:
            print('TS2 State (unknown): ', ahex(_ts2_state))
        print()
Esempio n. 16
0
 def group_data(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):    
     _dst_sub    = get_alias(_dst_sub, talkgroup_ids)
     _peerid     = get_alias(_peerid, peer_ids)
     _src_sub    = get_alias(_src_sub, subscriber_ids)
     print('({}) Group Data Packet Received From: {}' .format(self._system, _src_sub))
Esempio n. 17
0
    def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])

        if _call_type == 'group':
            
            # Check for ACL match, and return if the subscriber is not allowed
            if allow_sub(_rf_src) == False:
                self._logger.warning('(%s) Group Voice Packet ***REJECTED BY ACL*** From: %s, HBP Peer %s, Destination TGID %s', self._system, int_id(_rf_src), int_id(_peer_id), int_id(_dst_id))
                return
            
            # Is this a new call stream?   
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                if (self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM) and (pkt_time < (self.STATUS[_slot]['RX_TIME'] + hb_const.STREAM_TO)) and (_rf_src != self.STATUS[_slot]['RX_RFS']):
                    self._logger.warning('(%s) Packet received with STREAM ID: %s <FROM> SUB: %s PEER: %s <TO> TGID %s, SLOT %s collided with existing call', self._system, int_id(_stream_id), int_id(_rf_src), int_id(_peer_id), int_id(_dst_id), _slot)
                    return
                
                # This is a new call stream
                self.STATUS['RX_START'] = pkt_time
                self._logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)
                
                # If we can, use the LC from the voice header as to keep all options intact
                if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                    decoded = decode.voice_head_term(dmrpkt)
                    self.STATUS[_slot]['RX_LC'] = decoded['LC']
                
                # If we don't have a voice header then don't wait to decode it from the Embedded LC
                # just make a new one from the HBP header. This is good enough, and it saves lots of time
                else:
                    self.STATUS[_slot]['RX_LC'] = const.LC_OPT + _dst_id + _rf_src


            for rule in RULES[self._system]['GROUP_VOICE']:
                _target = rule['DST_NET']
                _target_status = systems[_target].STATUS
                
                if (rule['SRC_GROUP'] == _dst_id and rule['SRC_TS'] == _slot and rule['ACTIVE'] == True):
                    
                    # BEGIN CONTENTION HANDLING
                    #
                    # The rules for each of the 4 "ifs" below are listed here for readability. The Frame To Send is:
                    #   From a different group than last RX from this HBSystem, but it has been less than Group Hangtime
                    #   From a different group than last TX to this HBSystem, but it has been less than Group Hangtime
                    #   From the same group as the last RX from this HBSystem, but from a different subscriber, and it has been less than stream timeout
                    #   From the same group as the last TX to this HBSystem, but from a different subscriber, and it has been less than stream timeout
                    # The "continue" at the end of each means the next iteration of the for loop that tests for matching rules
                    #
                    if ((rule['DST_GROUP'] != _target_status[rule['DST_TS']]['RX_TGID']) and ((pkt_time - _target_status[rule['DST_TS']]['RX_TIME']) < RULES[_target]['GROUP_HANGTIME'])):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info('(%s) Call not routed to TGID%s, target active or in group hangtime: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(rule['DST_GROUP']), _target, rule['DST_TS'], int_id(_target_status[rule['DST_TS']]['RX_TGID']))
                        continue    
                    if ((rule['DST_GROUP'] != _target_status[rule['DST_TS']]['TX_TGID']) and ((pkt_time - _target_status[rule['DST_TS']]['TX_TIME']) < RULES[_target]['GROUP_HANGTIME'])):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info('(%s) Call not routed to TGID%s, target in group hangtime: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(rule['DST_GROUP']), _target, rule['DST_TS'], int_id(_target_status[rule['DST_TS']]['TX_TGID']))
                        continue
                    if (rule['DST_GROUP'] == _target_status[rule['DST_TS']]['RX_TGID']) and ((pkt_time - _target_status[rule['DST_TS']]['RX_TIME']) < hb_const.STREAM_TO):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info('(%s) Call not routed to TGID%s, matching call already active on target: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(rule['DST_GROUP']), _target, rule['DST_TS'], int_id(_target_status[rule['DST_TS']]['RX_TGID']))
                        continue
                    if (rule['DST_GROUP'] == _target_status[rule['DST_TS']]['TX_TGID']) and (_rf_src != _target_status[rule['DST_TS']]['TX_RFS']) and ((pkt_time - _target_status[rule['DST_TS']]['TX_TIME']) < hb_const.STREAM_TO):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info('(%s) Call not routed for subscriber %s, call route in progress on target: HBSystem: %s, TS: %s, TGID: %s, SUB: %s', self._system, int_id(_rf_src), _target, rule['DST_TS'], int_id(_target_status[rule['DST_TS']]['TX_TGID']), _target_status[rule['DST_TS']]['TX_RFS'])
                        continue

                    # Set values for the contention handler to test next time there is a frame to forward
                    _target_status[rule['DST_TS']]['TX_TIME'] = pkt_time
                    
                    if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']) or (_target_status[rule['DST_TS']]['TX_RFS'] != _rf_src) or (_target_status[rule['DST_TS']]['TX_TGID'] != rule['DST_GROUP']):       
                        # Record the DST TGID and Stream ID
                        _target_status[rule['DST_TS']]['TX_TGID'] = rule['DST_GROUP']
                        _target_status[rule['DST_TS']]['TX_STREAM_ID'] = _stream_id
                        _target_status[rule['DST_TS']]['TX_RFS'] = _rf_src
                        # Generate LCs (full and EMB) for the TX stream
                        # if _dst_id != rule['DST_GROUP']:
                        dst_lc = self.STATUS[_slot]['RX_LC'][0:3] + rule['DST_GROUP'] + _rf_src
                        _target_status[rule['DST_TS']]['TX_H_LC'] = bptc.encode_header_lc(dst_lc)
                        _target_status[rule['DST_TS']]['TX_T_LC'] = bptc.encode_terminator_lc(dst_lc)
                        _target_status[rule['DST_TS']]['TX_EMB_LC'] = bptc.encode_emblc(dst_lc)
                        self._logger.debug('(%s) Packet DST TGID (%s) does not match SRC TGID(%s) - Generating FULL and EMB LCs', self._system, int_id(rule['DST_GROUP']), int_id(_dst_id))
                        self._logger.info('(%s) Call routed to: System: %s TS: %s, TGID: %s', self._system, _target, rule['DST_TS'], int_id(rule['DST_GROUP']))
                    
                    # Handle any necessary re-writes for the destination
                    if rule['SRC_TS'] != rule['DST_TS']:
                        _tmp_bits = _bits ^ 1 << 7
                    else:
                        _tmp_bits = _bits
                    
                    # Assemble transmit HBP packet header
                    _tmp_data = _data[:8] + rule['DST_GROUP'] + _data[11:15] + chr(_tmp_bits) + _data[16:20]
                    
                    # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
                    # MUST RE-WRITE DESTINATION TGID IF DIFFERENT
                    # if _dst_id != rule['DST_GROUP']:
                    dmrbits = bitarray(endian='big')
                    dmrbits.frombytes(dmrpkt)
                    # Create a voice header packet (FULL LC)
                    if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                        dmrbits = _target_status[rule['DST_TS']]['TX_H_LC'][0:98] + dmrbits[98:166] + _target_status[rule['DST_TS']]['TX_H_LC'][98:197]
                    # Create a voice terminator packet (FULL LC)
                    elif _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VTERM:
                        dmrbits = _target_status[rule['DST_TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[rule['DST_TS']]['TX_T_LC'][98:197]
                    # Create a Burst B-E packet (Embedded LC)
                    elif _dtype_vseq in [1,2,3,4]:
                        dmrbits = dmrbits[0:116] + _target_status[rule['DST_TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264]
                    dmrpkt = dmrbits.tobytes()
                    _tmp_data = _tmp_data + dmrpkt + _data[53:55]
                    
                    # Transmit the packet to the destination system
                    systems[_target].send_system(_tmp_data)
                    self._logger.debug('(%s) Packet routed by rule: %s to %s system: %s', self._system, rule['NAME'], self._CONFIG['SYSTEMS'][_target]['MODE'], _target)
            
            
            
            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                self._logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
                
                #
                # Begin in-band signalling for call end. This has nothign to do with routing traffic directly.
                #
                
                # Iterate the rules dictionary
                for rule in RULES[self._system]['GROUP_VOICE']:
                    _target = rule['DST_NET']
            
                    # TGID matches a rule source, reset its timer
                    if _slot == rule['SRC_TS'] and _dst_id == rule['SRC_GROUP'] and ((rule['TO_TYPE'] == 'ON' and (rule['ACTIVE'] == True)) or (rule['TO_TYPE'] == 'OFF' and rule['ACTIVE'] == False)):
                        rule['TIMER'] = pkt_time + rule['TIMEOUT']
                        self._logger.info('(%s) Source group transmission match for rule \"%s\". Reset timeout to %s', self._system, rule['NAME'], rule['TIMER'])
                
                        # Scan for reciprocal rules and reset their timers as well.
                        for target_rule in RULES[_target]['GROUP_VOICE']:
                            if target_rule['NAME'] == rule['NAME']:
                                target_rule['TIMER'] = pkt_time + target_rule['TIMEOUT']
                                self._logger.info('(%s) Reciprocal group transmission match for rule \"%s\" on IPSC \"%s\". Reset timeout to %s', self._system, target_rule['NAME'], _target, rule['TIMER'])
            
                    # TGID matches an ACTIVATION trigger
                    if _dst_id in rule['ON']:
                        # Set the matching rule as ACTIVE
                        rule['ACTIVE'] = True
                        rule['TIMER'] = pkt_time + rule['TIMEOUT']
                        self._logger.info('(%s) Primary routing Rule \"%s\" changed to state: %s', self._system, rule['NAME'], rule['ACTIVE'])
                
                        # Set reciprocal rules for other IPSCs as ACTIVE
                        for target_rule in RULES[_target]['GROUP_VOICE']:
                            if target_rule['NAME'] == rule['NAME']:
                                target_rule['ACTIVE'] = True
                                target_rule['TIMER'] = pkt_time + target_rule['TIMEOUT']
                                self._logger.info('(%s) Reciprocal routing Rule \"%s\" in IPSC \"%s\" changed to state: %s', self._system, target_rule['NAME'], _target, rule['ACTIVE'])
                        
                    # TGID matches an DE-ACTIVATION trigger
                    if _dst_id in rule['OFF']:
                        # Set the matching rule as ACTIVE
                        rule['ACTIVE'] = False
                        self._logger.info('(%s) Routing Rule \"%s\" changed to state: %s', self._system, rule['NAME'], rule['ACTIVE'])
                
                        # Set reciprocal rules for other IPSCs as ACTIVE
                        _target = rule['DST_NET']
                        for target_rule in RULES[_target]['GROUP_VOICE']:
                            if target_rule['NAME'] == rule['NAME']:
                                target_rule['ACTIVE'] = False
                                self._logger.info('(%s) Reciprocal routing Rule \"%s\" in IPSC \"%s\" changed to state: %s', self._system, target_rule['NAME'], _target, rule['ACTIVE'])
            #                    
            # END IN-BAND SIGNALLING
            #
                
                
            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS']       = _rf_src
            self.STATUS[_slot]['RX_TYPE']      = _dtype_vseq
            self.STATUS[_slot]['RX_TGID']      = _dst_id
            self.STATUS[_slot]['RX_TIME']      = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
Esempio n. 18
0
 def private_data(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):    
     _dst_sub    = get_alias(_dst_sub, subscriber_ids)
     _peerid     = get_alias(_peerid, peer_ids)
     _src_sub    = get_alias(_src_sub, subscriber_ids)
     print('({}) Private Data Packet Received From: {} To: {}' .format(self._system, _src_sub, _dst_sub))
Esempio n. 19
0
    def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot,
                      _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])

        if _call_type == 'group':

            # Check for ACL match, and return if the subscriber is not allowed
            if allow_sub(_rf_src) == False:
                self._logger.warning(
                    '(%s) Group Voice Packet ***REJECTED BY ACL*** From: %s, HBP Peer %s, Destination TGID %s',
                    self._system, int_id(_rf_src), int_id(_peer_id),
                    int_id(_dst_id))
                return

            # Is this a new call stream?
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                if (self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM
                    ) and (pkt_time <
                           (self.STATUS[_slot]['RX_TIME'] + hb_const.STREAM_TO)
                           ) and (_rf_src != self.STATUS[_slot]['RX_RFS']):
                    self._logger.warning(
                        '(%s) Packet received with STREAM ID: %s <FROM> SUB: %s PEER: %s <TO> TGID %s, SLOT %s collided with existing call',
                        self._system, int_id(_stream_id), int_id(_rf_src),
                        int_id(_peer_id), int_id(_dst_id), _slot)
                    return

                # This is a new call stream
                self.STATUS['RX_START'] = pkt_time
                self._logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)

                # If we can, use the LC from the voice header as to keep all options intact
                if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                    decoded = decode.voice_head_term(dmrpkt)
                    self.STATUS[_slot]['RX_LC'] = decoded['LC']

                # If we don't have a voice header then don't wait to decode it from the Embedded LC
                # just make a new one from the HBP header. This is good enough, and it saves lots of time
                else:
                    self.STATUS[_slot][
                        'RX_LC'] = const.LC_OPT + _dst_id + _rf_src

            for rule in RULES[self._system]['GROUP_VOICE']:
                _target = rule['DST_NET']
                _target_status = systems[_target].STATUS

                if (rule['SRC_GROUP'] == _dst_id and rule['SRC_TS'] == _slot
                        and rule['ACTIVE'] == True):

                    # BEGIN CONTENTION HANDLING
                    #
                    # The rules for each of the 4 "ifs" below are listed here for readability. The Frame To Send is:
                    #   From a different group than last RX from this HBSystem, but it has been less than Group Hangtime
                    #   From a different group than last TX to this HBSystem, but it has been less than Group Hangtime
                    #   From the same group as the last RX from this HBSystem, but from a different subscriber, and it has been less than stream timeout
                    #   From the same group as the last TX to this HBSystem, but from a different subscriber, and it has been less than stream timeout
                    # The "continue" at the end of each means the next iteration of the for loop that tests for matching rules
                    #
                    if ((rule['DST_GROUP'] !=
                         _target_status[rule['DST_TS']]['RX_TGID']) and
                        ((pkt_time - _target_status[rule['DST_TS']]['RX_TIME'])
                         < RULES[_target]['GROUP_HANGTIME'])):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info(
                                '(%s) Call not routed to TGID%s, target active or in group hangtime: HBSystem: %s, TS: %s, TGID: %s',
                                self._system, int_id(rule['DST_GROUP']),
                                _target, rule['DST_TS'],
                                int_id(
                                    _target_status[rule['DST_TS']]['RX_TGID']))
                        continue
                    if ((rule['DST_GROUP'] !=
                         _target_status[rule['DST_TS']]['TX_TGID']) and
                        ((pkt_time - _target_status[rule['DST_TS']]['TX_TIME'])
                         < RULES[_target]['GROUP_HANGTIME'])):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info(
                                '(%s) Call not routed to TGID%s, target in group hangtime: HBSystem: %s, TS: %s, TGID: %s',
                                self._system, int_id(rule['DST_GROUP']),
                                _target, rule['DST_TS'],
                                int_id(
                                    _target_status[rule['DST_TS']]['TX_TGID']))
                        continue
                    if (rule['DST_GROUP']
                            == _target_status[rule['DST_TS']]['RX_TGID']) and (
                                (pkt_time -
                                 _target_status[rule['DST_TS']]['RX_TIME']) <
                                hb_const.STREAM_TO):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info(
                                '(%s) Call not routed to TGID%s, matching call already active on target: HBSystem: %s, TS: %s, TGID: %s',
                                self._system, int_id(rule['DST_GROUP']),
                                _target, rule['DST_TS'],
                                int_id(
                                    _target_status[rule['DST_TS']]['RX_TGID']))
                        continue
                    if (rule['DST_GROUP']
                            == _target_status[rule['DST_TS']]['TX_TGID']) and (
                                _rf_src !=
                                _target_status[rule['DST_TS']]['TX_RFS']) and (
                                    (pkt_time -
                                     _target_status[rule['DST_TS']]['TX_TIME'])
                                    < hb_const.STREAM_TO):
                        if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                            self._logger.info(
                                '(%s) Call not routed for subscriber %s, call route in progress on target: HBSystem: %s, TS: %s, TGID: %s, SUB: %s',
                                self._system, int_id(_rf_src), _target,
                                rule['DST_TS'],
                                int_id(
                                    _target_status[rule['DST_TS']]['TX_TGID']),
                                _target_status[rule['DST_TS']]['TX_RFS'])
                        continue

                    # Set values for the contention handler to test next time there is a frame to forward
                    _target_status[rule['DST_TS']]['TX_TIME'] = pkt_time

                    if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']) or (
                            _target_status[rule['DST_TS']]['TX_RFS'] != _rf_src
                    ) or (_target_status[rule['DST_TS']]['TX_TGID'] !=
                          rule['DST_GROUP']):
                        # Record the DST TGID and Stream ID
                        _target_status[
                            rule['DST_TS']]['TX_TGID'] = rule['DST_GROUP']
                        _target_status[
                            rule['DST_TS']]['TX_STREAM_ID'] = _stream_id
                        _target_status[rule['DST_TS']]['TX_RFS'] = _rf_src
                        # Generate LCs (full and EMB) for the TX stream
                        # if _dst_id != rule['DST_GROUP']:
                        dst_lc = self.STATUS[_slot]['RX_LC'][0:3] + rule[
                            'DST_GROUP'] + _rf_src
                        _target_status[rule['DST_TS']][
                            'TX_H_LC'] = bptc.encode_header_lc(dst_lc)
                        _target_status[rule['DST_TS']][
                            'TX_T_LC'] = bptc.encode_terminator_lc(dst_lc)
                        _target_status[rule['DST_TS']][
                            'TX_EMB_LC'] = bptc.encode_emblc(dst_lc)
                        self._logger.debug(
                            '(%s) Packet DST TGID (%s) does not match SRC TGID(%s) - Generating FULL and EMB LCs',
                            self._system, int_id(rule['DST_GROUP']),
                            int_id(_dst_id))
                        self._logger.info(
                            '(%s) Call routed to: System: %s TS: %s, TGID: %s',
                            self._system, _target, rule['DST_TS'],
                            int_id(rule['DST_GROUP']))

                    # Handle any necessary re-writes for the destination
                    if rule['SRC_TS'] != rule['DST_TS']:
                        _tmp_bits = _bits ^ 1 << 7
                    else:
                        _tmp_bits = _bits

                    # Assemble transmit HBP packet header
                    _tmp_data = _data[:8] + rule['DST_GROUP'] + _data[
                        11:15] + chr(_tmp_bits) + _data[16:20]

                    # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
                    # MUST RE-WRITE DESTINATION TGID IF DIFFERENT
                    # if _dst_id != rule['DST_GROUP']:
                    dmrbits = bitarray(endian='big')
                    dmrbits.frombytes(dmrpkt)
                    # Create a voice header packet (FULL LC)
                    if _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VHEAD:
                        dmrbits = _target_status[rule['DST_TS']]['TX_H_LC'][
                            0:98] + dmrbits[98:166] + _target_status[
                                rule['DST_TS']]['TX_H_LC'][98:197]
                    # Create a voice terminator packet (FULL LC)
                    elif _frame_type == hb_const.HBPF_DATA_SYNC and _dtype_vseq == hb_const.HBPF_SLT_VTERM:
                        dmrbits = _target_status[rule['DST_TS']]['TX_T_LC'][
                            0:98] + dmrbits[98:166] + _target_status[
                                rule['DST_TS']]['TX_T_LC'][98:197]
                    # Create a Burst B-E packet (Embedded LC)
                    elif _dtype_vseq in [1, 2, 3, 4]:
                        dmrbits = dmrbits[0:116] + _target_status[
                            rule['DST_TS']]['TX_EMB_LC'][
                                _dtype_vseq] + dmrbits[148:264]
                    dmrpkt = dmrbits.tobytes()
                    _tmp_data = _tmp_data + dmrpkt + _data[53:55]

                    # Transmit the packet to the destination system
                    systems[_target].send_system(_tmp_data)
                    self._logger.debug(
                        '(%s) Packet routed by rule: %s to %s system: %s',
                        self._system, rule['NAME'],
                        self._CONFIG['SYSTEMS'][_target]['MODE'], _target)

            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC
                ) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (
                    self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                self._logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)

                #
                # Begin in-band signalling for call end. This has nothign to do with routing traffic directly.
                #

                # Iterate the rules dictionary
                for rule in RULES[self._system]['GROUP_VOICE']:
                    _target = rule['DST_NET']

                    # TGID matches a rule source, reset its timer
                    if _slot == rule['SRC_TS'] and _dst_id == rule[
                            'SRC_GROUP'] and ((rule['TO_TYPE'] == 'ON' and
                                               (rule['ACTIVE'] == True)) or
                                              (rule['TO_TYPE'] == 'OFF'
                                               and rule['ACTIVE'] == False)):
                        rule['TIMER'] = pkt_time + rule['TIMEOUT']
                        self._logger.info(
                            '(%s) Source group transmission match for rule \"%s\". Reset timeout to %s',
                            self._system, rule['NAME'], rule['TIMER'])

                        # Scan for reciprocal rules and reset their timers as well.
                        for target_rule in RULES[_target]['GROUP_VOICE']:
                            if target_rule['NAME'] == rule['NAME']:
                                target_rule['TIMER'] = pkt_time + target_rule[
                                    'TIMEOUT']
                                self._logger.info(
                                    '(%s) Reciprocal group transmission match for rule \"%s\" on IPSC \"%s\". Reset timeout to %s',
                                    self._system, target_rule['NAME'], _target,
                                    rule['TIMER'])

                    # TGID matches an ACTIVATION trigger
                    if _dst_id in rule['ON']:
                        # Set the matching rule as ACTIVE
                        rule['ACTIVE'] = True
                        rule['TIMER'] = pkt_time + rule['TIMEOUT']
                        self._logger.info(
                            '(%s) Primary routing Rule \"%s\" changed to state: %s',
                            self._system, rule['NAME'], rule['ACTIVE'])

                        # Set reciprocal rules for other IPSCs as ACTIVE
                        for target_rule in RULES[_target]['GROUP_VOICE']:
                            if target_rule['NAME'] == rule['NAME']:
                                target_rule['ACTIVE'] = True
                                target_rule['TIMER'] = pkt_time + target_rule[
                                    'TIMEOUT']
                                self._logger.info(
                                    '(%s) Reciprocal routing Rule \"%s\" in IPSC \"%s\" changed to state: %s',
                                    self._system, target_rule['NAME'], _target,
                                    rule['ACTIVE'])

                    # TGID matches an DE-ACTIVATION trigger
                    if _dst_id in rule['OFF']:
                        # Set the matching rule as ACTIVE
                        rule['ACTIVE'] = False
                        self._logger.info(
                            '(%s) Routing Rule \"%s\" changed to state: %s',
                            self._system, rule['NAME'], rule['ACTIVE'])

                        # Set reciprocal rules for other IPSCs as ACTIVE
                        _target = rule['DST_NET']
                        for target_rule in RULES[_target]['GROUP_VOICE']:
                            if target_rule['NAME'] == rule['NAME']:
                                target_rule['ACTIVE'] = False
                                self._logger.info(
                                    '(%s) Reciprocal routing Rule \"%s\" in IPSC \"%s\" changed to state: %s',
                                    self._system, target_rule['NAME'], _target,
                                    rule['ACTIVE'])
            #
            # END IN-BAND SIGNALLING
            #

            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS'] = _rf_src
            self.STATUS[_slot]['RX_TYPE'] = _dtype_vseq
            self.STATUS[_slot]['RX_TGID'] = _dst_id
            self.STATUS[_slot]['RX_TIME'] = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
Esempio n. 20
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))
Esempio n. 21
0
                        if ord(l) > 1:
                            _slot = int_id(v[10:11])
                            _rx_slot = self.rx[_slot]
                            _rx_slot.slot = _slot
                            _rx_slot.rf_src = hex_str_3(int_id(v[0:3]))
                            _rx_slot.repeater_id = self._parent.get_repeater_id(
                                hex_str_4(int_id(v[3:7])))
                            _rx_slot.dst_id = hex_str_3(int_id(v[7:10]))
                            _rx_slot.cc = int_id(v[11:12])

                        if t == TAG_BEGIN_TX:
                            _rx_slot.stream_id = hex_str_4(
                                randint(0, 0xFFFFFFFF)
                            )  # Every stream has a unique ID
                            self._logger.info('(%s) Begin AMBE encode STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', \
                                          self._system, int_id(_rx_slot.stream_id), get_alias(_rx_slot.rf_src, subscriber_ids), int_id(_rx_slot.rf_src), get_alias(_rx_slot.repeater_id, peer_ids), int_id(_rx_slot.repeater_id), get_alias(_rx_slot.dst_id, talkgroup_ids), int_id(_rx_slot.dst_id), _slot)
                            self.send_voice_header(_rx_slot)
                        else:
                            self._logger.info('(%s) Set DMR Info SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', \
                                          self._system, get_alias(_rx_slot.rf_src, subscriber_ids), int_id(_rx_slot.rf_src), get_alias(_rx_slot.repeater_id, peer_ids), int_id(_rx_slot.repeater_id), get_alias(_rx_slot.dst_id, talkgroup_ids), int_id(_rx_slot.dst_id), _slot)
                    elif (
                        (t == TAG_AMBE) or
                        (t == TAG_AMBE_72)):  # generic AMBE or specific AMBE72
                        _slot = int_id(v[0])
                        _rx_slot = self.rx[_slot]
                        if _rx_slot.frame_count > 0:
                            self.send_voice72(_rx_slot, v[1:])
                    elif (t == TAG_AMBE_49):  # AMBE49
                        _slot = int_id(v[0])
                        _rx_slot = self.rx[_slot]
                        if _rx_slot.frame_count > 0:
Esempio n. 22
0
def alias_tgid(_id, _dict):
    alias = get_alias(_id, _dict, 'NAME')
    if type(alias) == list:
        return str(alias[0])
    else:
        return str(alias)
Esempio n. 23
0
def alias_call(_id, _dict):
    alias = get_alias(_id, _dict, 'CALLSIGN')
    if type(alias) == list:
        return str(alias[0])
    else:
        return str(alias)
Esempio n. 24
0
 def repeater_wake_up(self, _data):
     _source = _data[1:5]
     _source_name = get_alias(_source, peer_ids)
     print('({}) Repeater Wake-Up Packet Received: {} ({})' .format(self._system, _source_name, int_id(_source)))
Esempio n. 25
0
    def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot,
                      _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])

        if _call_type == 'group':

            # Check for GLOBAL Subscriber ID ACL Match
            if acl_check(_rf_src, ACL['SID']['GLOBAL'][_slot]) == False:
                if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                    self._logger.warning(
                        '(%s) Group Voice Call ***REJECTED BY INGRESS GLOBAL ACL***    SID: %s SLOT: %s HBP Peer %s',
                        self._system, int_id(_rf_src), _slot, int_id(_peer_id))
                    self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
                return
            # Check for SYSTEM Subscriber ID ACL Match
            if acl_check(_rf_src, ACL['SID'][self._system][_slot]) == False:
                if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                    self._logger.warning(
                        '(%s) Group Voice Call ***REJECTED BY INGRESS SYSTEM ACL***    SID: %s SLOT: %s HBP Peer %s',
                        self._system, int_id(_rf_src), _slot, int_id(_peer_id))
                    self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
                return

            # Check for GLOBAL Talkgroup ID ACL Match
            if acl_check(_dst_id, ACL['TGID']['GLOBAL'][_slot]) == False:
                if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                    self._logger.warning(
                        '(%s) Group Voice Call ***REJECTED BY INGRESS GLOBAL ACL***    TGID: %s SLOT: %s HBP Peer %s',
                        self._system, int_id(_dst_id), _slot, int_id(_peer_id))
                    self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
                return
            # Check for SYSTEM Talkgroup ID ID ACL Match
            if acl_check(_dst_id, ACL['TGID'][self._system][_slot]) == False:
                if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                    self._logger.warning(
                        '(%s) Group Voice Call ***REJECTED BY INGRESS SYSTEM ACL***    TGID: %s SLOT: %s HBP Peer %s',
                        self._system, int_id(_dst_id), _slot, int_id(_peer_id))
                    self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
                return

            # Is this is a new call stream?
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                self.STATUS['RX_START'] = pkt_time
                self._logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)

            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC
                ) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (
                    self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                self._logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)

            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS'] = _rf_src
            self.STATUS[_slot]['RX_TYPE'] = _dtype_vseq
            self.STATUS[_slot]['RX_TGID'] = _dst_id
            self.STATUS[_slot]['RX_TIME'] = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id

            for _target in self._CONFIG['SYSTEMS']:
                if _target != self._system:

                    _target_status = systems[_target].STATUS
                    _target_system = self._CONFIG['SYSTEMS'][_target]

                    # Check for GLOBAL Subscriber ID ACL Match
                    if acl_check(_rf_src,
                                 ACL['SID']['GLOBAL'][_slot]) == False:
                        if (_stream_id !=
                                _target_status[_slot]['TX_STREAM_ID']):
                            self._logger.warning(
                                '(%s) Group Voice Call ***REJECTED BY EGRESS GLOBAL ACL***    SID: %s SLOT: %s HBP Peer %s',
                                _target, int_id(_rf_src), _slot,
                                int_id(_peer_id))
                            _target_status[_slot]['TX_STREAM_ID'] = _stream_id
                        return
                    # Check for SYSTEM Subscriber ID ACL Match
                    if acl_check(_rf_src, ACL['SID'][_target][_slot]) == False:
                        if (_stream_id !=
                                _target_status[_slot]['TX_STREAM_ID']):
                            self._logger.warning(
                                '(%s) Group Voice Call ***REJECTED BY EGRESS SYSTEM ACL***    SID: %s SLOT: %s HBP Peer %s',
                                _target, int_id(_rf_src), _slot,
                                int_id(_peer_id))
                            _target_status[_slot]['TX_STREAM_ID'] = _stream_id
                        return

                    # Check for GLOBAL Talkgroup ID ACL Match
                    if acl_check(_dst_id,
                                 ACL['TGID']['GLOBAL'][_slot]) == False:
                        if (_stream_id !=
                                _target_status[_slot]['TX_STREAM_ID']):
                            self._logger.warning(
                                '(%s) Group Voice Call ***REJECTED BY EGRESS GLOBAL ACL***    TGID: %s SLOT: %s HBP Peer %s',
                                _target, int_id(_dst_id), _slot,
                                int_id(_peer_id))
                            _target_status[_slot]['TX_STREAM_ID'] = _stream_id
                        return
                    # Check for SYSTEM Talkgroup ID ID ACL Match
                    if acl_check(_dst_id,
                                 ACL['TGID'][_target][_slot]) == False:
                        if (_stream_id !=
                                _target_status[_slot]['TX_STREAM_ID']):
                            self._logger.warning(
                                '(%s) Group Voice Call ***REJECTED BY EGRESS SYSTEM ACL***    TGID: %s HBP Peer %s',
                                _target, int_id(_dst_id), int_id(_peer_id))
                            _target_status[_slot]['TX_STREAM_ID'] = _stream_id
                        return

                    systems[_target].send_system(_data)
Esempio n. 26
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))
Esempio n. 27
0
 def repeater_wake_up(self, _data):
     _source = _data[1:5]
     _source_name = get_alias(_source, peer_ids)
     print('({}) Repeater Wake-Up Packet Received: {} ({})'.format(
         self._system, _source_name, int_id(_source)))
Esempio n. 28
0
 def group_data(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
     _dst_sub = get_alias(_dst_sub, talkgroup_ids)
     _peerid = get_alias(_peerid, peer_ids)
     _src_sub = get_alias(_src_sub, subscriber_ids)
     print('({}) Group Data Packet Received From: {}'.format(
         self._system, _src_sub))
Esempio n. 29
0
 def private_data(self, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
     _dst_sub = get_alias(_dst_sub, subscriber_ids)
     _peerid = get_alias(_peerid, peer_ids)
     _src_sub = get_alias(_src_sub, subscriber_ids)
     print('({}) Private Data Packet Received From: {} To: {}'.format(
         self._system, _src_sub, _dst_sub))
Esempio n. 30
0
    def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
        pkt_time = time()
        dmrpkt = _data[20:53]
        _bits = int_id(_data[15])

        if _call_type == 'group':
            
            # Is this is a new call stream?
            if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
                self.STATUS['RX_START'] = pkt_time
                logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)
            
            # Final actions - Is this a voice terminator?
            if (_frame_type == hb_const.HBPF_DATA_SYNC) and (_dtype_vseq == hb_const.HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != hb_const.HBPF_SLT_VTERM):
                call_duration = pkt_time - self.STATUS['RX_START']
                logger.info('(%s) *CALL END*   STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
                        self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
            
            # Mark status variables for use later
            self.STATUS[_slot]['RX_RFS']       = _rf_src
            self.STATUS[_slot]['RX_TYPE']      = _dtype_vseq
            self.STATUS[_slot]['RX_TGID']      = _dst_id
            self.STATUS[_slot]['RX_TIME']      = pkt_time
            self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
            
            
            for _target in self._CONFIG['SYSTEMS']: 
                    if _target != self._system:
                        
                        _target_status = systems[_target].STATUS
                        _target_system = self._CONFIG['SYSTEMS'][_target]
                        _target_status[_slot]['TX_STREAM_ID'] = _stream_id
                            
                        # ACL Processing
                        if self._CONFIG['GLOBAL']['USE_ACL']:
                            if not acl_check(_rf_src, self._CONFIG['GLOBAL']['SUB_ACL']):
                                if self._laststrid != _stream_id:
                                    logger.debug('(%s) CALL DROPPED ON EGRESS WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL ACL', _target_system, int_id(_stream_id), int_id(_rf_src))
                                    self._laststrid = _stream_id
                                return
                            if _slot == 1 and not acl_check(_dst_id, self._CONFIG['GLOBAL']['TG1_ACL']):
                                if self._laststrid != _stream_id:
                                    logger.debug('(%s) CALL DROPPED ON EGRESS WITH STREAM ID %s ON TGID %s BY GLOBAL TS1 ACL', _target_system, int_id(_stream_id), int_id(_dst_id))
                                    self._laststrid = _stream_id
                                return
                            if _slot == 2 and not acl_check(_dst_id, self._CONFIG['GLOBAL']['TG2_ACL']):
                                if self._laststrid != _stream_id:
                                    logger.debug('(%s) CALL DROPPED ON EGRESS WITH STREAM ID %s ON TGID %s BY GLOBAL TS2 ACL', _target_system, int_id(_stream_id), int_id(_dst_id))
                                    self._laststrid = _stream_id
                                return
                        if self._target_system['USE_ACL']:
                            if not acl_check(_rf_src, _target_system['SUB_ACL']):
                                if self._laststrid != _stream_id:
                                    logger.debug('(%s) CALL DROPPED ON EGRESS WITH STREAM ID %s FROM SUBSCRIBER %s BY SYSTEM ACL', _target_system, int_id(_stream_id), int_id(_rf_src))
                                    self._laststrid = _stream_id
                                return
                            if _slot == 1 and not acl_check(_dst_id, _target_system['TG1_ACL']):
                                if self._laststrid != _stream_id:
                                    logger.debug('(%s) CALL DROPPED ON EGRESS WITH STREAM ID %s ON TGID %s BY SYSTEM TS1 ACL', _target_system, int_id(_stream_id), int_id(_dst_id))
                                    self._laststrid = _stream_id
                                return
                            if _slot == 2 and not acl_check(_dst_id, _target_system['TG2_ACL']):
                                if self._laststrid != _stream_id:
                                    logger.debug('(%s) CALL DROPPED ON EGRESS WITH STREAM ID %s ON TGID %s BY SYSTEM TS2 ACL', _target_system, int_id(_stream_id), int_id(_dst_id))
                                    self._laststrid = _stream_id
                                return
                        self._laststrid = _stream_id
                        
                        systems[_target].send_system(_data)