Merge pull request #17 from N4IRS/master
Add Changes From N4IRS and N4IRR to original
This commit is contained in:
commit
7607a5309d
|
@ -0,0 +1,9 @@
|
|||
[SETTINGS]
|
||||
_debug = False
|
||||
_outToFile = False
|
||||
_outToUDP = True
|
||||
_gateway = 127.0.0.1
|
||||
_gateway_port = 1234
|
||||
_remote_control_port = 1235
|
||||
_tg_filter = 2,3,13,3174,3777215,3100,9,9998,3112
|
||||
|
165
ambe_audio.py
165
ambe_audio.py
|
@ -14,9 +14,10 @@ from twisted.internet import reactor
|
|||
from binascii import b2a_hex as h
|
||||
from bitstring import BitArray
|
||||
|
||||
import sys
|
||||
import sys, socket, ConfigParser, thread, traceback
|
||||
import cPickle as pickle
|
||||
from dmrlink import IPSC, NETWORK, networks, logger, int_id, hex_str_3
|
||||
from dmrlink import IPSC, NETWORK, networks, logger, int_id, hex_str_3, get_info, talkgroup_ids, subscriber_ids, peer_ids
|
||||
from time import time
|
||||
|
||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||
__copyright__ = 'Copyright (c) 2015 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||
|
@ -27,18 +28,91 @@ __version__ = '0.1a'
|
|||
__email__ = 'n0mjs@me.com'
|
||||
__status__ = 'pre-alpha'
|
||||
|
||||
|
||||
try:
|
||||
from ipsc.ipsc_message_types import *
|
||||
except ImportError:
|
||||
sys.exit('IPSC message types file not found or invalid')
|
||||
|
||||
|
||||
#
|
||||
# ambeIPSC class,
|
||||
#
|
||||
class ambeIPSC(IPSC):
|
||||
|
||||
_configFile='ambe_audio.cfg'
|
||||
_debug = False
|
||||
_outToFile = False
|
||||
_outToUDP = True
|
||||
#_gateway = "192.168.1.184"
|
||||
_gateway = "127.0.0.1"
|
||||
_gateway_port = 1234
|
||||
_remote_control_port = 1235
|
||||
_tg_filter = [2,3,13,3174,3777215,3100,9,9998,3112] #set this to the tg to monitor
|
||||
_no_tg = -99
|
||||
_sock = -1;
|
||||
lastPacketTimeout = 0
|
||||
_transmitStartTime = 0
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
IPSC.__init__(self, *args, **kwargs)
|
||||
self.CALL_DATA = []
|
||||
|
||||
|
||||
#
|
||||
# Define default values for operation. These will be overridden by the .cfg file if found
|
||||
#
|
||||
|
||||
self._currentTG = self._no_tg
|
||||
self._sequenceNr = 0
|
||||
self.readConfigFile(self._configFile)
|
||||
|
||||
print('DMRLink ambe server')
|
||||
|
||||
#
|
||||
# Open output sincs
|
||||
#
|
||||
if self._outToFile == True:
|
||||
f = open('ambe.bin', 'wb')
|
||||
print('Opening output file: ambe.bin')
|
||||
if self._outToUDP == True:
|
||||
self._sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
print('Send UDP frames to DMR gateway {}:{}'.format(self._gateway, self._gateway_port))
|
||||
|
||||
try:
|
||||
thread.start_new_thread( self.remote_control, (self._remote_control_port, ) )
|
||||
except:
|
||||
traceback.print_exc()
|
||||
print( "Error: unable to start thread" )
|
||||
|
||||
|
||||
# Utility function to convert bytes to string of hex values (for debug)
|
||||
def ByteToHex( self, byteStr ):
|
||||
return ''.join( [ "%02X " % ord(x) for x in byteStr ] ).strip()
|
||||
|
||||
#
|
||||
# Now read the configuration file and parse out the values we need
|
||||
#
|
||||
def readConfigFile(self, configFileName):
|
||||
config = ConfigParser.ConfigParser()
|
||||
try:
|
||||
self._tg_filter=[]
|
||||
config.read(configFileName)
|
||||
for sec in config.sections():
|
||||
for key, val in config.items(sec):
|
||||
if self._debug == True:
|
||||
print( '%s="%s"' % (key, val) )
|
||||
self._debug = (config.get(sec, '_debug') == "True")
|
||||
self._outToFile = (config.get(sec, '_outToFile') == "True")
|
||||
self._outToUDP = (config.get(sec, '_outToUDP') == "True")
|
||||
self._gateway = config.get(sec, '_gateway')
|
||||
self._gateway_port = int(config.get(sec, '_gateway_port'))
|
||||
_tgs = config.get(sec, '_tg_filter')
|
||||
self._tg_filter = map(int, _tgs.split(','))
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
sys.exit('Configuration file \''+configFileName+'\' is not a valid configuration file! Exiting...')
|
||||
|
||||
#************************************************
|
||||
# CALLBACK FUNCTIONS FOR USER PACKET TYPES
|
||||
#************************************************
|
||||
|
@ -53,22 +127,79 @@ class ambeIPSC(IPSC):
|
|||
_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)
|
||||
_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))
|
||||
|
||||
def outputFrames(self, _ambe_frames, _ambe_frame1, _ambe_frame2, _ambe_frame3):
|
||||
if self._debug == True:
|
||||
print(_ambe_frames)
|
||||
print('Frame 1:', self.ByteToHex(_ambe_frame1.tobytes()))
|
||||
print('Frame 2:', self.ByteToHex(_ambe_frame2.tobytes()))
|
||||
print('Frame 3:', self.ByteToHex(_ambe_frame3.tobytes()))
|
||||
|
||||
if self._outToFile == True:
|
||||
f.write( _ambe_frame1.tobytes() )
|
||||
f.write( _ambe_frame2.tobytes() )
|
||||
f.write( _ambe_frame3.tobytes() )
|
||||
|
||||
if self._outToUDP == True:
|
||||
self._sock.sendto(_ambe_frame1.tobytes(), (self._gateway, self._gateway_port))
|
||||
self._sock.sendto(_ambe_frame2.tobytes(), (self._gateway, self._gateway_port))
|
||||
self._sock.sendto(_ambe_frame3.tobytes(), (self._gateway, self._gateway_port))
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Define a function for the thread
|
||||
# Use netcat to dynamically change the TGs that are forwarded to Allstar
|
||||
# echo "x,y,z" | nc 127.0.0.1 1235
|
||||
#
|
||||
def remote_control(self, port):
|
||||
s = socket.socket() # Create a socket object
|
||||
host = socket.gethostname() # Get local machine name
|
||||
s.bind((host, port)) # Bind to the port
|
||||
|
||||
s.listen(5) # Now wait for client connection.
|
||||
print('Remote control is listening on:', host, port)
|
||||
while True:
|
||||
c, addr = s.accept() # Establish connection with client.
|
||||
print( 'Got connection from', addr )
|
||||
tgs = c.recv(1024)
|
||||
if tgs:
|
||||
self._tg_filter = map(int, tgs.split(','))
|
||||
print( 'New TGs=', self._tg_filter )
|
||||
c.close() # Close the connection
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger.info('DMRlink \'ambe_audio.py\' (c) 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||
for ipsc_network in NETWORK:
|
||||
|
|
|
@ -218,7 +218,7 @@ class bridgeIPSC(IPSC):
|
|||
|
||||
# Calculate and append the authentication hash for the target network... if necessary
|
||||
if NETWORK[_target]['LOCAL']['AUTH_ENABLED']:
|
||||
_tmp_data = self.hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _tmp_data)
|
||||
_tmp_data = self.auth_hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _tmp_data)
|
||||
# Send the packet to all peers in the target IPSC
|
||||
networks[_target].send_to_ipsc(_tmp_data)
|
||||
|
||||
|
@ -242,7 +242,7 @@ class bridgeIPSC(IPSC):
|
|||
|
||||
# Calculate and append the authentication hash for the target network... if necessary
|
||||
if NETWORK[target]['LOCAL']['AUTH_ENABLED']:
|
||||
_tmp_data = self.hashed_packet(NETWORK[target]['LOCAL']['AUTH_KEY'], _tmp_data)
|
||||
_tmp_data = self.auth_hashed_packet(NETWORK[target]['LOCAL']['AUTH_KEY'], _tmp_data)
|
||||
# Send the packet to all peers in the target IPSC
|
||||
networks[target].send_to_ipsc(_tmp_data)
|
||||
|
||||
|
@ -258,7 +258,7 @@ class bridgeIPSC(IPSC):
|
|||
|
||||
# Calculate and append the authentication hash for the target network... if necessary
|
||||
if NETWORK[target]['LOCAL']['AUTH_ENABLED']:
|
||||
_tmp_data = self.hashed_packet(NETWORK[target]['LOCAL']['AUTH_KEY'], _tmp_data)
|
||||
_tmp_data = self.auth_hashed_packet(NETWORK[target]['LOCAL']['AUTH_KEY'], _tmp_data)
|
||||
# Send the packet to all peers in the target IPSC
|
||||
networks[target].send_to_ipsc(_tmp_data)
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#! /bin/sh
|
||||
|
||||
#################################################
|
||||
# #
|
||||
# Create directory structure for DMRlink #
|
||||
# #
|
||||
#################################################
|
||||
|
||||
# Minor updates to DIAL
|
||||
# rm /etc/asterisk/firsttime
|
||||
cd /etc/asterisk/
|
||||
wget https://github.com/N4IRS/AllStar/raw/master/configs/dnsmgr.conf
|
||||
# wget https://github.com/N4IRS/AllStar/raw/master/configs/modules.conf
|
||||
|
||||
# Checkout DMRlink and put it in /opt
|
||||
cd /srv
|
||||
git clone https://github.com/N4IRS/DMRlink
|
||||
cd /srv/DMRlink/
|
||||
./mk_dmrlink
|
||||
|
||||
# setup boot for DV3000
|
||||
cd /srv
|
||||
systemctl stop getty@ttyAMA0.service
|
||||
systemctl disable getty@ttyAMA0.service
|
||||
apt-get install -y sudo
|
||||
|
||||
# Setup WiringPi
|
||||
git clone git://git.drogon.net/wiringPi
|
||||
cd wiringPi/
|
||||
./build
|
||||
cd ..
|
||||
|
||||
# Setup AMBEserverGPIO
|
||||
git clone https://github.com/dl5di/OpenDV.git
|
||||
mv OpenDV/DummyRepeater/DV3000 DV3000
|
||||
rm -rf OpenDV
|
||||
cd DV3000/
|
||||
make clean
|
||||
make
|
||||
make install
|
||||
make init-install
|
||||
python AMBEtest3.py
|
||||
cd /etc/init.d
|
||||
update-rc.d AMBEserverGPIO start 50 2 3 4 5
|
||||
|
||||
# Setup DMRGateway
|
||||
cd /srv
|
||||
git clone https://github.com/N4IRS/DMRGateway.git
|
||||
cd DMRGateway/
|
||||
./install.sh
|
||||
cp config.txt /boot
|
||||
cp cmdline.txt /boot
|
||||
|
||||
# reboot
|
||||
|
||||
|
|
@ -46,6 +46,8 @@ __maintainer__ = 'Cort Buffington, N0MJS'
|
|||
__email__ = 'n0mjs@me.com'
|
||||
__status__ = 'beta'
|
||||
|
||||
# Change the current directory to the location of the application
|
||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-c', '--config', action='store', dest='CFG_FILE', help='/full/path/to/config.file (usually dmrlink.cfg)')
|
||||
|
@ -290,15 +292,15 @@ try:
|
|||
with open(PATH+'subscriber_ids.csv', 'rU') as subscriber_ids_csv:
|
||||
subscribers = csv.reader(subscriber_ids_csv, dialect='excel', delimiter=',')
|
||||
for row in subscribers:
|
||||
subscriber_ids[int(row[1])] = (row[0])
|
||||
subscriber_ids[int(row[0])] = (row[1])
|
||||
except ImportError:
|
||||
logger.warning('subscriber_ids.csv not found: Subscriber aliases will not be available')
|
||||
|
||||
|
||||
try:
|
||||
with open(PATH+'peer_ids.csv', 'rU') as peer_ids_csv:
|
||||
peers = csv.reader(peer_ids_csv, dialect='excel', delimiter=',')
|
||||
for row in peers:
|
||||
peer_ids[int(row[1])] = (row[0])
|
||||
peer_ids[int(row[0])] = (row[1])
|
||||
except ImportError:
|
||||
logger.warning('peer_ids.csv not found: Peer aliases will not be available')
|
||||
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
#
|
||||
# Rename to dmrlink.cfg and add your information
|
||||
#
|
||||
# minor tweaks to match install for use by DMRGateway
|
||||
# N4IRS
|
||||
#
|
||||
#
|
||||
|
||||
# GLOBAL CONFIGURATION ITEMS
|
||||
#
|
||||
[GLOBAL]
|
||||
PATH: /absolute/path/to/DMRlink
|
||||
PATH: /opt/dmrlink/
|
||||
|
||||
|
||||
# NETWORK REPORTING CONFIGURATION
|
||||
|
@ -54,9 +56,9 @@ PRINT_PEERS_INC_FLAGS: 0
|
|||
# used.
|
||||
#
|
||||
[LOGGER]
|
||||
LOG_FILE: /tmp/dmrlink.log
|
||||
LOG_HANDLERS: console
|
||||
LOG_LEVEL: CRITICAL
|
||||
LOG_FILE: /var/log/dmrlink/dmrlink.log
|
||||
LOG_HANDLERS: file
|
||||
LOG_LEVEL: INFO
|
||||
LOG_NAME: DMRlink
|
||||
|
||||
|
||||
|
@ -67,7 +69,7 @@ LOG_NAME: DMRlink
|
|||
# [NAME] The name you want to use to identify the IPSC instance (use
|
||||
# something better than "IPSC1"...)
|
||||
# ENABLED: Should we communiate with this network? Handy if you need to
|
||||
# shut one down but don't want to lose the config
|
||||
# shut one down but don't want to lose the config
|
||||
# RADIO_ID: This is the radio ID that DMRLink should use to communicate
|
||||
# IP: This is the local IPv4 address to listen on. It may be left
|
||||
blank if you do not need or wish to specify. It is mostly
|
||||
|
@ -103,10 +105,10 @@ LOG_NAME: DMRlink
|
|||
# ...Repeat the block for each IPSC network to join.
|
||||
#
|
||||
|
||||
[IPSC1]
|
||||
[SAMPLE_PEER]
|
||||
ENABLED: True
|
||||
RADIO_ID: 12345
|
||||
IP: 4.3.2.1
|
||||
IP: 127.0.0.1
|
||||
PORT: 50000
|
||||
ALIVE_TIMER: 5
|
||||
MAX_MISSED: 20
|
||||
|
@ -126,3 +128,31 @@ AUTH_ENABLED: True
|
|||
AUTH_KEY: 1A2B3C
|
||||
MASTER_IP: 1.2.3.4
|
||||
MASTER_PORT: 50000
|
||||
|
||||
|
||||
[SAMPLE_MASTER]
|
||||
ENABLED: False
|
||||
RADIO_ID: 54321
|
||||
IP: 192.168.1.1
|
||||
PORT: 50000
|
||||
ALIVE_TIMER: 5
|
||||
MAX_MISSED: 20
|
||||
PEER_OPER: True
|
||||
IPSC_MODE: DIGITAL
|
||||
TS1_LINK: True
|
||||
TS2_LINK: True
|
||||
CSBK_CALL: False
|
||||
RCM: True
|
||||
CON_APP: True
|
||||
XNL_CALL: False
|
||||
XNL_MASTER: False
|
||||
DATA_CALL: True
|
||||
VOICE_CALL: True
|
||||
MASTER_PEER: True
|
||||
AUTH_ENABLED: True
|
||||
AUTH_KEY: 1A2B3C
|
||||
# Below not used for a Master
|
||||
# MASTER_IP: 1.2.3.4
|
||||
# MASTER_PORT: 50000
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#! /bin/sh
|
||||
|
||||
#################################################
|
||||
# #
|
||||
# Create directory structure for DMRlink #
|
||||
# #
|
||||
#################################################
|
||||
|
||||
# To provide more readable output from DMRlink with current subscriber and repeater IDs, we download the CSV files from DMR-MARC
|
||||
# If you are going to use this in a cron task, don't run it more then once a day.
|
||||
# It might be good to find alternale a source as a backup.
|
||||
|
||||
# <http://www.dmr-marc.net/cgi-bin/trbo-database/datadump.cgi>
|
||||
|
||||
# wget -O users.csv -q "http://www.dmr-marc.net/cgi-bin/trbo-database/datadump.cgi?table=users&format=csv&header=0"
|
||||
|
||||
# Options are:
|
||||
|
||||
# table { users | repeaters }
|
||||
|
||||
# format { table | csv | csvq | json }
|
||||
|
||||
# header { 0 | 1 } (only applies to table and csv formats)
|
||||
|
||||
# id { nnnnnn } (query an individual record)
|
||||
|
||||
# Get the user IDs.
|
||||
wget -O subscriber_ids.csv -q "http://www.dmr-marc.net/cgi-bin/trbo-database/datadump.cgi?table=users&format=csv&header=0"
|
||||
|
||||
# Get the peer IDs
|
||||
wget -O peer_ids.csv -q "http://www.dmr-marc.net/cgi-bin/trbo-database/datadump.cgi?table=repeaters&format=csv&header=0"
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
#!/bin/sh
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: Mototrbo_IPSC_bridging
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: DMRlink Bridge
|
||||
# Description: Open Source IPSC bridging
|
||||
### END INIT INFO
|
||||
|
||||
# Where is the directory containing DMRlink
|
||||
DIR=/opt/dmrlink/bridge
|
||||
# Filename of the python script
|
||||
DAEMON=$DIR/bridge.py
|
||||
# Daemon name
|
||||
DAEMON_NAME=bridge
|
||||
|
||||
# Add any command line options for your daemon where
|
||||
DAEMON_OPTS=""
|
||||
|
||||
# This next line determines what user the script runs as.
|
||||
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
|
||||
DAEMON_USER=root
|
||||
|
||||
# The process ID of the script when it runs is stored here:
|
||||
PIDFILE=/var/run/$DAEMON_NAME.pid
|
||||
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
do_start () {
|
||||
log_daemon_msg "Starting system $DAEMON_NAME daemon"
|
||||
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
|
||||
log_end_msg $?
|
||||
}
|
||||
do_stop () {
|
||||
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
|
||||
start-stop-daemon --stop --pidfile $PIDFILE --remove-pidfile --retry 10
|
||||
log_end_msg $?
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
|
||||
start|stop)
|
||||
do_${1}
|
||||
;;
|
||||
|
||||
restart|reload|force-reload)
|
||||
do_stop
|
||||
do_start
|
||||
;;
|
||||
|
||||
status)
|
||||
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
|
||||
;;
|
||||
*)
|
||||
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
To install DMRlink for DMRGateway
|
||||
cd /srv
|
||||
git clone https://github.com/N4IRS/DMRlink.git
|
||||
cd DMRlink
|
||||
./mk_dmrlink
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
#! /bin/sh
|
||||
|
||||
#################################################
|
||||
# #
|
||||
# Create directory structure for DMRlink #
|
||||
# #
|
||||
#################################################
|
||||
|
||||
apt-get install unzip -y
|
||||
apt-get install python-twisted -y
|
||||
|
||||
# To allow multiple instances of DMRlink to run
|
||||
# You need multiple ipsc directories, dmrlink.py and dmrlink.cfg
|
||||
# The needed files are copied to /opt/dmrlink
|
||||
|
||||
# Make needed directories
|
||||
mkdir -p /opt/dmrlink/ambe_audio/ipsc
|
||||
mkdir -p /opt/dmrlink/bridge/ipsc
|
||||
mkdir -p /opt/dmrlink/gateway/ipsc
|
||||
mkdir -p /opt/dmrlink/log/ipsc
|
||||
mkdir -p /opt/dmrlink/playback/ipsc
|
||||
mkdir -p /opt/dmrlink/play_group/ipsc
|
||||
mkdir -p /opt/dmrlink/record/ipsc
|
||||
mkdir -p /opt/dmrlink/rcm/ipsc
|
||||
mkdir -p /opt/dmrlink/doc
|
||||
mkdir -p /opt/dmrlink/samples
|
||||
mkdir -p /var/log/dmrlink
|
||||
|
||||
# Put scripts in /opt/dmrlink
|
||||
cp /srv/DMRlink/get_ids.sh /opt/dmrlink # should be linked to /etc/cron.daily
|
||||
cp /srv/DMRlink/init.d/bridge /opt/dmrlink/rc.bridge
|
||||
|
||||
# bitstring install
|
||||
cd /opt/dmrlink
|
||||
wget https://pypi.python.org/packages/source/b/bitstring/bitstring-3.1.3.zip
|
||||
unzip bitstring-3.1.3.zip
|
||||
cd bitstring-3.1.3
|
||||
python setup.py install
|
||||
cd /opt/dmrlink
|
||||
rm bitstring-3.1.3.zip
|
||||
|
||||
# Put common files in /opt/dmrlink
|
||||
cp /srv/DMRlink/subscriber_ids.csv /opt/dmrlink
|
||||
cp /srv/DMRlink/talkgroup_ids.csv /opt/dmrlink
|
||||
cp /srv/DMRlink/peer_ids.csv /opt/dmrlink
|
||||
cp /srv/DMRlink/get_ids.sh /opt/dmrlink
|
||||
|
||||
# Copy ipsc directory into each app directory
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/ambe_audio/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/bridge/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/gateway/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/log/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/playback/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/play_group/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/record/ipsc
|
||||
cp /srv/DMRlink/ipsc/* /opt/dmrlink/rcm/ipsc
|
||||
|
||||
# Put the samples together for easy ref
|
||||
cp /srv/DMRlink/bridge_rules_SAMPLE.py /opt/dmrlink/samples
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/samples
|
||||
cp /srv/DMRlink/known_bridges_SAMPLE.py /opt/dmrlink/samples
|
||||
cp /srv/DMRlink/playback_config_SAMPLE.py /opt/dmrlink/samples
|
||||
|
||||
# Put the doc together for easy ref
|
||||
cp /srv/DMRlink/FAQ.md /opt/dmrlink/doc
|
||||
cp /srv/DMRlink/internal_data_decode.txt /opt/dmrlink/doc
|
||||
cp /srv/DMRlink/LICENSE.txt /opt/dmrlink/doc
|
||||
cp /srv/DMRlink/README.md /opt/dmrlink/doc
|
||||
cp /srv/DMRlink/requirements.txt /opt/dmrlink/doc
|
||||
|
||||
# Stock ambe_audio
|
||||
cp /srv/DMRlink/ambe_audio.cfg /opt/dmrlink/ambe_audio/
|
||||
cp /srv/DMRlink/ambe_audio.py /opt/dmrlink/ambe_audio/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/ambe_audio/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/ambe_audio/dmrlink.cfg
|
||||
|
||||
# ambe_audio for DMRGateway
|
||||
cp /srv/DMRlink/ambe_audio.cfg /opt/dmrlink/gateway/
|
||||
cp /srv/DMRlink/ambe_audio.py /opt/dmrlink/gateway/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/gateway/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/gateway/dmrlink.cfg
|
||||
|
||||
# Bridge app
|
||||
cp /srv/DMRlink/bridge.py /opt/dmrlink/bridge/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/bridge/
|
||||
cp /srv/DMRlink/bridge_rules_SAMPLE.py /opt/dmrlink/bridge/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/bridge/dmrlink.cfg
|
||||
|
||||
# Log app
|
||||
cp /srv/DMRlink/log.py /opt/dmrlink/log/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/log/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/log/dmrlink.cfg
|
||||
|
||||
# Playback (Parrot)
|
||||
cp /srv/DMRlink/playback.py /opt/dmrlink/playback/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/playback/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/playback/dmrlink.cfg
|
||||
|
||||
# Play Group app
|
||||
cp /srv/DMRlink/play_group.py /opt/dmrlink/play_group/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/play_group/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/play_group/dmrlink.cfg
|
||||
|
||||
# record app
|
||||
cp /srv/DMRlink/record.py /opt/dmrlink/record/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/record/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/record/dmrlink.cfg
|
||||
|
||||
# rcm app
|
||||
cp /srv/DMRlink/rcm_db_log.py /opt/dmrlink/rcm/
|
||||
cp /srv/DMRlink/rcm.py /opt/dmrlink/rcm/
|
||||
cp /srv/DMRlink/dmrlink.py /opt/dmrlink/rcm/
|
||||
cp /srv/DMRlink/dmrlink_SAMPLE.cfg /opt/dmrlink/rcm/dmrlink.cfg
|
||||
cp /srv/DMRlink/pickle_stat_reader.py /opt/dmrlink/rcm/
|
||||
|
1738
peer_ids.csv
1738
peer_ids.csv
File diff suppressed because one or more lines are too long
|
@ -1 +1,3 @@
|
|||
Twisted>=12.0.0
|
||||
https://pypi.python.org/packages/source/b/bitstring/bitstring-3.1.3.zip
|
||||
|
||||
|
|
24492
subscriber_ids.csv
24492
subscriber_ids.csv
File diff suppressed because one or more lines are too long
|
@ -1 +1,11 @@
|
|||
Worldwide,1
Local,2
North America,3
T6-DCI Bridge,3100
Kansas Statewide,3120
Missouri,3129
Massachussetts,3125
Midwest,3169
Northeast,3172
|
||||
Worldwide,1
Local,2
North America,3
|
||||
DMRPlus,9
|
||||
Worldwide English,13
|
||||
TAC 310,310
|
||||
DCI Bridge 2,3100
DCI 1,3160
|
||||
Midwest,3169
Northeast,3172
|
||||
Southeast,3174
|
||||
Flordia,3112
|
||||
Kansas Statewide,3120
Massachussetts,3125
Missouri,3129
|
||||
DCI Comm 1,3777215
|
||||
Echo Server,9998
|
|
Loading…
Reference in New Issue