[thci] add SSH support for OpenThread wpanctl THCI (#3086)

This commit is contained in:
Jing
2018-09-26 19:59:18 -07:00
committed by Jonathan Hui
parent be1641434b
commit ea1b83a4e7
3 changed files with 122 additions and 37 deletions
+80 -36
View File
@@ -39,6 +39,7 @@ import logging
from Queue import Queue from Queue import Queue
import serial import serial
import paramiko
from IThci import IThci from IThci import IThci
from GRLLibs.UtilityModules.Test import Thread_Device_Role, Device_Data_Requirement, MacType from GRLLibs.UtilityModules.Test import Thread_Device_Role, Device_Data_Requirement, MacType
from GRLLibs.UtilityModules.enums import PlatformDiagnosticPacket_Direction, PlatformDiagnosticPacket_Type from GRLLibs.UtilityModules.enums import PlatformDiagnosticPacket_Direction, PlatformDiagnosticPacket_Type
@@ -69,13 +70,19 @@ class OpenThread_WpanCtl(IThci):
try: try:
self.UIStatusMsg = '' self.UIStatusMsg = ''
self.mac = kwargs.get('EUI') self.mac = kwargs.get('EUI')
self.port = kwargs.get('SerialPort')
self.handle = None self.handle = None
self.AutoDUTEnable = False self.AutoDUTEnable = False
self._is_net = False # whether device is through ser2net self._is_net = False # whether device is through ser2net
self.logStatus = {'stop':'stop', 'running':'running', 'pauseReq':'pauseReq', 'paused':'paused'} self.logStatus = {'stop':'stop', 'running':'running', 'pauseReq':'pauseReq', 'paused':'paused'}
self.joinStatus = {'notstart':'idle', 'ongoing':'discover', 'succeed':'joined', 'failed':'failed'} self.joinStatus = {'notstart':'idle', 'ongoing':'discover', 'succeed':'joined', 'failed':'failed'}
self.logThreadStatus = self.logStatus['stop'] self.logThreadStatus = self.logStatus['stop']
self.connectType = (kwargs.get('Param5')).strip().lower() if kwargs.get('Param5') is not None else 'usb'
if self.connectType == 'ip':
self.dutIpv4 = kwargs.get('TelnetIP')
self.dutPort = kwargs.get('TelnetPort')
self.port = self.dutIpv4 + ':' + self.dutPort
else:
self.port = kwargs.get('SerialPort')
self.intialize() self.intialize()
except Exception, e: except Exception, e:
ModuleHelper.WriteIntoDebugLogger('initialize() Error: ' + str(e)) ModuleHelper.WriteIntoDebugLogger('initialize() Error: ' + str(e))
@@ -119,9 +126,6 @@ class OpenThread_WpanCtl(IThci):
if self._is_net: if self._is_net:
return self.handle.recv(size) return self.handle.recv(size)
else: else:
#read_data = self.handle.read(size)
#print "read_data : %s" % read_data
#return read_data
return self.handle.read(size) return self.handle.read(size)
def _write(self, data): def _write(self, data):
@@ -192,14 +196,20 @@ class OpenThread_WpanCtl(IThci):
while self.logThreadStatus != self.logStatus['paused'] and self.logThreadStatus != self.logStatus['stop']: while self.logThreadStatus != self.logStatus['paused'] and self.logThreadStatus != self.logStatus['stop']:
pass pass
ssh_stdin = None
ssh_stdout = None
ssh_stderr = None
try: try:
# command retransmit times # command retransmit times
retry_times = 3 retry_times = 3
while retry_times > 0: while retry_times > 0:
retry_times -= 1 retry_times -= 1
try: try:
self._sendline(cmd) if self._is_net:
self._expect(cmd) ssh_stdin, ssh_stdout, ssh_stderr = self.handle.exec_command(cmd)
else:
self._sendline(cmd)
self._expect(cmd)
except Exception as e: except Exception as e:
logging.exception('%s: failed to send command[%s]: %s', self.port, cmd, str(e)) logging.exception('%s: failed to send command[%s]: %s', self.port, cmd, str(e))
if retry_times == 0: if retry_times == 0:
@@ -210,28 +220,53 @@ class OpenThread_WpanCtl(IThci):
line = None line = None
response = [] response = []
retry_times = 10 retry_times = 10
while retry_times > 0: stdout_lines = []
line = self._readline() stderr_lines = []
print "read line: %s" % line if self._is_net:
logging.info('%s: the read line is[%s]', self.port, line) stdout_lines = ssh_stdout.readlines()
if line: stderr_lines = ssh_stderr.readlines()
response.append(line) if stderr_lines:
print "response: %s" % response for stderr_line in stderr_lines:
if re.match(WPAN_CARRIER_PROMPT, line): if re.search(r'Not\s+Found|failed\s+with\s+error', stderr_line.strip(), re.M | re.I):
break print "Command failed:" + stderr_line
elif re.search(r'Not\s+Found|failed\s+with\s+error', line, re.M|re.I): return 'Fail'
print "Command failed" print "Got line: " + stderr_line
return 'Fail' logging.info('%s: the read line is[%s]', self.port, stderr_line)
response.append(str(stderr_line.strip()))
elif stdout_lines:
for stdout_line in stdout_lines:
logging.info('%s: the read line is[%s]', self.port, stdout_line)
if re.search(r'Not\s+Found|failed\s+with\s+error', stdout_line.strip(), re.M | re.I):
print "Command failed"
return 'Fail'
print "Got line: " + stdout_line
logging.info('%s: send command[%s] done!', self.port, cmd)
response.append(str(stdout_line.strip()))
response.append(WPAN_CARRIER_PROMPT)
return response
else:
while retry_times > 0:
line = self._readline()
print "read line: %s" % line
logging.info('%s: the read line is[%s]', self.port, line)
if line:
response.append(line)
print "response: %s" % response
if re.match(WPAN_CARRIER_PROMPT, line):
break
elif re.search(r'Not\s+Found|failed\s+with\s+error', line, re.M | re.I):
print "Command failed"
return 'Fail'
else:
retry_times -= 1
time.sleep(0.1)
else: else:
retry_times -= 1 retry_times -= 1
time.sleep(0.1) time.sleep(1)
else: if not re.match(WPAN_CARRIER_PROMPT, line):
retry_times -= 1 raise Exception('%s: failed to find end of response' % self.port)
time.sleep(1) logging.info('%s: send command[%s] done!', self.port, cmd)
if not re.match(WPAN_CARRIER_PROMPT, line): return response
raise Exception('%s: failed to find end of response' % self.port)
logging.info('%s: send command[%s] done!', self.port, cmd)
return response
except Exception, e: except Exception, e:
ModuleHelper.WriteIntoDebugLogger('sendCommand() Error: ' + str(e)) ModuleHelper.WriteIntoDebugLogger('sendCommand() Error: ' + str(e))
raise raise
@@ -698,8 +733,8 @@ class OpenThread_WpanCtl(IThci):
return self.__sendCommand(WPANCTL_CMD + 'getprop -v Commissioner:SessionId')[0] return self.__sendCommand(WPANCTL_CMD + 'getprop -v Commissioner:SessionId')[0]
def _connect(self): def _connect(self):
print 'My port is %s' % self.port if self.connectType == 'usb':
if self.port.startswith('COM'): print 'My port is %s' % self.port
self.handle = serial.Serial(self.port, 115200, timeout=0.1) self.handle = serial.Serial(self.port, 115200, timeout=0.1)
input_data = self.handle.read(self.handle.inWaiting()) input_data = self.handle.read(self.handle.inWaiting())
if not input_data: if not input_data:
@@ -717,11 +752,16 @@ class OpenThread_WpanCtl(IThci):
time.sleep(3) time.sleep(3)
self._is_net = False self._is_net = False
elif ':' in self.port: elif self.connectType == 'ip':
host, port = self.port.split(':') print "My IP: %s Port: %s" % (self.dutIpv4, self.dutPort)
self.handle = socket.create_connection((host, port)) try:
self.handle.setblocking(0) self.handle = paramiko.SSHClient()
self._is_net = True self.handle.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.handle.connect(self.dutIpv4, port=self.dutPort, username=WPAN_CARRIER_USER, password=WPAN_CARRIER_PASSWD)
self.handle.exec_command("stty cols 128")
self._is_net = True
except Exception as e:
ModuleHelper.WriteIntoDebugLogger('connect to ssh Error: ' + str(e))
else: else:
raise Exception('Unknown port schema') raise Exception('Unknown port schema')
self.UIStatusMsg = self.getVersionNumber() self.UIStatusMsg = self.getVersionNumber()
@@ -1306,11 +1346,15 @@ class OpenThread_WpanCtl(IThci):
"""factory reset""" """factory reset"""
print '%s call reset' % self.port print '%s call reset' % self.port
try: try:
self._sendline(WPANCTL_CMD + 'leave') if self._is_net:
self.__sendCommand(WPANCTL_CMD + 'leave')
else:
self._sendline(WPANCTL_CMD + 'leave')
self.__sendCommand(WPANCTL_CMD + 'dataset erase') self.__sendCommand(WPANCTL_CMD + 'dataset erase')
time.sleep(2) time.sleep(2)
self._read() if not self._is_net:
self._read()
except Exception, e: except Exception, e:
ModuleHelper.WriteIntoDebugLogger('reset() Error: ' + str(e)) ModuleHelper.WriteIntoDebugLogger('reset() Error: ' + str(e))
+24
View File
@@ -57,3 +57,27 @@ Alternatively, platform developers may follow the instructions below to add a ne
9. Drag the "OpenThread_WpanCtl: Wpantund + NCP" reference device to the **Test Bed** section with the desired number. 9. Drag the "OpenThread_WpanCtl: Wpantund + NCP" reference device to the **Test Bed** section with the desired number.
10. Select one or more test cases to execute. 10. Select one or more test cases to execute.
The above is for the serial connection mode between the DUT and the Host PC. The ssh connection mode is
also supported for OpenThread WpanCtl, but it can not be auto-discovered and only can be used via ‘Drag and Add’ way
in the ‘Configure Test Bed’ Page of Test Harness. The configuration is as following:
1. Make Raspberry Pi and Host PC in the same LAN.
2. Login Raspberry Pi, sudo raspi-config, then -> interfacing options -> enable ssh.
3. Install python paramiko package to `C:\GRL\Pyton2.7`
4. Copy "OpenThread_WpanCtl.png" to `C:\GRL\Thread1.1\Web\images`.
5. Copy "deviceInputFields.xml" to `C:\GRL\Thread1.1\Web\data`.
6. Copy "OpenThread_WpanCtl.py" to `C:\GRL\Thread1.1\Thread_Harness\THCI`.
7. Launch the Thread Test Harness Software, modify the default configuration if needed, and select **Start**.
8. Drag the "OpenThread_WpanCtl: Wpantund + NCP (SSH)" reference device to the **Test Bed** section with the desired number.
Then fill in the Raspberry Pi IPv4 address and port and click `connect` icon button to get the NCP version.
9. Select one or more test cases to execute.
+18 -1
View File
@@ -76,7 +76,7 @@
hint="eg: 115200">115200 hint="eg: 115200">115200
</ITEM> </ITEM>
</DEVICE> </DEVICE>
<DEVICE name="OpenThread_WpanCtl" thumbnail="OpenThread.png" description = "OpenThread_WpanCtl: wpantund + NCP" THCI="OpenThread_WpanCtl"> <DEVICE name="OpenThread_WpanCtl" thumbnail="OpenThread_WpanCtl.png" description = "OpenThread_WpanCtl: Wpantund + NCP" THCI="OpenThread_WpanCtl">
<ITEM label="Serial Line" <ITEM label="Serial Line"
type="text" type="text"
forParam="SerialPort" forParam="SerialPort"
@@ -90,4 +90,21 @@
hint="eg: 115200">115200 hint="eg: 115200">115200
</ITEM> </ITEM>
</DEVICE> </DEVICE>
<DEVICE name="OpenThread_WpanCtl_SSH" thumbnail="OpenThread_WpanCtl.png" description = "OpenThread_WpanCtl: Wpantund + NCP (SSH)" THCI="OpenThread_WpanCtl">
<ITEM label="IP addr"
type="text"
forParam="TelnetIP"
validation="ipv4"
hint="eg: 192.168.1.111">192.168.1.100
</ITEM>
<ITEM label="PORT"
type="text"
forParam="TelnetPort"
validation="port"
hint="eg: 4901">22
</ITEM>
<ITEM type="hidden" label = ""
forParam="Param5">ip
</ITEM>
</DEVICE>
</DEVICE_FIELDS> </DEVICE_FIELDS>