From 2e2c8e30a13725c269d2ed1258d89edaffffc288 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 30 Jan 2022 22:42:27 +0000 Subject: [PATCH] AMI --- AMI.py | 76 +++++++++++++++++++++++++----------------------- bridge_master.py | 36 +++++++++++++++++++++-- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/AMI.py b/AMI.py index 89f421b..c60ec80 100644 --- a/AMI.py +++ b/AMI.py @@ -1,18 +1,30 @@ +import sys + from time import time -from random import randint from twisted.internet import reactor,task from twisted.internet.defer import Deferred -from twisted.internet.protocol import ClientFactory,ReconnectingClientFactory,Protocol +from twisted.internet.protocol import ClientFactory,ClientFactory,Protocol from twisted.protocols.basic import LineReceiver class AMI(): - def __init__(self,host,port): + def __init__(self,host,port,username,secret,nodenum): self._AMIClient = self.AMIClient + self.host = host + self.port = port + self.username = username.encode('utf-8') + self.secret = secret.encode('utf-8') + self.nodenum = str(nodenum) + def send_command(self,command): + self._AMIClient.command = command + self._AMIClient.username = self.username + self._AMIClient.secret = self.secret + self._AMIClient.nodenum = self.nodenum.encode('utf-8') + self.command = command - self.CF = reactor.connectTCP(host, port, self.CCClientFactory(self._AMIClient)) + self.CF = reactor.connectTCP(self.host, self.port, self.AMIClientFactory(self._AMIClient)) def closeConnection(self): self.transport.loseConnection() @@ -21,55 +33,45 @@ class AMI(): delimiter = b'\r\n' - end = b"Bye-bye!" - def connectionMade(self): - print('b') - self.sendLine('Action: login') - self.sendLine('Username: admin') - self.sendLine('Secret: ilcgi') - self.sendLine('\r\n') + self.sendLine(b'Action: login') + self.sendLine(b''.join([b'Username: ',self.username])) + self.sendLine(b''.join([b'Secret: ',self.secret])) + self.sendLine(self.delimiter) def lineReceived(self,line): - print(line) - - if line == 'Asterisk Call Manager/1.0': - print('OK') + if line == b'Asterisk Call Manager/1.0': return - k,v = line.split(':') - - if v == ' Success': - self.lastresponse = True - elif k == 'Response' and v == ' Error': - self.transport.loseConnection() - - else: - self.sendLine('Action: command') - self.sendLine('Command:' + self.command) - self.sendline('\r\n') + if line == b'Response: Success': + self.sendLine(b'Action: command') + #print(b''.join([b'Command: ',b'rpt cmd ',self.nodenum,b' ',self.command])) + self.sendLine(b''.join([b'Command: ',b'rpt cmd ',self.nodenum,b' ',self.command])) + #self.sendLine(b'Command: ' + b'rpt cmd 29177 ilink 3 2001') + self.sendLine(self.delimiter) self.transport.loseConnection() - class AMIClientFactory(ReconnectingClientFactory): - def __init__(self,AMIClient,command): - self.command = command + class AMIClientFactory(ClientFactory): + def __init__(self,AMIClient): + #self.command = command self.done = Deferred() self.protocol = AMIClient - self.protocol.command = command - print('a') - + #self.protocol.command = command + def clientConnectionFailed(self, connector, reason): - print("connection failed:", reason.getErrorMessage()) - ReconnectingClientFactory.clientConnectionLost(self, connector, reason) + ClientFactory.clientConnectionLost(self, connector, reason) def clientConnectionLost(self, connector, reason): - print("connection lost:", reason.getErrorMessage()) - ReconnectingClientFactory.clientConnectionLost(self, connector, reason) + ClientFactory.clientConnectionLost(self, connector, reason) if __name__ == '__main__': - AMIc = AMI.AMIClientFactory(AMI.AMIClient,'rpt cmd 29177 ilink 3 2001') + + a = AMI(sys.argv[1],int(sys.argv[2]),'admin','llcgi',29177) + #AMIOBJ.AMIClientFactory(AMIOBJ.AMIClient,'rpt cmd 29177 ilink 3 2001') + a.send_command(sys.argv[3].encode('utf-8')) + reactor.run() diff --git a/bridge_master.py b/bridge_master.py index 437da19..9381b33 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -80,6 +80,7 @@ import re from binascii import b2a_hex as ahex +from AMI import AMI ##from hmac import new as hmac_new, compare_digest ##from hashlib import sha256, hash @@ -2216,7 +2217,7 @@ class routerHBP(HBSYSTEM): #Handle private voice calls (for reflectors) - if _call_type == 'unit' and not _data_call: + if _call_type == 'unit' and not _data_call and _slot == 2: if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']): self.STATUS[_slot]['packets'] = 0 @@ -2362,7 +2363,36 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['VOICE_STREAM'] = _voice_call self.STATUS[_slot]['packets'] = self.STATUS[_slot]['packets'] +1 - + + #Handle AMI + if _call_type == 'unit' and not _data_call and _slot == 1: + if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']): + if _int_dst_id == 4000: + logger.info('(%s) AMI: Private call from %s to %s (Disconnect)',self._system, int_id(_rf_src), _int_dst_id) + AMIOBJ.send_command('ilink 5 0') + else: + logger.info('(%s) AMI: Private call from %s to %s (Link)',self._system, int_id(_rf_src), _int_dst_id) + AMIOBJ.send_command('ilink 6 0') + AMIOBJ.send_command('ilink 3 ' + str(_int_dst_id)) + + if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != HBPF_SLT_VTERM): + pass + + + # Mark status variables for use later + self.STATUS[_slot]['RX_PEER'] = _peer_id + self.STATUS[_slot]['RX_SEQ'] = _seq + 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 + self.STATUS[_slot]['VOICE_STREAM'] = _voice_call + + self.STATUS[_slot]['packets'] = self.STATUS[_slot]['packets'] +1 + + + #Handle group calls if _call_type == 'group' or _call_type == 'vcsbk': @@ -2704,6 +2734,8 @@ if __name__ == '__main__': CONFIG['SYSTEMS'].update(SQLCONFIG) else: logger.debug('(MYSQL) problem connecting to SQL server, aborting') + + AMIOBJ = AMI('asl.gb7fr.org.uk',5038,'admin','llcgi',29177) # Set up the signal handler