Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ Let's say we want change ```serial_port```'s value to other COM port. For exampl
To do so we would have to create a new file called ```mbedls.json``` in directory where want to use this modification. File content could look like this: a JSON file where keys are ```target_id```'s and values are dictionaries with new values:

```
$ cat mbedls.ls
$ cat mbedls.json
{
"0240022648cb1e77000000000000000000000000b512e3cf" : {
"serial_port" : "MyComPort01"
Expand All @@ -461,24 +461,21 @@ $ mbedls

# Mocking new or existing target to custom platform name
Command line switch ```--mock``` provide simple manufacturers ID masking with new platform name.
Users should be able to add locally new ```MID``` -> ```platform_name``` mapping when e.g. prototyping.
Users should be able to add temporarily new ```MID``` -> ```platform_name``` mapping when e.g. prototyping.

Mock configuration will be stored in directory where ```mbedls --mock``` command was issues, in local file ```.mbedls-mock```.
Mock configuration will be stored in `$HOME/.mbed-ls/` directory, in local file ```.mbedls-mock```.

**Note***: ```MID```: "manufacturers ID", first 4 characters of ```target_id```. Example: If ```target_id``` is ```02400221A0811E505D5FE3E8```, corresponding manufacturers ID is ```0240```.
**Note***: ```MID``` stands for "manufacturers ID". `MID` is first four (4) characters of ```target_id``` string. Example: If ```target_id``` is ```02400221A0811E505D5FE3E8```, corresponding manufacturers ID is ```0240```.

## Mock command line examples
* Add new command line parameter ```--mock``` (switch -m)
* Add new / mask existing mapping ```MID``` -> ```platform_name``` and assign MID
* Mock command line parameter: `--mock` or (switch `-m`)
* Add new / mask existing mapping ```MID``` -> ```platform_name``` and assign `MID`:
* ```$ mbedls --mock MID:PLATFORM_NAME``` or
* ```$ mbedls --mock MID1:PLATFORM_NAME1,MID2:PLATFORM_NAME2```
* Mask existing manufacturers ID with new platform name
* Remove masking with '!' prefix
* ```$ mbedls --mock !MID```
* Remove all maskings using !* notation
* ```$ mbedls --mock !*```
* Combine above using comma (```,```) separator:
* ```$ mbedls --mock MID1:PLATFORM_NAME1,!MID2```
* Example: `$ mbedls --mock 0818:NUCLEO_F767ZI`
* Remove masking with '!' prefix: `$ mbedls --mock !MID`
* Remove all maskings using !* notation: `$ mbedls --mock !*`
* Combine above using comma (`,`) separator: `$ mbedls --mock MID1:PLATFORM_NAME1,!MID2`

## Mocking example with Freescale K64F platform
Initial setup with 1 x Freescale ```K64F``` board:
Expand Down Expand Up @@ -513,7 +510,7 @@ $ mbedls
+--------------+---------------------+------------+------------+-------------------------+
```

