Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac OS X Support #1

Merged
merged 7 commits into from
Feb 20, 2015
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
159 changes: 159 additions & 0 deletions mbed_lstools/lstools_darwin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
"""
mbed SDK
Copyright (c) 2011-2015 ARM Limited

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import re
import subprocess
import plistlib

from lstools_base import MbedLsToolsBase

class MbedLsToolsDarwin(MbedLsToolsBase):
""" MbedLsToolsDarwin supports mbed-enabled platforms detection on Mac OS X
"""

mbed_volume_name_match = re.compile(r'\bmbed\b', re.I)

def list_mbeds(self):
""" returns mbed list with platform names if possible
"""

result = []

# {volume_id: {serial:, vendor_id:, product_id:, tty:}}
volumes = self.get_mbed_volumes()
#print 'volumes:', volumes

# {volume_id: mount_point}
mounts = self.get_mount_points()
#print "mounts:", mounts

# put together all of that info into the expected format:
result = [
{
'mount_point': mounts[v],
'serial_port': volumes[v]['tty'],
'target_id': self.target_id(volumes[v]),
'platform_name': self.platform_name(self.target_id(volumes[v]))
} for v in volumes
]

# if we're missing any platform names, try to fill those in by reading
# mbed.htm:
for m in result:
if m['mount_point'] and not m['platform_name']:
htm_target_id = self.get_mbed_htm_target_id(m['mount_point'])
if htm_target_id:
m['target_id'] = htm_target_id
m['platform_name'] = self.platform_name(htm_target_id[:4])

return result


def get_mount_points(self):
''' Returns map {volume_id: mount_point} '''

# list disks, this gives us disk name, and volume name + mount point:
diskutil_ls = subprocess.Popen(['diskutil', 'list', '-plist'], stdout=subprocess.PIPE)
disks = plistlib.readPlist(diskutil_ls.stdout)
diskutil_ls.wait()

r = {}

for disk in disks['AllDisksAndPartitions']:
mount_point = None
if 'MountPoint' in disk:
mount_point = disk['MountPoint']
r[disk['DeviceIdentifier']] = mount_point

return r


def get_mbed_volumes(self):
''' returns a map {volume_id: {serial:, vendor_id:, product_id:, tty:}'''

# to find all the possible mbed volumes, we look for registry entries
# under the USB bus which have a "BSD Name" that starts with "disk"
# (i.e. this is a USB disk), and have a IORegistryEntryName that
# matches /\cmbed/
# Once we've found a disk, we can search up for a parent with a valid
# serial number, and then search down again to find a tty that's part
# of the same composite device
# ioreg -a -r -n "AppleUSBXHCI" -l
ioreg_usb = subprocess.Popen(['ioreg', '-a', '-r', '-n', 'AppleUSBXHCI', '-l'], stdout=subprocess.PIPE)
usb_bus = plistlib.readPlist(ioreg_usb.stdout)
ioreg_usb.wait()

r = {}

def findTTYRecursive(obj):
''' return the first tty (AKA IODialinDevice) that we can find in the
children of the specified object, or None if no tty is present.
'''
if 'IODialinDevice' in obj:
return obj['IODialinDevice']
if 'IORegistryEntryChildren' in obj:
for child in obj['IORegistryEntryChildren']:
found = findTTYRecursive(child)
if found:
return found
return None

def findVolumesRecursive(obj, parents):
if 'BSD Name' in obj and obj['BSD Name'].startswith('disk') and \
self.mbed_volume_name_match.search(obj['IORegistryEntryName']):
disk_id = obj['BSD Name']
# now search up through our parents until we find a serial number:
usb_info = {
'serial':None,
'vendor_id':None,
'product_id':None,
'tty':None,
}
for parent in [obj] + parents:
if 'USB Serial Number' in parent:
usb_info['serial'] = parent['USB Serial Number']
if 'idVendor' in parent and 'idProduct' in parent:
usb_info['vendor_id'] = parent['idVendor']
usb_info['product_id'] = parent['idProduct']
if usb_info['serial']:
# stop at the first one we find (or we'll pick up hubs,
# etc.), but first check for a tty that's also a child of
# this device:
usb_info['tty'] = findTTYRecursive(parent)
break
r[disk_id] = usb_info
if 'IORegistryEntryChildren' in obj:
for child in obj['IORegistryEntryChildren']:
findVolumesRecursive(child, [obj] + parents)

for obj in usb_bus:
findVolumesRecursive(obj, [])

return r


def target_id(self, usb_info):
if usb_info['serial'] is not None:
return usb_info['serial']
else:
return None

def platform_name(self, target_id):
if target_id[:4] in self.manufacture_ids:
return self.manufacture_ids[target_id[:4]]


12 changes: 10 additions & 2 deletions mbed_lstools/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from lstools_win7 import MbedLsToolsWin7
from lstools_ubuntu import MbedLsToolsUbuntu
from lstools_darwin import MbedLsToolsDarwin


def create():
Expand All @@ -19,6 +20,7 @@ def create():
if mbed_os is not None:
if mbed_os == 'Windows7': result = MbedLsToolsWin7()
elif mbed_os == 'Ubuntu': result = MbedLsToolsUbuntu()
elif mbed_os == 'Darwin': result = MbedLsToolsDarwin()
return result

def mbed_os_support():
Expand All @@ -31,6 +33,8 @@ def mbed_os_support():
result = 'Windows7'
elif (os_info[0] == 'posix' and os_info[1] == 'Linux' and ('Ubuntu' in os_info[3])):
result = 'Ubuntu'
elif (os_info[0] == 'posix' and os_info[1] == 'Darwin'):
result = 'Darwin'
return result

def mbed_lstools_os_info():
Expand All @@ -52,13 +56,13 @@ def cmd_parser_setup():
dest='simple',
default=False,
action="store_true",
help='Pareser friendly verbose mode')
help='Parser friendly verbose mode')

parser.add_option('', '--json',
dest='json',
default=False,
action="store_true",
help='JSON formated output')
help='JSON formatted output')

(opts, args) = parser.parse_args()
return (opts, args)
Expand All @@ -71,6 +75,10 @@ def mbedls_main():
(opts, args) = cmd_parser_setup()
mbeds = create()

if mbeds is None:
sys.stderr.write('This platform is not supported! Pull requests welcome at github.com/ARMmbed/mbed-ls\n')
sys.exit(-1)

if opts.json:
mbeds_data = mbeds.list_mbeds()
print json.dumps(mbeds_data, indent=4, sort_keys=True)
Expand Down