mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[thci] add SSH support for OpenThread wpanctl THCI (#3086)
This commit is contained in:
@@ -39,6 +39,7 @@ import logging
|
||||
from Queue import Queue
|
||||
|
||||
import serial
|
||||
import paramiko
|
||||
from IThci import IThci
|
||||
from GRLLibs.UtilityModules.Test import Thread_Device_Role, Device_Data_Requirement, MacType
|
||||
from GRLLibs.UtilityModules.enums import PlatformDiagnosticPacket_Direction, PlatformDiagnosticPacket_Type
|
||||
@@ -69,13 +70,19 @@ class OpenThread_WpanCtl(IThci):
|
||||
try:
|
||||
self.UIStatusMsg = ''
|
||||
self.mac = kwargs.get('EUI')
|
||||
self.port = kwargs.get('SerialPort')
|
||||
self.handle = None
|
||||
self.AutoDUTEnable = False
|
||||
self._is_net = False # whether device is through ser2net
|
||||
self.logStatus = {'stop':'stop', 'running':'running', 'pauseReq':'pauseReq', 'paused':'paused'}
|
||||
self.joinStatus = {'notstart':'idle', 'ongoing':'discover', 'succeed':'joined', 'failed':'failed'}
|
||||
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()
|
||||
except Exception, e:
|
||||
ModuleHelper.WriteIntoDebugLogger('initialize() Error: ' + str(e))
|
||||
@@ -119,9 +126,6 @@ class OpenThread_WpanCtl(IThci):
|
||||
if self._is_net:
|
||||
return self.handle.recv(size)
|
||||
else:
|
||||
#read_data = self.handle.read(size)
|
||||
#print "read_data : %s" % read_data
|
||||
#return read_data
|
||||
return self.handle.read(size)
|
||||
|
||||
def _write(self, data):
|
||||
@@ -192,14 +196,20 @@ class OpenThread_WpanCtl(IThci):
|
||||
while self.logThreadStatus != self.logStatus['paused'] and self.logThreadStatus != self.logStatus['stop']:
|
||||
pass
|
||||
|
||||
ssh_stdin = None
|
||||
ssh_stdout = None
|
||||
ssh_stderr = None
|
||||
try:
|
||||
# command retransmit times
|
||||
retry_times = 3
|
||||
while retry_times > 0:
|
||||
retry_times -= 1
|
||||
try:
|
||||
self._sendline(cmd)
|
||||
self._expect(cmd)
|
||||
if self._is_net:
|
||||
ssh_stdin, ssh_stdout, ssh_stderr = self.handle.exec_command(cmd)
|
||||
else:
|
||||
self._sendline(cmd)
|
||||
self._expect(cmd)
|
||||
except Exception as e:
|
||||
logging.exception('%s: failed to send command[%s]: %s', self.port, cmd, str(e))
|
||||
if retry_times == 0:
|
||||
@@ -210,28 +220,53 @@ class OpenThread_WpanCtl(IThci):
|
||||
line = None
|
||||
response = []
|
||||
retry_times = 10
|
||||
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'
|
||||
stdout_lines = []
|
||||
stderr_lines = []
|
||||
if self._is_net:
|
||||
stdout_lines = ssh_stdout.readlines()
|
||||
stderr_lines = ssh_stderr.readlines()
|
||||
if stderr_lines:
|
||||
for stderr_line in stderr_lines:
|
||||
if re.search(r'Not\s+Found|failed\s+with\s+error', stderr_line.strip(), re.M | re.I):
|
||||
print "Command failed:" + stderr_line
|
||||
return 'Fail'
|
||||
print "Got line: " + stderr_line
|
||||
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:
|
||||
retry_times -= 1
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
retry_times -= 1
|
||||
time.sleep(1)
|
||||
if not re.match(WPAN_CARRIER_PROMPT, line):
|
||||
raise Exception('%s: failed to find end of response' % self.port)
|
||||
logging.info('%s: send command[%s] done!', self.port, cmd)
|
||||
return response
|
||||
time.sleep(1)
|
||||
if not re.match(WPAN_CARRIER_PROMPT, line):
|
||||
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:
|
||||
ModuleHelper.WriteIntoDebugLogger('sendCommand() Error: ' + str(e))
|
||||
raise
|
||||
@@ -698,8 +733,8 @@ class OpenThread_WpanCtl(IThci):
|
||||
return self.__sendCommand(WPANCTL_CMD + 'getprop -v Commissioner:SessionId')[0]
|
||||
|
||||
def _connect(self):
|
||||
print 'My port is %s' % self.port
|
||||
if self.port.startswith('COM'):
|
||||
if self.connectType == 'usb':
|
||||
print 'My port is %s' % self.port
|
||||
self.handle = serial.Serial(self.port, 115200, timeout=0.1)
|
||||
input_data = self.handle.read(self.handle.inWaiting())
|
||||
if not input_data:
|
||||
@@ -717,11 +752,16 @@ class OpenThread_WpanCtl(IThci):
|
||||
time.sleep(3)
|
||||
self._is_net = False
|
||||
|
||||
elif ':' in self.port:
|
||||
host, port = self.port.split(':')
|
||||
self.handle = socket.create_connection((host, port))
|
||||
self.handle.setblocking(0)
|
||||
self._is_net = True
|
||||
elif self.connectType == 'ip':
|
||||
print "My IP: %s Port: %s" % (self.dutIpv4, self.dutPort)
|
||||
try:
|
||||
self.handle = paramiko.SSHClient()
|
||||
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:
|
||||
raise Exception('Unknown port schema')
|
||||
self.UIStatusMsg = self.getVersionNumber()
|
||||
@@ -1306,11 +1346,15 @@ class OpenThread_WpanCtl(IThci):
|
||||
"""factory reset"""
|
||||
print '%s call reset' % self.port
|
||||
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')
|
||||
time.sleep(2)
|
||||
self._read()
|
||||
|
||||
if not self._is_net:
|
||||
self._read()
|
||||
except Exception, e:
|
||||
ModuleHelper.WriteIntoDebugLogger('reset() Error: ' + str(e))
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
hint="eg: 115200">115200
|
||||
</ITEM>
|
||||
</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"
|
||||
type="text"
|
||||
forParam="SerialPort"
|
||||
@@ -90,4 +90,21 @@
|
||||
hint="eg: 115200">115200
|
||||
</ITEM>
|
||||
</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>
|
||||
|
||||
Reference in New Issue
Block a user