* We can remove mapping ```1234``` -> Anythying using ```!``` wildcard.
* We can remove mapping ```1234``` -> Anythying using ```!``` wild-card.
Note: We are using flag ```-json``` to get JSON format output of the ```--mock``` operation.
```
$ mbedls --mock !1234 --json
Expand All @@ -539,7 +536,7 @@ $ mbedls --mock !*

We can verify our mapping is reset:
```
$ cat .mbedls-mock
$ cat $HOME/.mbed-ls/.mbedls-mock
{}
```

Expand Down
119 changes: 76 additions & 43 deletions mbed_lstools/lstools_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@

import re
import os
from os.path import expanduser
import json
import lockfile
from os import listdir
from os.path import isfile, join
from lockfile import LockFailed

class MbedLsToolsBase:
""" Base class for mbed-lstools, defines mbed-ls tools interface for mbed-enabled devices detection for various hosts
Expand All @@ -38,6 +41,9 @@ def __init__(self):
for mid in mock_ids:
self.manufacture_ids[mid] = mock_ids[mid]

# Create in HOME directory place for mbed-ls to store information
self.mbedls_home_dir_init()

# Which OSs are supported by this module
# Note: more than one OS can be supported by mbed-lstools_* module
os_supported = []
Expand Down Expand Up @@ -190,11 +196,27 @@ def __init__(self):
"RIOT": "RIOT",
}

# Directory where we will store global (OS user specific mocking)
HOME_DIR = expanduser("~")
MBEDLS_HOME_DIR = '.mbed-ls'
MOCK_FILE_NAME = '.mbedls-mock'
MBEDLS_GLOBAL_LOCK = 'mbedls-lock'
MOCK_HOME_FILE_NAME = os.path.join(HOME_DIR, MBEDLS_HOME_DIR, MOCK_FILE_NAME)
RETARGET_FILE_NAME = 'mbedls.json'
DETAILS_TXT_NAME = 'DETAILS.TXT'
MBED_HTM_NAME = 'mbed.htm'

def mbedls_home_dir_init(self):
""" Initialize data in home directory for locking features
"""
if not os.path.isdir(os.path.join(self.HOME_DIR, self.MBEDLS_HOME_DIR)):
os.mkdir(os.path.join(self.HOME_DIR, self.MBEDLS_HOME_DIR))

def mbedls_get_global_lock(self):
file_path = os.path.join(self.HOME_DIR, self.MBEDLS_HOME_DIR, self.MBEDLS_GLOBAL_LOCK)
lock = lockfile.LockFile(file_path)
return lock

def list_manufacture_ids(self):
from prettytable import PrettyTable

Expand All @@ -213,43 +235,65 @@ def mock_read(self):
"""! Load mocking data from local file
@return Curent mocking configuration (dictionary)
"""
if isfile(self.MOCK_FILE_NAME):
if self.DEBUG_FLAG:
self.debug(self.mock_read.__name__, "reading mock file %s"% self.MOCK_FILE_NAME)

def read_mock_file(filename):
self.debug(self.mock_read.__name__, "reading mock file '%s'"% filename)
try:
with open(self.MOCK_FILE_NAME, "r") as f:
with open(filename, "r") as f:
return json.load(f)
except IOError as e:
self.err("reading file '%s' failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
self.err("reading file '%s' failed: %s"% (os.path.abspath(filename),
str(e)))
except ValueError as e:
self.err("reading file '%s' content failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
self.err("reading file '%s' content failed: %s"% (os.path.abspath(filename),
str(e)))
return {}

try:
with self.mbedls_get_global_lock():
# This read is for backward compatibility
# When user already have on its system local mock-up it will work
# overwriting global one
if isfile(self.MOCK_FILE_NAME):
return read_mock_file(self.MOCK_FILE_NAME)

if isfile(self.MOCK_HOME_FILE_NAME):
return read_mock_file(self.MOCK_HOME_FILE_NAME)
except LockFailed as e:
self.err(str(e))
return {}

def mock_write(self, mock_ids):
"""! Write current mocking structure
@param mock_ids JSON mock data to dump to file
"""
if self.DEBUG_FLAG:
self.debug(self.mock_write.__name__, "writing %s"% self.MOCK_FILE_NAME)
def write_mock_file(filename, mock_ids):
self.debug(self.mock_write.__name__, "writing mock file '%s'"% filename)
try:
with open(filename, "w") as f:
f.write(json.dumps(mock_ids, indent=4))
return True
except IOError as e:
self.err("writing file '%s' failed: %s"% (os.path.abspath(filename),
str(e)))
except ValueError as e:
self.err("writing file '%s' content failed: %s"% (os.path.abspath(filename),
str(e)))
return False

try:
with open(self.MOCK_FILE_NAME, "w") as f:
f.write(json.dumps(mock_ids, indent=4))
except IOError as e:
self.err("reading file '%s' failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
str(e)))
except ValueError as e:
self.err("reading file '%s' content failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
str(e)))
with self.mbedls_get_global_lock():
return write_mock_file(self.MOCK_HOME_FILE_NAME, mock_ids)
except LockFailed as e:
self.err(str(e))
return False

def retarget_read(self):
"""! Load retarget data from local file
@return Curent retarget configuration (dictionary)
"""
if os.path.isfile(self.RETARGET_FILE_NAME):
if self.DEBUG_FLAG:
self.debug(self.retarget_read.__name__, "reading retarget file %s"% self.RETARGET_FILE_NAME)
self.debug(self.retarget_read.__name__, "reading retarget file %s"% self.RETARGET_FILE_NAME)
try:
with open(self.RETARGET_FILE_NAME, "r") as f:
return json.load(f)
Expand Down Expand Up @@ -278,17 +322,14 @@ def mock_manufacture_ids(self, mid, platform_name, oper='+'):
# Operations on mocked structure
if oper == '+':
mock_ids[mid] = platform_name
if self.DEBUG_FLAG:
self.debug(self.mock_manufacture_ids.__name__, "mock_ids['%s'] = '%s'"% (mid, platform_name))
self.debug(self.mock_manufacture_ids.__name__, "mock_ids['%s'] = '%s'"% (mid, platform_name))
elif oper in ['-', '!']:
if mid in mock_ids:
mock_ids.pop(mid)
if self.DEBUG_FLAG:
self.debug(self.mock_manufacture_ids.__name__, "removing '%s' mock"% mid)
self.debug(self.mock_manufacture_ids.__name__, "removing '%s' mock"% mid)
elif mid == '*':
mock_ids = {} # Zero mocking set
if self.DEBUG_FLAG:
self.debug(self.mock_manufacture_ids.__name__, "zero mocking set")
self.debug(self.mock_manufacture_ids.__name__, "zero mocking set")

self.mock_write(mock_ids)
return mock_ids
Expand Down Expand Up @@ -335,8 +376,7 @@ def list_mbeds_ext(self):
target_id = val['target_id']
if target_id in self.retarget_data:
mbeds[i].update(self.retarget_data[target_id])
if self.DEBUG_FLAG:
self.debug(self.list_mbeds_ext.__name__, ("retargeting", target_id, mbeds[i]))
self.debug(self.list_mbeds_ext.__name__, ("retargeting", target_id, mbeds[i]))

# Add interface chip meta data to mbed structure
details_txt = self.get_details_txt(val['mount_point'])
Expand All @@ -353,8 +393,7 @@ def list_mbeds_ext(self):
if field_name not in mbeds[i]:
mbeds[i][field_name] = mbed_htm[field]

if self.DEBUG_FLAG:
self.debug(self.list_mbeds_ext.__name__, (mbeds[i]['platform_name_unique'], val['target_id']))
self.debug(self.list_mbeds_ext.__name__, (mbeds[i]['platform_name_unique'], val['target_id']))
return mbeds

def list_platforms(self):
Expand Down Expand Up @@ -416,7 +455,8 @@ def debug(self, name, text):
@param text Text to be included in debug message
@details Function prints directly on console
"""
print 'debug @%s.%s: %s'% (self.__class__.__name__, name, text)
if self.DEBUG_FLAG:
print 'debug @%s.%s: %s'% (self.__class__.__name__, name, text)

def __str__(self):
"""! Object to string casting
Expand Down Expand Up @@ -538,11 +578,9 @@ def get_mbed_htm_lines(self, mount_point):
with open(mbed_htm_path, 'r') as f:
result = f.readlines()
except IOError:
if self.DEBUG_FLAG:
self.debug(self.get_mbed_htm_target_id.__name__, ('Failed to open file', mbed_htm_path))
self.debug(self.get_mbed_htm_target_id.__name__, ('Failed to open file', mbed_htm_path))
except OSError:
if self.DEBUG_FLAG:
self.debug(self.get_mbed_htm_target_id.__name__, ('Failed to list mount point', mount_point))
self.debug(self.get_mbed_htm_target_id.__name__, ('Failed to list mount point', mount_point))

return result

Expand Down Expand Up @@ -576,8 +614,7 @@ def get_details_txt(self, mount_point):
with open(path_to_details_txt, 'r') as f:
result = self.parse_details_txt(f.readlines())
except IOError:
if self.DEBUG_FLAG:
self.debug(self.get_mbed_fw_version.get_details_txt.__name__, ('Failed to open file', path_to_details_txt))
self.debug(self.get_mbed_fw_version.get_details_txt.__name__, ('Failed to open file', path_to_details_txt))
return result if result else None

def parse_details_txt(self, lines):
Expand All @@ -603,20 +640,16 @@ def scan_html_line_for_target_id(self, line):
m = re.search('\?code=([a-fA-F0-9]+)', line)
if m:
result = m.groups()[0]
if self.DEBUG_FLAG:
self.debug(self.scan_html_line_for_target_id.__name__, line.strip())
if self.DEBUG_FLAG:
self.debug(self.scan_html_line_for_target_id.__name__, (m.groups(), result))
self.debug(self.scan_html_line_for_target_id.__name__, line.strip())
self.debug(self.scan_html_line_for_target_id.__name__, (m.groups(), result))
return result
# Last resort, we can try to see if old mbed.htm format is there
else:
m = re.search('\?auth=([a-fA-F0-9]+)', line)
if m:
result = m.groups()[0]
if self.DEBUG_FLAG:
self.debug(self.scan_html_line_for_target_id.__name__, line.strip())
if self.DEBUG_FLAG:
self.debug(self.scan_html_line_for_target_id.__name__, (m.groups(), result))
self.debug(self.scan_html_line_for_target_id.__name__, line.strip())
self.debug(self.scan_html_line_for_target_id.__name__, (m.groups(), result))
return result
return None

Expand Down
9 changes: 3 additions & 6 deletions mbed_lstools/lstools_linux_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ def get_dev_by_id_process(self, lines, retval):
line = line.rstrip()
if not line.lower().startswith('total '): # total 0
result.append(line)
if self.DEBUG_FLAG:
self.debug(self.get_dev_by_id_process.__name__, line)
self.debug(self.get_dev_by_id_process.__name__, line)
return result

def get_dev_by_id(self, subdir):
Expand All @@ -157,17 +156,15 @@ def get_mounts(self):
result = []
cmd = 'mount | grep vfat'

if self.DEBUG_FLAG:
self.debug(self.get_mounts.__name__, cmd)
self.debug(self.get_mounts.__name__, cmd)

_stdout, _, retval = self.run_cli_process(cmd)

if not retval:
for line in _stdout.splitlines():
line = line.rstrip()
result.append(line)
if self.DEBUG_FLAG:
self.debug(self.get_mounts.__name__, line)
self.debug(self.get_mounts.__name__, line)
return result

def get_disk_hex_ids(self, disk_list):
Expand Down
15 changes: 5 additions & 10 deletions mbed_lstools/lstools_win7.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ def get_mbed_com_port(self, tid):
self.winreg.Enum = self.winreg.OpenKey(self.winreg.HKEY_LOCAL_MACHINE, r'SYSTEM\CurrentControlSet\Enum')
usb_devs = self.winreg.OpenKey(self.winreg.Enum, 'USB')

if self.DEBUG_FLAG:
self.debug(self.get_mbed_com_port.__name__, 'ID: ' + tid)
self.debug(self.get_mbed_com_port.__name__, 'ID: ' + tid)

# first try to find all devs keys (by tid)
dev_keys = []
Expand All @@ -105,8 +104,7 @@ def get_mbed_com_port(self, tid):
try:
param = self.winreg.OpenKey(key, "Device Parameters")
port = self.winreg.QueryValueEx(param, 'PortName')[0]
if self.DEBUG_FLAG:
self.debug(self.get_mbed_com_port.__name__, port)
self.debug(self.get_mbed_com_port.__name__, port)
return port
except:
pass
Expand All @@ -122,8 +120,7 @@ def get_mbed_com_port(self, tid):
ports += [self.get_mbed_com_port(dev)]
for port in ports:
if port:
if self.DEBUG_FLAG:
self.debug(self.get_mbed_com_port.__name__, port)
self.debug(self.get_mbed_com_port.__name__, port)
return port
except:
pass
Expand All @@ -148,8 +145,7 @@ def get_mbeds(self):
# TargetID is a hex string with 10-48 chars
tid = re.search('[0-9A-Fa-f]{10,48}', mbed[1]).group(0)
mbeds += [(mountpoint, tid)]
if self.DEBUG_FLAG:
self.debug(self.get_mbeds.__name__, (mountpoint, tid))
self.debug(self.get_mbeds.__name__, (mountpoint, tid))
return mbeds

# =============================== Registry ====================================
Expand Down Expand Up @@ -183,8 +179,7 @@ def get_mbed_devices(self):
result += [d for d in self.get_dos_devices() if ven.upper() in d[1].upper()]

for r in result:
if self.DEBUG_FLAG:
self.debug(self.get_mbed_devices.__name__, r)
self.debug(self.get_mbed_devices.__name__, r)
return result

def get_dos_devices(self):
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ def read(fname):
"mbedls=mbed_lstools:mbedls_main",
],
},
install_requires=["PrettyTable>=0.7.2"])
install_requires=[
"PrettyTable>=0.7.2",
"lockfile"])