def test_rifidi_server(self): self.port = '2020' self.host = 'localhost' telnet = Telnet(self.host, self.port) #telnet.write('\r\n') #expected = '\r\nosgi> ' actual = telnet.read_eager() #self.assertEqual(expected, actual) expected = {} expected['Rifidi App: Diagnostic:GPIO (STOPPED)'] = False expected['Rifidi App: Diagnostic:Serial (STOPPED)'] = False expected['Rifidi App: Diagnostic:Tags (STARTED)'] = False expected['Rifidi App: Diagnostic:TagGenerator (STARTED)'] = False expected['Rifidi App: AppService:ReadZones (STARTED)'] = False expected['Rifidi App: AppService:SensorStatus (STARTED)'] = False expected['Rifidi App: AppService:UniqueTagInterval (STARTED)'] = False expected['Rifidi App: AppService:StableSet (STARTED)'] = False expected['Rifidi App: AppService:UniqueTagBatchInterval (STARTED)'] = False expected['Rifidi App: Monitoring:ReadZones (STARTED)'] = False expected['Rifidi App: Monitoring:Tags (STARTED)'] = False expected['Rifidi App: Monitoring:SensorStatus (STARTED)'] = False expected['Rifidi App: Ambient:Association (STARTED)'] = False expected['Rifidi App: Ambient:DBApp (STARTED)'] = False expected['Rifidi App: Ambient:MessageReceiver (STARTED)'] = False expected['Rifidi App: Ambient:SensorDownAlert (STARTED)'] = False expected['Rifidi App: Ambient:TagCountApp (STARTED)'] = False expected['Rifidi App: Ambient:StationStatusAlert (STARTED)'] = False expected['Rifidi App: Ambient:Grouping (STARTED)'] = False expected['Rifidi App: Ambient:TagReadApp (STARTED)'] = False expected['Rifidi App: Ambient:Receiving (STARTED)'] = False expected['Rifidi App: Ambient:Portal (STOPPED)'] = False expected['Rifidi App: Ambient:ReceiveTest (STARTED)'] = False telnet.write('apps\r\n') time.sleep(2.5) done = False while not done: value = '' value = telnet.read_eager() actual += value if value == '': done = True actual = actual.replace('osgi>', '') actual = re.sub(r'[0-9]+:', '', actual, count=0) actual = actual.split('\r\n') for i in range(0, actual.__len__()-1): actual[i] = re.sub(r'^ ', '', actual[i]) for i in actual: if i in expected: expected[i] = True for i in expected.keys(): self.assertTrue(i)
def send_command(self, command): try: tvConnection = Telnet(self.ip, LG_WEBOS_CONTROL_PORT) print(tvConnection.read_eager().decode('ascii')) print("Command is: " + command) print(command.encode('ascii') + b"\n") tvConnection.write(command.encode('ascii') + b"\r\n") print(tvConnection.read_eager().decode('ascii')) tvConnection.close() except: print("Could not connect to TV")
class TelnetConnection(BaseClass): def __init__(self, host, port, username, password): """ Try to connect by Telnet to remote server and set attribute client and ftp_client if connected. If not, set attribute init_error to error raised by connection. :param host: host of the server :param port: port of the server :param username: username from server :param password: password for user from server """ super().__init__(host, port, username, password) self.client = None self.init_error = None try: self.client = Telnet(host) self.client.read_until('Username : '******'{username}\r') self.client.read_until('Password : '******'{password}\n') self.client.write('\r') except OSError as error: self.init_error = error self.logger.error(error) def execute(self, filename, command, message=None): """ Write to file or read from file according to command. :param filename: path to file on remote server :param command: command to work with file-read or write etc :param message: message to write into file """ if not self.client and self.init_error: return self.output(filename=filename, error=self.init_error) if command == 'read_file': try: self.client.write(f'cat {filename}') self.client.write('\n') data_from_file = self.client.read_eager() return self.output( filename=filename, output_data=f'Data from file: {data_from_file}') except Exception as error: return self.output(filename=filename, error=f'Got error {error}') if command == 'write_to_file': if not message: return self.output(filename=filename, error='Got no message ti write to file') try: self.client.write(f'echo {message} >> {filename}') return self.output( filename=filename, output_data=f'Data written to file: {message}') except Exception as error: return self.output(filename=filename, error=f'Got error {error}') return self.output( filename=filename, error='Useless command. Please, try again and check your input')
class connection: def __init__(self, port=""): self.serial = None self.tn = None self.connected = False if port == "": port = self.detect(port) if port == "": self.tn = Telnet("192.168.1.1", 5510) self.connected = True if port != "": self.serial = serial.Serial(port=port, baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1) self.connected = self.serial.is_open def detect(self, port): if port == "": for port in serial.tools.list_ports.comports(): if port.vid == 0x1199: portid = port.location[-1:] if int(portid) == 3: print("Detected Sierra Wireless device at: " + port.device) return port.device return "" def readreply(self): info = [] if self.serial is not None: while (True): tmp = self.serial.readline().decode('utf-8').replace('\r', '').replace('\n', '') if "OK" in info: return info elif ("ERROR" in info) or info == "": return -1 info.append(tmp) return info def send(self, cmd): if self.tn is not None: self.tn.write(bytes(cmd + "\r", 'utf-8')) time.sleep(0.05) data = "" while True: tmp = self.tn.read_eager() if tmp != b"": data += tmp.strip().decode('utf-8') else: break return data.split("\r\n") elif self.serial is not None: self.serial.write(bytes(cmd + "\r", 'utf-8')) time.sleep(0.05) return self.readreply() def close(self): if self.tn is not None: self.tn.close() self.connected = False if self.serial is not None: self.serial.close() self.connected = False
def test_rifidi_server(self): ret = subprocess.call(['sudo', '/etc/init.d/rifidi-server', 'stop']) ret1 = subprocess.call(['sudo', '/etc/init.d/rifidi-server', 'start']) assert not ret and not ret1 self.port = '2020' self.host = 'localhost' telnet = Telnet(self.host, self.port) #telnet.write('\r\n') expected = '\r\nosgi> ' actual = telnet.read_eager() self.assertEqual(expected, actual) expected = '\r\nosgi> 0:Rifidi App: Diagnostic:GPIO (STOPPED)\r\n'+\ '1:Rifidi App: Diagnostic:Serial (STOPPED)\r\n'+\ '2:Rifidi App: Diagnostic:Tags (STARTED)\r\n'+\ '3:Rifidi App: Diagnostic:TagGenerator (STARTED)\r\n'+\ '4:Rifidi App: AppService:ReadZones (STARTED)\r\n'+\ '5:Rifidi App: AppService:SensorStatus (STARTED)\r\n'+\ '6:Rifidi App: AppService:UniqueTagInterval (STARTED)\r\n'+\ '7:Rifidi App: AppService:StableSet (STARTED)\r\n'+\ '8:Rifidi App: AppService:UniqueTagBatchInterval (STARTED)\r\n'+\ '9:Rifidi App: Monitoring:ReadZones (STARTED)\r\n'+\ '10:Rifidi App: Monitoring:Tags (STARTED)\r\n'+\ '11:Rifidi App: Monitoring:SensorStatus (STARTED)\r\n'+\ 'osgi> ' telnet.write('apps\r\n') time.sleep(2.5) done = False while not done: value = '' value = telnet.read_eager() actual += value if value == '': done = True self.assertEqual(expected, actual)
class TelnetHacker(Hacker): @staticmethod def getServiceName(): return 'telnet' def init(self): self.server = args.server self.client = Telnet() def attempt(self, login, password): if args.verbose: msg = '%s / %s @ %s' % (login, password, self.server) self.log(msg) if args.debug: return False try: self.client.open(self.server, port=args.port, timeout=args.timeout) self.client.read_until('login: '******'Password: '******'"%s"' % msg if 'incorrect' in msg: return False # double check that we're in fact logged in cmd = 'echo $?' self.client.write(cmd + "\n") time.sleep(.1) msg = self.client.read_eager() if not msg.startswith(cmd): raise Exception('unexpected response: ' + msg) print '"%s"' % msg msg = msg[len(cmd):].strip(" \r\n") print '"%s"' % msg if not msg: # or did we timeout? return False if msg[0] in ['0', '1']: return True if msg[-1] in ['0', '1']: return True finally: self.client.close()
class tcpClient: '''This class is going to be an ascii interface layer of SSAL Test Suit''' def __init__(self,ip,port,timeout=5): from telnetlib import Telnet self.telnet=Telnet(host=ip,port=port,timeout=timeout) self.ip=ip self.port=port self.timeout=timeout self.data=b"" def send(self,data): '''Will raise Broken pipe error if connection closed, otherwise will send ascii data over telnet''' self.telnet.write(data) def sendLine(self,data): '''Will raise Broken pipe error if connection closed, otherwise will send ascii data new line terminated over telnet''' self.telnet.write((data+"\n").encode()) def sendCRLF(self,data): '''Will raise Broken pipe error if connection closed, otherwise will send ascii data new line terminated over telnet''' self.telnet.write((data+"\r\n").encode()) def readLine(self): '''Will raise EOFError if connection closed, otherwise will return ascii data''' return self.telnet.read_until(b"\n",timeout=self.timeout) def readAvailable(self): '''Will raise EOFError if connection closed, otherwise will return ascii data''' return self.telnet.read_eager() def asyncRead(self,delay=0.1): import time from threading import Thread def run(): self.run=True while(self.run): data=self.readLine() self.data+=data time.sleep(delay) t=Thread(target=run) t.start() def avilable(self): return len(self.data) def read(self): data=self.data self.data=b"" return data def close(self): self.run=False self.telnet.close() def stop(self): self.run=False def __del__(self): self.stop()
class telnet: '''This class is going to be an ascii interface layer of SSAL Test Suit''' def __init__(self, ip, port, timeout=0.5): from telnetlib import Telnet self.telnet = Telnet(host=ip, port=port, timeout=timeout) self.ip = ip self.port = port self.timeout = timeout def send(self, data): '''Will raise Broken pipe error if connection closed, otherwise will send ascii data over telnet''' self.telnet.write(data.encode()) def sendLine(self, data): '''Will raise Broken pipe error if connection closed, otherwise will send ascii data new line terminated over telnet''' self.telnet.write((data + "\n").encode()) def sendCRLF(self, data): '''Will raise Broken pipe error if connection closed, otherwise will send ascii data new line terminated over telnet''' self.telnet.write((data + "\r\n").encode()) def readLine(self): '''Will raise EOFError if connection closed, otherwise will return ascii data''' return self.telnet.read_until(b"\n", timeout=self.timeout).decode() def readAvailable(self): '''Will raise EOFError if connection closed, otherwise will return ascii data''' return self.telnet.read_eager().decode() def close(self): '''Close telnet connection''' self.telnet.close() def reconnect(self): '''Manual reconnection''' from telnetlib import Telnet self.telnet = Telnet(host=self.ip, port=self.port, timeout=self.timeout)
def telnet_read_eager(tn: telnetlib.Telnet, wf: object, current_output_log: List[str], enable_removeLF: bool) -> str: """ Dealing with unread material. """ """ if tn.eof == True: return "" """ current_output = tn.read_eager() decoded_current_output = decode(current_output) if len(current_output) > 0: if enable_removeLF: print_and_write(decoded_current_output, wf, current_output_log, string_remove="\n") else: print_and_write(decoded_current_output, wf, current_output_log, string_remove="") return decoded_current_output
("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))) os.write(standard_err, "Firewall issue? Correct address?\n") sys.exit(1) if verbose: #sock.set_debuglevel(10000) print "socket open to %s %d\n" % (address, telnet_port) tries = MAX_TRIES while 1: i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) if i == ERROR: os.write(standard_err, ( "FENCE: An error was encountered when communicating with the rsb device at %s" % address)) buf = sock.read_eager() os.write(standard_err, ("FENCE: The error message is - %s" % txt + " " + buf)) sock.close() sys.exit(1) try: buf = sock.read_eager() except EOFError: if completed_action == 1: # action was completed succesfully, connection closed is OK sys.exit(result) else: raise if i == USERNAME:
class TelnetClient(): def __init__(self, port, password, server_id): self.terminate = False self.server_id = server_id self.tn = Telnet('localhost', port) self.tn.read_until('Enter password:{0}'.format(os.linesep)) self.tn.write(password + os.linesep) self.start_time = time.time() self.run() def read(self): try: return self.tn.read_eager() except: self.terminate = True return '' def write(self, line): try: self.tn.write(line.encode('UTF-8') + os.linesep) except: self.terminate = True def send_back(self, lines_to_send): key = 'server-{0}-out'.format(self.server_id) lines = cache.get(key, []) lines.extend(lines_to_send) cache.set(key, lines) def get_lines_from_cache(self): key = 'server-{0}-in'.format(self.server_id) lines = cache.get(key, []) cache.delete(key) return lines def ping(self): pingtime = cache.get('server-{0}-ping'.format(self.server_id)) if not pingtime or time.time() - pingtime > 3: self.terminate = True def run(self): received_data = '' while True: # check if we should shut down the process self.ping() # terminate!! if self.terminate: break # receive lines from server received_data += self.read() lines = received_data.split(os.linesep) received_data = lines.pop() # put tail back to buffer for next run # lines to send back to client if lines: self.send_back(lines) # lines to send to telnet server for line in self.get_lines_from_cache(): self.write(line) time.sleep(0.2) # be nice to CPU run only 5 times per sec
class TelnetPCChannel(Channel): """ Telnet PC 主要是linux server的类,包含读写以及重连断开等动作 """ def __init__(self, host, port, timeout=300): """ 初始化telnet lib实例 :param host: ip :param port: 端口 :param timeout: 超时时间 """ self.conn_type = 'TelnetPC' self.host = host self.port = port try: self.telnet = Telnet(host, port, timeout) self.telnet.set_option_negotiation_callback( self.handle_negotiation) # 设置回调函数处理跟终端的协商 self.telnet.sock.sendall(IAC + DO + SGA + IAC + WONT + TTYPE) self.telnet.set_debuglevel(0) # 调试开关 0 不开启调试 self.connected = True self.msg = '' except Exception as e: print('Connect to host:' + host + '[' + str(e) + ']') self.msg = 'Connect to host:' + host + '[' + str(e) + ']' self.connected = False def handle_negotiation(self, socket, command, option): """ 回调函数,处理telnet服务器发送回来的协商报文 :param socket: socket :param command: WILL DO and so on :param option: ECHO SGA and so on :return: none """ if command == DO and option == ECHO: # ECHO socket.sendall(IAC + WONT + ECHO) # Wont Echo if command == WILL and option == ECHO: # Will Echo socket.sendall(IAC + DO + ECHO) # Do Echo if command == DO and option == TSPEED: # Terminal Speed socket.sendall(IAC + WONT + TSPEED) # Wont Terminal Speed if command == DO and option == XDISPLOC: # X Display Location socket.sendall(IAC + WONT + XDISPLOC) # Wont X Display Location if command == DO and option == NEW_ENVIRON: # New Environment Option socket.sendall(IAC + WONT + NEW_ENVIRON) # Wont New Environment Option if command == DO and option == NAWS: # Negotiate About Window Size # 回应WindowSize大小 Width=90 Height=32 和 Do not Status 仿照SecurityCRT socket.sendall(IAC + WILL + NAWS + IAC + SB + NAWS + chr(0).encode('ascii') + chr(90).encode('ascii') + chr(0).encode('ascii') + chr(32).encode('ascii') + IAC + SE + IAC + DONT + STATUS) if command == DO and option == LFLOW: # Remote Flow Control socket.sendall(IAC + WILL + LFLOW) # Will Remote Flow Control # if command == WILL and option == SGA: # socket.send(IAC + DO + SGA) if command == DO and option == STATUS: # Do Status socket.sendall(IAC + WONT + STATUS) # Wont Status if command == DO and option == TTYPE: # Terminal Type socket.sendall(IAC + WONT + TTYPE) # Do not Terminal Type # -------------------------此处代码等待后续进行扩展,完全仿造CRT做----------------------------------------------- if self.telnet.read_sb_data( ) == TTYPE + chr(1).encode('ascii'): # 匹配服务器发送的协商vty类型的消息 # 回复vty的类型 'vt100' socket.send(IAC + SB + TTYPE + chr(0).encode('ascii') + chr(118).encode('ascii') + chr(116).encode('ascii') + chr(49).encode('ascii') + chr(48).encode('ascii') + chr(48).encode('ascii') + IAC + SE) def is_alive(self): """ 判断连接状态 :return: True:成功 False:失败 """ return self.connected def is_exist_data(self): """ 判断socket上面是否存在数据 :return: True:存在数据,False:不存在数据 :rtype: bool """ return self.telnet.sock_avail() def reconnectChannel(self, reconnect_times=100, sleep_interval=1): """ telnet重连 :param reconnect_times: 重连次数,默认100 :type reconnect_times: int :param sleep_interval: 每次重连时间,默认1s :type sleep_interval: int :return: None :rtype: None """ for times in range(reconnect_times): time.sleep(sleep_interval) try: self.telnet.close() self.telnet = Telnet(self.host, self.port, 3) self.telnet.set_option_negotiation_callback( self.handle_negotiation) self.telnet.sock.sendall(IAC + DO + SGA + IAC + WONT + TTYPE) self.connected = True print("[通知]socket重连成功") return self.telnet except BaseException as e: self.connected = False print('try %d times:%s' % (times, e)) return 0 def disconnectChannel(self): """ 断开socket连接 :return: """ self.telnet.close() def readChannel(self): """ 读取远程服务器返回信息,如果为空,暂停0.01s, 断开连接触发重传 :return: """ if not self.is_exist_data(): time.sleep(0.01) try: res = self.telnet.read_eager( ) # 此处连接linux pc注意使用read_eager否则cat大文件的时候会假死 return res if res else None except BaseException as e: print(e) self.reconnectChannel() def writeChannel(self, type_in): """ 往远端服务器写入信息 :param type_in: 往远端服务器输入的信息 :return: None """ try: if type_in == '\003' or type_in == '\003\r': self.telnet.sock.sendall(IAC + WILL + ECHO) self.telnet.sock.sendall(IAC + WILL + SGA) self.telnet.write(type_in.encode('ascii')) except BaseException as e: print(e) self.reconnectChannel()
def test_connection(): T = Telnet() T.open("smtp.gmail.com", port=587) time.sleep(0.5) assert T.read_eager().decode().split(" ")[0] == "220" T.close()
try: while (rescnt<2): #print ("aaa") if (songlen>titleDispLen): MoveTime+=1 if (MoveTime>MoveRate): MoveTime=0 if (DisplayPos+titleDispLen>songlen): DisplayPos=0 else: DisplayPos+=2 cad.lcd.set_cursor(0,0) dispEnd=DisplayPos+titleDispLen write_to_cad(title[DisplayPos:dispEnd]) try: readline=conn.read_eager() except: sys.exit() if (len(readline) >0 ): LineEnd=readline.find(b'\n') if LineEnd == -1: fullLine+=readline.decode('utf8') if LineEnd == 0: fullLine=parse.unquote(fullLine) #print (fullLine) displayline(fullLine) readline=readline[2:len(readline)] fullLine=readline.decode('utf8')
class connection(metaclass=LogBase): def __init__(self, port=""): self.serial = None self.tn = None self.connected = False if port == "": port = self.detect(port) if port == "": try: self.tn = Telnet("192.168.1.1", 5510, 5) self.connected = True except: self.connected = False if port != "": self.serial = serial.Serial(port=port, baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1) self.connected = self.serial.is_open def waitforusb(self, vid, pid): timeout = 0 while timeout < 10: for device in self.detectusbdevices(): if device.vid == vid: if device.pid == pid: return True time.sleep(1) timeout += 1 return False def websend(self, url): headers = { 'Referer': 'http://192.168.0.1/index.html', 'Accept-Charset': 'UTF-8' } r = requests.get(url, headers=headers) if b"FACTORY:ok" in r.content or b"success" in r.content: print( f"Detected a ZTE in web mode .... switching mode success (convert back by sending \"AT+ZCDRUN=F\" via AT port)" ) return self.waitforusb(vendor.zte.value, 0x0016) return False def getserialports(self): return [port for port in serial.tools.list_ports.comports()] def detectusbdevices(self): dev = usb.core.find(find_all=True) ids = [deviceclass(cfg.idVendor, cfg.idProduct) for cfg in dev] return ids def detect(self, port): vendortable = { 0x1199: ["Sierra Wireless", 3], 0x2c7c: ["Quectel", 3], 0x19d2: ["ZTE", 2], 0x0846: ["Netgear", 2], 0x413c: ["Telit", 0] } mode = "Unknown" for device in self.detectusbdevices(): if device.vid == vendor.zte.value: if device.pid == 0x0016: print( f"Detected a {vendortable[device.vid][0]} device with pid {hex(device.pid)} in Diag mode" ) mode = "AT" break elif device.pid == 0x1403: print( f"Detected a {vendortable[device.vid][0]} device with pid {hex(device.pid)} in Web mode" ) mode = "Web" # url = 'http://192.168.0.1/goform/goform_set_cmd_process?goformId=USB_MODE_SWITCH&usb_mode=1' #adb url = 'http://192.168.0.1/goform/goform_process?goformId=MODE_SWITCH&switchCmd=FACTORY' if self.websend(url): mode = "AT" break elif device.vid == vendor.telit.value: if device.pid == 0x81d7: print( f"Detected a {vendortable[device.vid][0]} device with pid {hex(device.pid)} in Diag mode" ) print("Sending download mode command") interface = 5 diag = qcdiag(loglevel=self.__logger.level, portconfig=[[0x413c, 0x81d7, interface]]) if diag.connect(): data = diag.hdlc.receive_reply() res = diag.send(b"\x4b\x65\x01\x00") if res[0] == 0x4B: print("Sending download mode succeeded") diag.disconnect() break if mode == "AT" or mode == "Unknown": for port in self.getserialports(): if port.vid in vendortable: portid = port.location[-1:] if int(portid) == vendortable[port.vid][1]: print( f"Detected a {vendortable[port.vid][0]} at interface at: " + port.device) return port.device return "" def readreply(self): info = [] timeout = 0 if self.serial is not None: while True: tmp = self.serial.readline().decode('utf-8').replace( '\r', '').replace('\n', '') if "OK" in tmp: info.append(tmp) return info elif "ERROR" in tmp: return -1 if tmp != "": info.append(tmp) else: timeout += 1 if timeout == 20: break return info def send(self, cmd): if self.tn is not None: self.tn.write(bytes(cmd + "\r", 'utf-8')) time.sleep(0.05) data = "" while True: tmp = self.tn.read_eager() if tmp != b"": data += tmp.strip().decode('utf-8') else: break return data.split("\r\n") elif self.serial is not None: self.serial.write(bytes(cmd + "\r", 'utf-8')) time.sleep(0.05) return self.readreply() def close(self): if self.tn is not None: self.tn.close() self.connected = False if self.serial is not None: self.serial.close() self.connected = False def ati(self): data = {} info = self.send("ATI") if info != -1: for line in info: if "Revision" in line: data["revision"] = line.split(":")[1].strip() if "Model" in line: data["model"] = line.split(":")[1].strip() if "Quectel" in line: data["vendor"] = "Quectel" if "Manufacturer" in line: data["manufacturer"] = line.split(":")[1].strip() if "Sierra Wireless" in data["manufacturer"]: data["vendor"] = "Sierra Wireless" elif "ZTE CORPORATION" in data["manufacturer"]: data["vendor"] = "ZTE" elif "Netgear" in data["manufacturer"]: data["vendor"] = "Netgear" elif "Telit" in data["manufacturer"]: data["vendor"] = "Telit" return data
import os import sys import re import time import signal from os.path import join import subprocess from subprocess import Popen, PIPE from telnetlib import Telnet if __name__ == '__main__': # try a nice shutdown try : telnet = Telnet('localhost', '2020') actual = telnet.read_eager() telnet.write('close\r\n') time.sleep(1) actual = telnet.read_eager() telnet.write('y\r\n') except: pass # kill anything that is left p1 = Popen(['ps','ax'], stdout=PIPE) p2 = Popen(['grep', 'org.rifidi.edge'], stdin=p1.stdout, stdout=PIPE) output = p2.communicate()[0] output = output.split('\n') if output: for i in output: if re.search('grep', i):
class connection: def __init__(self, port=""): self.serial = None self.tn = None self.connected = False if port == "": port = self.detect(port) if port != "": self.serial = serial.Serial(port=port, baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1) self.connected = self.serial.is_open def waitforusb(self, vid, pid): timeout = 0 while timeout < 10: for device in self.detectusbdevices(): if device.vid == vid: if device.pid == pid: return True time.sleep(1) timeout += 1 return False def websend(self, url): headers = { 'Referer': 'http://192.168.0.1/index.html', 'Accept-Charset': 'UTF-8' } r = requests.get(url, headers=headers) if b"FACTORY:ok" in r.content or b"success" in r.content: print( f"Detected a ZTE in web mode .... switching mode success (convert back by sending \"AT+ZCDRUN=F\" via AT port)" ) return self.waitforusb(vendor.zte.value, 0x0016) return False def getserialports(self): return [port for port in serial.tools.list_ports.comports()] def detectusbdevices(self): dev = usb.core.find(find_all=True) ids = [deviceclass(cfg.idVendor, cfg.idProduct) for cfg in dev] return ids def detect(self, port): atvendortable = { 0x1199: ["Sierra Wireless", 3], 0x2c7c: ["Quectel", 3], 0x19d2: ["ZTE", 2], 0x413c: ["Telit", 3], 0x0846: ["Netgear", 2], 0x04E8: ["Samsung", -1] } mode = "Unknown" for device in self.detectusbdevices(): if device.vid == vendor.zte.value: if device.pid == 0x0016: print( f"Detected a {atvendortable[device.vid][0]} device with pid {hex(device.pid)} in AT mode" ) mode = "AT" break elif device.pid == 0x1403: print( f"Detected a {atvendortable[device.vid][0]} device with pid {hex(device.pid)} in Web mode" ) mode = "Web" url = 'http://192.168.0.1/goform/goform_set_cmd_process?goformId=USB_MODE_SWITCH&usb_mode=6' if self.websend(url): print("Successfully enabled adb.") break elif device.vid == vendor.netgear.value: try: # vid 0846, netgear mr1100, mr5100 self.tn = Telnet("192.168.1.1", 5510, 5) self.connected = True except: self.connected = False if mode == "AT" or mode == "Unknown": for port in self.getserialports(): if port.vid in atvendortable: portid = port.location[-1:] if int(portid) == atvendortable[port.vid][1]: print( f"Detected a {atvendortable[port.vid][0]} at interface at: " + port.device) return port.device return "" def readreply(self): info = [] timeout = 0 if self.serial is not None: while True: tmp = self.serial.readline().decode('utf-8').replace( '\r', '').replace('\n', '') if "OK" in tmp: info.append(tmp) return info elif "ERROR" in tmp: return -1 if tmp != "": info.append(tmp) else: timeout += 1 if timeout == 20: break return info def send(self, cmd): if self.tn is not None: self.tn.write(bytes(cmd + "\r", 'utf-8')) time.sleep(0.05) data = "" while True: tmp = self.tn.read_eager() if tmp != b"": data += tmp.strip().decode('utf-8') else: break if "ERROR" in data: return -1 return data.split("\r\n") elif self.serial is not None: self.serial.write(bytes(cmd + "\r", 'utf-8')) time.sleep(0.05) resp = self.readreply() return resp def close(self): if self.tn is not None: self.tn.close() self.connected = False if self.serial is not None: self.serial.close() self.connected = False def ati(self): data = {} info = self.send("ATI") if info != -1: for line in info: if "Revision" in line: data["revision"] = line.split(":")[1].strip() if "Model" in line: data["model"] = line.split(":")[1].strip() if "Quectel" in line: data["vendor"] = "Quectel" if "Manufacturer" in line: data["manufacturer"] = line.split(":")[1].strip() if "Sierra Wireless" in data["manufacturer"]: data["vendor"] = "Sierra Wireless" elif "ZTE CORPORATION" in data["manufacturer"]: data["vendor"] = "ZTE" elif "SIMCOM INCORPORATED" in data["manufacturer"]: data["vendor"] = "Simcom" elif "Alcatel" in data["manufacturer"]: data["vendor"] = "Alcatel" elif "Netgear" in data["manufacturer"]: data["vendor"] = "Netgear" elif "SAMSUNG" in data["manufacturer"]: data["vendor"] = "Samsung" info = self.send("AT+CGMI") if info != -1: for line in info: if "Quectel" in line: data["vendor"] = "Quectel" break elif "Fibucom" in line: data["vendor"] = "Fibucom" break elif "Netgear" in line: data["vendor"] = "Netgear" break elif "SAMSUNG" in line: data["vendor"] = "Samsung" break info = self.send("AT+CGMR") if info != -1: if len(info) > 1: data["model"] = info[1] return data
class TelnetClient(object): #---------------------------------------------------------------------- def __init__(self, host, port): self._client = Telnet(host, port, timeout=TELNET_TIMEOUT) self._prompts = dict(default='>>> ', continous='... ') self._prompt_default = self._prompts['default'] self._prompt_continous = self._prompts['continous'] self._next_prompt = self._prompts['default'] #---------------------------------------------------------------------- def _read_input(self): prompt = self._next_prompt if sys.stdin.isatty() else '' data_to_send = str(raw_input(prompt)) data_to_send += '\n' return data_to_send #---------------------------------------------------------------------- def _read_response(self): return self._client.read_eager() #---------------------------------------------------------------------- def _get_next_prompt(self, response): current_prompt = response[-4:] if current_prompt in self._prompts.itervalues(): self._next_prompt = current_prompt else: self._next_prompt = None #---------------------------------------------------------------------- def _have_prompt(self): return (self._next_prompt is not None) #---------------------------------------------------------------------- def _fetch_remote_locals(self): """ Read the locals() from the remote console and then add their keys into the local main namespace to get them auto completed as they were 'real' locals. """ self._client.write('locals().keys()\n') received_data = self._client.read_until(self._prompt_default, timeout=TELNET_TIMEOUT) received_data = received_data[:-4] keys = eval(received_data) for key in keys: if not __main__.__dict__.has_key(key): __main__.__dict__[key] = getattr(__main__, key, None) #---------------------------------------------------------------------- def _get_initial_prompt(self): received_data = self._client.read_until(self._prompt_default, timeout=TELNET_TIMEOUT) if sys.stdin.isatty(): sys.stdout.write(received_data[:-4]) # do some magic for auto completion self._fetch_remote_locals() # enable readline completion after we filled __main__.__dict__ with the # locals of the remote console readline.parse_and_bind("tab: complete") #---------------------------------------------------------------------- def _run(self): self._get_initial_prompt() while True: if self._have_prompt(): data_to_send = self._read_input() if data_to_send: self._client.write(data_to_send) received_data = self._read_response() self._get_next_prompt(received_data) if self._next_prompt: # cut off the prompt, if any received_data = received_data[:-4] # print data sys.stdout.write(received_data) #---------------------------------------------------------------------- def run(self): try: return self._run() except (EOFError, KeyboardInterrupt): pass finally: self._client.close()
def run(self, args): port = args.port cn = connection(port) if cn.connected: info = cn.ati() if "vendor" in info: if info["vendor"] == "Sierra Wireless" or info[ "vendor"] == "Netgear": print("Sending at switch command") kg = SierraKeygen(cn) if kg.openlock(): if cn.send('AT!CUSTOM="ADBENABLE",1\r') == -1: print("Error on sending adb enable command.") if cn.send('AT!CUSTOM="TELNETENABLE",1\r') != -1: time.sleep(5) tn = Telnet("192.168.1.1", 23, 15) tn.write(b"adbd &\r\n") info = tn.read_eager() print(info) print("Enabled adb via telnet") else: print("Error on sending telnet enable command.") elif info["vendor"] == "Quectel": print("Sending at switch command") salt = cn.send("AT+QADBKEY?\r") if salt != -1: if len(salt) > 1: salt = salt[1] code = crypt.crypt("SH_adb_quectel", "$1$" + salt) code = code[12:] cn.send("AT+QADBKEY=\"%s\"\r" % code) if cn.send( "AT+QCFG=\"usbcfg\",0x2C7C,0x125,1,1,1,1,1,1,0\r" ) == -1: if cn.send("AT+QLINUXCMD=\"adbd\"" ) != -1: #echo test > /dev/ttyGS0 print("Success enabling adb") else: print("Success enabling adb") print( "In order to disable adb, send AT+QCFG=\"usbcfg\",0x2C7C,0x125,1,1,1,1,1,0,0" ) elif info["vendor"] == "ZTE": print("Sending switch command via diag") if cn.send("AT+ZMODE=1") != -1: print("Success enabling adb") else: interface = 0 diag = qcdiag(loglevel=self.__logger.level, portconfig=[[0x19d2, 0x0016, interface]]) if diag.connect(): res = diag.send(b"\x4B\xA3\x06\x00") if res[0] == 0x4B: challenge = res[4:4 + 8] response = hashlib.md5(challenge).digest() res = diag.send(b"\x4B\xA3\x07\x00" + response) if res[0] == 0x4B: if res[3] == 0x00: print("Auth success") res = diag.send(b"\x41" + b"\x30\x30\x30\x30\x30\x30") if res[1] == 0x01: print("SPC success") sp = b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE" res = diag.send(b"\x46" + sp) if res[0] == 0x46 and res[1] == 0x01: print("SP success") else: res = diag.send(b"\x25" + sp) if res[0] == 0x46 and res[1] == 0x01: print("SP success") res = diag.send( b"\x4B\xFA\x0B\x00\x01") #Enable adb serial if res[0] != 0x13: print("Success enabling adb serial") res = diag.send(b"\x4B\x5D\x05\x00") #Operate ADB if res[0] != 0x13: print("Success enabling adb") diag.disconnect() elif info["vendor"] == "Simcom": print("Sending at switch command") # Simcom7600 if cn.send("AT+CUSBADB=1,1") != -1: print("Success enabling adb") elif info["vendor"] == "Fibocom": print("Sending at switch command") # FibocomL718: if cn.send("AT+ADBDEBUG=1") != -1: print("Success enabling adb") elif info["vendor"] == "Alcatel": print("Send scsi switch command") print( "Run \"sudo sg_raw /dev/sg0 16 f9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -v\" to enable adb" ) elif info["vendor"] == "Samsung": if cn.send("AT+USBMODEM=1"): print("Success enabling adb") elif cn.send("AT+SYSSCOPE=1,0,0"): print("Success enabling adb") cn.close()
class ZBController: def __init__(self): self.conn = Telnet() self.sequence = 0 def open(self, hostname): Telnet.open(self.conn, hostname, 4900) def _network_command(self, command, args, status_prefix): self.write('network %s %s' % (command, args)) _, match, _ = self.conn.expect(['%s (0x[0-9A-F]{2})' % status_prefix], timeout=2) if match is None: raise TimeoutError() return int(match.group(1), 0) def form_network(self, channel=19, power=0, pan_id = 0xfafa): status = self._network_command('form', '%d %d 0x%04x' % (channel, power, pan_id), 'form') if status == 0x70: #already in network pass elif status != 0x00: raise UnhandledStatusError() def leave_network(self): status = self._network_command('leave', '', 'leave') if status == 0x70: # already out of network pass elif status == 0x00: out = self.conn.read_until('EMBER_NETWORK_DOWN', timeout=2) if not out.endswith('EMBER_NETWORK_DOWN'): raise TimeoutError() else: raise UnhandledStatusError() def enable_permit_join(self): status = self._network_command('pjoin', '0xff', 'pJoin for 255 sec:') if status != 0x00: raise NetworkOperationError("Error enabling pjoin: 0x%x" % status) def disable_permit_join(self): status = self._network_command('pjoin', '0x00', 'pJoin for 0 sec:') if status == 0x00: print "Pjoin Disabled" else: print "Error disabling pjoin: 0x%x" % status def wait_for_join(self): _, match, _ = self.conn.expect(['Device Announce: (0x[0-9A-F]{4})']) if match is None: raise TimeoutError() print 'Device %s joined' % match.group(1) return int(match.group(1), 0) def send_zcl_command(self, destination, cmd, debug=False): payload = [] for arg in cmd.args: payload += _list_from_arg(arg.type, arg.value) if debug: sys.stdout.write('raw 0x%04X {01 %02X %02X %s}' % (cmd.cluster_code, self.sequence, cmd.code, " ".join(["%02X" % x for x in payload]))) else: self.write('raw 0x%04X {01 %02X %02X %s}' % (cmd.cluster_code, self.sequence, cmd.code, " ".join(["%02X" % x for x in payload]))) self.write('send 0x%04X 1 1' % destination) self.sequence = self.sequence + 1 % 0x100 #TODO: wait for response def send_zcl_ota_notify(self, destination, cmd): payload = [] for arg in cmd.args: payload += _list_from_arg(arg.type, arg.value) self.write('zcl ota server notify 0x%04X %02X %s' % (destination, 1, " ".join(["0x%04X" % x for x in payload]))) self.sequence = self.sequence + 1 % 0x100 def bind_node(self, node_id, node_ieee_address, cluster_id, timeout = 10): ''' Binds a destination node to us. Expects node_id and cluster_id as integers, and node_ieee_address as a string with hex bytes separated by spaces. ''' self.write('zdo bind %d 1 1 %d {%s} {}' % ( node_id, cluster_id, node_ieee_address)) # note that we're basically waiting for any ZDO command, which is a little liberal # RX: ZDO, command 0x8021, status: 0x00 _, match, _ = self.conn.expect( ["RX: ZDO, command 0x[0-9A-Za-z]{4}, status: 0x([0-9A-Za-z]{2})"], timeout=timeout) if match is None: raise AssertionError("TIMED OUT waiting for bind response") if match.group(1) != '00': raise AssertionError("Bind Request returned status %s" % match.group(1)) def configure_reporting(self, destination, attribute, min_interval, max_interval, threshold): ''' Configures the device to report the given attribute to the controller. ''' if attribute.type in ['INT8U', 'INT16U', 'INT32U', 'INT8S', 'INT16S', 'INT32S']: threshold_value_list = _list_from_arg(attribute.type, threshold) else: threshold_value_list = [0] self.write('zcl global send-me-a-report %d %d %d %d %d {%s}' % ( attribute.cluster_code, attribute.code, attribute.type_code, min_interval, max_interval, _hex_string_from_list(threshold_value_list))) self.write('send 0x%04X 1 1' % destination) def write_attribute(self, destination, attribute, value, timeout = 10): ''' Writes an attribute on a device. Attributes are instances of ZCLAttribute. ''' payload = _list_from_arg(attribute.type, value, strip_string_length=True) write_log(0, "Writing Attribute %s to %s" % (attribute.name, " ".join(['%02X' % x for x in payload]))) self.write('zcl global write %d %d %d {%s}' % (attribute.cluster_code, attribute.code, attribute.type_code, " ".join(['%02X' % x for x in payload]))) self.write('send 0x%04X 1 1' % destination) #RX len 4, ep 01, clus 0x0020 (Unknown clus. [0x0020]) FC 18 seq EC cmd 04 payload[00 ] _, match, _ = self.conn.expect(['RX len [0-9]+, ep [0-9A-Z]+, ' + 'clus 0x%04X \([a-zA-Z0-9\.\[\]\(\) ]+\) .* cmd 04 payload\[([0-9A-Z ]*)\]' % attribute.cluster_code], timeout=timeout) #TODO: actually do something with the response def write_local_attribute(self, attribute, value): ''' Writes an attribute that's local to the controller. ''' payload = _list_from_arg(attribute.type, value) payload_string = " ".join(['%02X' % x for x in payload]) self.write('write 1 %d %d 1 %d {%s}' % ( attribute.cluster_code, attribute.code, attribute.type_code, payload_string)) time.sleep(1) def make_server(self): self.write('zcl global direction 1') def make_client(self): self.write('zcl global direction 0') #T000BD5C5:RX len 11, ep 01, clus 0x000A (Time) FC 18 seq 20 cmd 01 payload[00 00 00 E2 00 00 00 00 ] #READ_ATTR_RESP: (Time) #- attr:0000, status:00 #type:E2, val:00000000 def read_attribute(self, destination, attribute, timeout=10): self.write('zcl global read %d %d' % (attribute.cluster_code, attribute.code)) self.write('send 0x%04X 1 1' % destination) _, match, _ = self.conn.expect(['RX len [0-9]+, ep [0-9A-Z]+, ' + 'clus 0x%04X \([a-zA-Z0-9\.\[\]\(\) ]+\) .* cmd 01 payload\[([0-9A-Z ]*)\]' % attribute.cluster_code], timeout=timeout) if match is None: raise AssertionError('TIMED OUT reading attribute %s' % attribute.name) payload = [int(x, 16) for x in match.group(1).split()] attribute_id = _pop_argument('INT16U', payload) status = _pop_argument('INT8U', payload) if status != 0: raise AssertionError('Attribute Read failed with status 0x%02X' % status) attribute_type_code = _pop_argument('INT8U', payload) attribute_type = zcl.get_type_string(attribute_type_code) return _pop_argument(attribute_type, payload) #T183FCD64:RX len 5, ep 01, clus 0x0020 (Unknown clus. [0x0020]) FC 18 seq D3 cmd 0B payload[03 00 ] def expect_zcl_command(self, command, timeout=10): ''' Waits for an incomming message and validates it against the given cluster ID, command ID, and arguments. Any arguments given as None are ignored. Raises an AssertionError on mis-match or timeout. ''' # read and discard any data already queued up in the buffer self.conn.read_eager() # we're pretty loose about what we accept as the incoming command. This is # mostly to more easily handle DefaultResponses, which are displayed # with their cluster ID as whatever cluster they're responding to _, match, _ = self.conn.expect(['RX .* cmd %02X payload\[([0-9A-Z ]*)\]' % command.code], timeout=timeout) if match is None: raise AssertionError("TIMED OUT waiting for " + command.name) payload = [int(x, 16) for x in match.group(1).split()] _validate_payload(command.args, payload) def write(self, msg): self.conn.write(msg + '\n')
class Stream: def __init__(self, host, port, timeout=3000, testing=False): self.host = host self.port = port self.timeout = timeout self.socket = None self.testing = testing self.state = ConnectionState.INIT def connect(self): if self.testing: logger.debug("Connected") self.state = ConnectionState.CONNECTED return if self.state not in [ConnectionState.INIT or ConnectionState.DISCONNECTED]: return try: self.socket = Telnet(self.host, self.port, self.timeout) data = self.socket.read_until(str.encode("*")) self.state = ConnectionState.CONNECTED logger.info(data) except OSError: logger.critical("Socket connection error") @property def is_connected(self): return self.state == ConnectionState.CONNECTED def ensure_connection(self): if self.is_connected: return raise OSError def close(self): if self.testing: logger.debug("Closed") return if not self.is_connected: return self.state = ConnectionState.DISCONNECTED self.socket.close() def send(self, cmd): logger.debug(cmd) if self.testing: return self.ensure_connection() try: self.socket.write(cmd.encode("ascii") + b'\n') except OSError: logger.error("Error sending data") def read(self): self.ensure_connection() while True: data = self.socket.read_eager() if len(data) == 0: break yield data def read_until(self, string): if self.testing: logger.debug("Reading") return self.ensure_connection() return self.socket.read_until(str.encode(string))
class TelnetCCMChannel(Channel): """ Telnet CCM 类,主要用户跟telnet ccm服务器交互(发送返回msg,处理协商,判断socket是否存在) """ def __init__(self, host, port, timeout=3): self.conn_type = 'TelnetCCM' self.host = host self.port = port self.timeout = timeout self.telnet = None self.msg = None self.connected = False try: self.telnet = Telnet(host, port, self.timeout) self.telnet.set_option_negotiation_callback( self.handle_negotiation) # 设置回调函数处理跟终端的协商 self.connected = True except BaseException as e: self.msg = 'Connect to host:' + host + '[' + str(e) + ']' self.connected = False print((self.msg)) @staticmethod def handle_negotiation(socket, command, option): """ 回调函数,处理telnet服务器发送回来的协商报文 :param socket: socket :param command: WILL DO and so on :param option: ECHO SGA and so on :return: none """ if command == WILL and option == ECHO: # Will Echo socket.send(IAC + DO + ECHO) # Do Echo if command == WILL and option == SGA: socket.send(IAC + DO + SGA) def reconnectChannel(self, reconnect_times=100, sleep_interval=1): """ telnet重连 :param reconnect_times: 重连次数,默认100 :type reconnect_times: int :param sleep_interval: 每次重连时间,默认1s :type sleep_interval: int :return: None :rtype: None """ for times in range(reconnect_times): time.sleep(sleep_interval) try: self.telnet.close() self.telnet = Telnet(self.host, self.port, self.timeout) self.connected = True print("[通知]socket重连成功") return self.telnet except BaseException as e: self.connected = False print('[通知]第%d次尝试重连,重连失败原因:%s' % (times, e)) def disconnectChannel(self): """ 断开连接 :return:None """ self.telnet.close() def readChannel(self): """ 读取ccm发回来的数据信息(如果数据为空不存在暂停0.01s),socket连接断开触发重连 :return: """ if not self.is_exist_data(): time.sleep(0.01) try: res = self.telnet.read_eager() return res except BaseException as e: print(e) self.reconnectChannel() def writeChannel(self, type_in): """ 往ccm服务器发送数据信息,socket断开触发重连 :param type_in: :return: """ try: self.telnet.write(type_in.encode('ascii')) except BaseException as e: print(e) self.reconnectChannel() def is_alive(self): """ 判断连接状态 :return: True:成功 False:失败 """ return self.connected def is_exist_data(self): """ 判断socket上面是否存在数据 :return: True:存在数据,False:不存在数据 :rtype: bool """ return self.telnet.sock_avail()
class Stream: def __init__(self, host, port, timeout=3000, testing=False): self.host = host self.port = port self.timeout = timeout self.socket = None self.testing = testing self.state = ConnectionState.INIT def connect(self): if self.testing: logger.debug("Connected") self.state = ConnectionState.CONNECTED return if self.state not in [ ConnectionState.INIT or ConnectionState.DISCONNECTED ]: return try: self.socket = Telnet(self.host, self.port, self.timeout) data = self.socket.read_until(str.encode("*")) self.state = ConnectionState.CONNECTED logger.info(data) except OSError: logger.critical("Socket connection error") @property def is_connected(self): return self.state == ConnectionState.CONNECTED def ensure_connection(self): if self.is_connected: return raise OSError def close(self): if self.testing: logger.debug("Closed") return if not self.is_connected: return self.state = ConnectionState.DISCONNECTED self.socket.close() def send(self, cmd): # logger.debug(cmd) if self.testing: return self.ensure_connection() try: self.socket.write(cmd.encode("ascii") + b'\n') except OSError: logger.error("Error sending data") def read(self): self.ensure_connection() while True: data = self.socket.read_eager() if len(data) == 0: break yield data def read_until(self, string): if self.testing: logger.debug("Reading") return self.ensure_connection() return self.socket.read_until(str.encode(string))
class ZBController: def __init__(self): self.conn = Telnet() self.sequence = 0 def open(self, hostname): Telnet.open(self.conn, hostname, 4900) def _network_command(self, command, args, status_prefix): self.write('network %s %s' % (command, args)) _, match, _ = self.conn.expect(['%s (0x[0-9A-F]{2})' % status_prefix], timeout=2) if match is None: raise TimeoutError() return int(match.group(1), 0) def form_network(self, channel=19, power=0, pan_id=0xfafa): status = self._network_command( 'form', '%d %d 0x%04x' % (channel, power, pan_id), 'form') if status == 0x70: #already in network pass elif status != 0x00: raise UnhandledStatusError() def leave_network(self): status = self._network_command('leave', '', 'leave') if status == 0x70: # already out of network pass elif status == 0x00: out = self.conn.read_until('EMBER_NETWORK_DOWN', timeout=2) if not out.endswith('EMBER_NETWORK_DOWN'): raise TimeoutError() else: raise UnhandledStatusError() def enable_permit_join(self): status = self._network_command('pjoin', '0xff', 'pJoin for 255 sec:') if status != 0x00: raise NetworkOperationError("Error enabling pjoin: 0x%x" % status) def disable_permit_join(self): status = self._network_command('pjoin', '0x00', 'pJoin for 0 sec:') if status == 0x00: print "Pjoin Disabled" else: print "Error disabling pjoin: 0x%x" % status def wait_for_join(self): _, match, _ = self.conn.expect(['Device Announce: (0x[0-9A-F]{4})']) if match is None: raise TimeoutError() print 'Device %s joined' % match.group(1) return int(match.group(1), 0) def send_zcl_command(self, destination, cmd, debug=False): payload = [] for arg in cmd.args: payload += _list_from_arg(arg.type, arg.value) if debug: sys.stdout.write('raw 0x%04X {01 %02X %02X %s}' % (cmd.cluster_code, self.sequence, cmd.code, " ".join(["%02X" % x for x in payload]))) else: self.write('raw 0x%04X {01 %02X %02X %s}' % (cmd.cluster_code, self.sequence, cmd.code, " ".join( ["%02X" % x for x in payload]))) self.write('send 0x%04X 1 1' % destination) self.sequence = self.sequence + 1 % 0x100 #TODO: wait for response def send_zcl_ota_notify(self, destination, cmd): payload = [] for arg in cmd.args: payload += _list_from_arg(arg.type, arg.value) self.write('zcl ota server notify 0x%04X %02X %s' % (destination, 1, " ".join(["0x%04X" % x for x in payload]))) self.sequence = self.sequence + 1 % 0x100 def bind_node(self, node_id, node_ieee_address, cluster_id, timeout=10): ''' Binds a destination node to us. Expects node_id and cluster_id as integers, and node_ieee_address as a string with hex bytes separated by spaces. ''' self.write('zdo bind %d 1 1 %d {%s} {}' % (node_id, cluster_id, node_ieee_address)) # note that we're basically waiting for any ZDO command, which is a little liberal # RX: ZDO, command 0x8021, status: 0x00 _, match, _ = self.conn.expect( ["RX: ZDO, command 0x[0-9A-Za-z]{4}, status: 0x([0-9A-Za-z]{2})"], timeout=timeout) if match is None: raise AssertionError("TIMED OUT waiting for bind response") if match.group(1) != '00': raise AssertionError("Bind Request returned status %s" % match.group(1)) def configure_reporting(self, destination, attribute, min_interval, max_interval, threshold): ''' Configures the device to report the given attribute to the controller. ''' if attribute.type in [ 'INT8U', 'INT16U', 'INT32U', 'INT8S', 'INT16S', 'INT32S' ]: threshold_value_list = _list_from_arg(attribute.type, threshold) else: threshold_value_list = [0] self.write('zcl global send-me-a-report %d %d %d %d %d {%s}' % (attribute.cluster_code, attribute.code, attribute.type_code, min_interval, max_interval, _hex_string_from_list(threshold_value_list))) self.write('send 0x%04X 1 1' % destination) def write_attribute(self, destination, attribute, value, timeout=10): ''' Writes an attribute on a device. Attributes are instances of ZCLAttribute. ''' payload = _list_from_arg(attribute.type, value, strip_string_length=True) write_log( 0, "Writing Attribute %s to %s" % (attribute.name, " ".join(['%02X' % x for x in payload]))) self.write( 'zcl global write %d %d %d {%s}' % (attribute.cluster_code, attribute.code, attribute.type_code, " ".join(['%02X' % x for x in payload]))) self.write('send 0x%04X 1 1' % destination) #RX len 4, ep 01, clus 0x0020 (Unknown clus. [0x0020]) FC 18 seq EC cmd 04 payload[00 ] _, match, _ = self.conn.expect([ 'RX len [0-9]+, ep [0-9A-Z]+, ' + 'clus 0x%04X \([a-zA-Z0-9\.\[\]\(\) ]+\) .* cmd 04 payload\[([0-9A-Z ]*)\]' % attribute.cluster_code ], timeout=timeout) #TODO: actually do something with the response def write_local_attribute(self, attribute, value): ''' Writes an attribute that's local to the controller. ''' payload = _list_from_arg(attribute.type, value) payload_string = " ".join(['%02X' % x for x in payload]) self.write('write 1 %d %d 1 %d {%s}' % (attribute.cluster_code, attribute.code, attribute.type_code, payload_string)) time.sleep(1) def make_server(self): self.write('zcl global direction 1') def make_client(self): self.write('zcl global direction 0') #T000BD5C5:RX len 11, ep 01, clus 0x000A (Time) FC 18 seq 20 cmd 01 payload[00 00 00 E2 00 00 00 00 ] #READ_ATTR_RESP: (Time) #- attr:0000, status:00 #type:E2, val:00000000 def read_attribute(self, destination, attribute, timeout=10): self.write('zcl global read %d %d' % (attribute.cluster_code, attribute.code)) self.write('send 0x%04X 1 1' % destination) _, match, _ = self.conn.expect([ 'RX len [0-9]+, ep [0-9A-Z]+, ' + 'clus 0x%04X \([a-zA-Z0-9\.\[\]\(\) ]+\) .* cmd 01 payload\[([0-9A-Z ]*)\]' % attribute.cluster_code ], timeout=timeout) if match is None: raise AssertionError('TIMED OUT reading attribute %s' % attribute.name) payload = [int(x, 16) for x in match.group(1).split()] attribute_id = _pop_argument('INT16U', payload) status = _pop_argument('INT8U', payload) if status != 0: raise AssertionError('Attribute Read failed with status 0x%02X' % status) attribute_type_code = _pop_argument('INT8U', payload) attribute_type = zcl.get_type_string(attribute_type_code) return _pop_argument(attribute_type, payload) #T183FCD64:RX len 5, ep 01, clus 0x0020 (Unknown clus. [0x0020]) FC 18 seq D3 cmd 0B payload[03 00 ] def expect_zcl_command(self, command, timeout=10): ''' Waits for an incomming message and validates it against the given cluster ID, command ID, and arguments. Any arguments given as None are ignored. Raises an AssertionError on mis-match or timeout. ''' # read and discard any data already queued up in the buffer self.conn.read_eager() # we're pretty loose about what we accept as the incoming command. This is # mostly to more easily handle DefaultResponses, which are displayed # with their cluster ID as whatever cluster they're responding to _, match, _ = self.conn.expect( ['RX .* cmd %02X payload\[([0-9A-Z ]*)\]' % command.code], timeout=timeout) if match is None: raise AssertionError("TIMED OUT waiting for " + command.name) payload = [int(x, 16) for x in match.group(1).split()] _validate_payload(command.args, payload) def write(self, msg): self.conn.write(msg + '\n')
class telnetspawn(pexpect.spawn): closed = True readahead = 16 readahead_buf = '' def __init__ (self, host, port=23, timeout=30, maxread=2000, searchwindowsize=None, logfile=None, sendlinesep="\r\n"): self.telnet = Telnet(host, port) self.sendlinesep = sendlinesep self.args = None self.command = None pexpect.spawn.__init__(self, None, None, timeout, maxread, searchwindowsize, logfile) self.child_fd = -1 self.own_fd = False self.closed = False self.name = '<telnet connection %s:%d>'%(host, port) self.default_timeout = timeout return def __del__ (self): telnetspawn.close(self) self.logfile.write("\n") return def close (self): if self.closed: return self.telnet.close() self.closed = True return def flush (self): while len(self.telnet.read_eager()) > 0: continue return def isatty (self): return False def isalive (self): return not self.closed def terminate (self, force=False): raise ExceptionPexpect ('This method is not valid for telnet connections.') def kill (self, sig): return def send(self, s): time.sleep(self.delaybeforesend) if self.logfile is not None: self.logfile.write (s) self.logfile.flush() if self.logfile_send is not None: self.logfile_send.write (s) self.logfile_send.flush() self.telnet.write(s) return s def send(self, s, noSendLog=None): if noSendLog is not None: self.send(s) else: time.sleep(self.delaybeforesend) self.telnet.write(s) return s def read_nonblocking (self, size=1, timeout=-1): if timeout != -1: self.timeout = timeout buf = self.readahead_buf self.readahead_buf = '' # FIXME: update timeout during this loop!! more = self.telnet.read_eager() while len(more) > 0: buf += more more = self.telnet.read_eager() if len(buf) <= size: if self.logfile is not None: self.logfile.write(buf) self.logfile.flush() if self.logfile_read is not None: self.logfile_read.write(buf) self.logfile_read.flush() return buf self.readahead_buf = buf[size:] buf = buf[:size] if timeout != -1: self.timeout = self.default_timeout if self.logfile is not None: self.logfile.write(buf) self.logfile.flush() if self.logfile_read is not None: self.logfile_read.write(buf) self.logfile_read.flush() return buf
import os import sys import re import time import signal from os.path import join import subprocess from subprocess import Popen, PIPE from telnetlib import Telnet if __name__ == '__main__': # try a nice shutdown try: telnet = Telnet('localhost', '2020') actual = telnet.read_eager() telnet.write('close\r\n') time.sleep(1) actual = telnet.read_eager() telnet.write('y\r\n') except: pass # kill anything that is left p1 = Popen(['ps', 'ax'], stdout=PIPE) p2 = Popen(['grep', 'org.rifidi.edge'], stdin=p1.stdout, stdout=PIPE) output = p2.communicate()[0] output = output.split('\n') if output: for i in output: if re.search('grep', i):