177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray#!/usr/bin/env python
277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray# Use of this source code is governed by a BSD-style license that can be
577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray# found in the LICENSE file.
677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
777486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayimport cmd
877486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayimport dbus
977486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayimport dbus.exceptions
1077486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayimport dbus.mainloop.glib
1177486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayimport gobject
1277486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayimport threading
1377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
1477486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayfrom functools import wraps
1577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
1677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
1777486dc43e91aea97510b3443d2c83b199768fbfArman UgurayDBUS_ERROR = 'org.freedesktop.DBus.Error'
1877486dc43e91aea97510b3443d2c83b199768fbfArman UgurayNEARD_PATH = '/org/neard/'
1977486dc43e91aea97510b3443d2c83b199768fbfArman UgurayPROMPT = 'NFC> '
2077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
2177486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayclass NfcClientException(Exception):
2277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """Exception class for exceptions thrown by NfcClient."""
2377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
2477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
2577486dc43e91aea97510b3443d2c83b199768fbfArman Uguraydef print_message(message, newlines=2):
2677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
2777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    Prints the given message with extra wrapping newline characters.
2877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
2977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @param message: Message to print.
3077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @param newlines: Integer, specifying the number of '\n' characters that
3177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            should be padded at the beginning and end of |message| before
3277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            being passed to "print".
3377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
3477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
3577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    padding = newlines * '\n'
3677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    message = padding + message + padding
3777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    print message
3877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
3977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
4077486dc43e91aea97510b3443d2c83b199768fbfArman Uguraydef handle_errors(func):
4177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
4277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    Decorator for handling exceptions that are commonly raised by many of the
4377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    methods in NfcClient.
4477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
4577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @param func: The function this decorator is wrapping.
4677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
4777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
4877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @wraps(func)
4977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _error_handler(*args):
5077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        try:
5177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return func(*args)
5277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        except dbus.exceptions.DBusException as e:
5377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if e.get_dbus_name() == DBUS_ERROR + '.ServiceUnknown':
5477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                print_message('neard may have crashed or disappeared. '
5577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                              'Check if neard is running and run "initialize" '
5677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                              'from this shell.')
5777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                return
5877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if e.get_dbus_name() == DBUS_ERROR + '.UnknownObject':
5977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                print_message('Could not find object.')
6077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                return
6177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message(str(e))
6277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        except Exception as e:
6377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message(str(e))
6477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    return _error_handler
6577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
6677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
6777486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayclass NfcClient(object):
6877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
6977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    neard D-Bus client
7077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
7177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
7277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    NEARD_SERVICE_NAME = 'org.neard'
7377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    IMANAGER = NEARD_SERVICE_NAME + '.Manager'
7477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    IADAPTER = NEARD_SERVICE_NAME + '.Adapter'
7577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    ITAG = NEARD_SERVICE_NAME + '.Tag'
7677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    IRECORD = NEARD_SERVICE_NAME + '.Record'
7777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    IDEVICE = NEARD_SERVICE_NAME + '.Device'
7877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
7977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def __init__(self):
8077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._mainloop = None
8177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._mainloop_thread = None
8277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._adapters = {}
8377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._adapter_property_handler_matches = {}
8477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
8577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def begin(self):
8677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
8777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Starts the D-Bus client.
8877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
8977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
9077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # Here we run a GLib MainLoop in its own thread, so that the client can
9177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # listen to D-Bus signals while keeping the console interactive.
9277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._dbusmainloop = dbus.mainloop.glib.DBusGMainLoop(
9377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                set_as_default=True)
9477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        dbus.mainloop.glib.threads_init()
9577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        gobject.threads_init()
9677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
9777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        def _mainloop_thread_func():
9877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self._mainloop = gobject.MainLoop()
9977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            context = self._mainloop.get_context()
10077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self._run_loop = True
10177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            while self._run_loop:
10277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                context.iteration(True)
10377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._mainloop_thread = threading.Thread(None, _mainloop_thread_func)
10477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._mainloop_thread.start()
10577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
10677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._bus = dbus.SystemBus()
10777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self.setup_manager()
10877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
10977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def end(self):
11077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
11177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Stops the D-Bus client.
11277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
11377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
11477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._run_loop = False
11577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._mainloop.quit()
11677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._mainloop_thread.join()
11777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
11877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def restart(self):
11977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Reinitializes the NFC client."""
12077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self.setup_manager()
12177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
12277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
12377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_manager_proxy(self):
12477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return dbus.Interface(
12577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self._bus.get_object(self.NEARD_SERVICE_NAME, '/'),
12677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self.IMANAGER)
12777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
12877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
12977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_adapter_proxy(self, adapter):
13077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return dbus.Interface(
13177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self._bus.get_object(self.NEARD_SERVICE_NAME, adapter),
13277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self.IADAPTER)
13377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
13477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_cached_adapter_proxy(self, adapter):
13577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy = self._adapters.get(adapter, None)
13677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not adapter_proxy:
13777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            raise NfcClientException('Adapter "' + adapter + '" not found.')
13877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return adapter_proxy
13977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
14077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
14177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
14277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_tag_proxy(self, tag):
14377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return dbus.Interface(
14477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self._bus.get_object(self.NEARD_SERVICE_NAME, tag),
14577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self.ITAG)
14677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
14777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
14877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_device_proxy(self, device):
14977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return dbus.Interface(
15077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self._bus.get_object(self.NEARD_SERVICE_NAME, device),
15177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self.IDEVICE)
15277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
15377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
15477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_record_proxy(self, record):
15577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return dbus.Interface(
15677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self._bus.get_object(self.NEARD_SERVICE_NAME, record),
15777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self.IRECORD)
15877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
15977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
16077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_adapter_properties(self, adapter):
16177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy = self._get_cached_adapter_proxy(adapter)
16277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return adapter_proxy.GetProperties()
16377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
16477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _get_adapters(self):
16577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        props = self._manager.GetProperties()
16677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return props.get('Adapters', None)
16777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
16877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def setup_manager(self):
16977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
17077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Creates a manager proxy and subscribes to adapter signals. This method
17177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        will also initialize proxies for adapters if any are available.
17277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
17377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
17477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # Create the manager proxy.
17577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._adapters.clear()
17677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._manager = self._get_manager_proxy()
17777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not self._manager:
17877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Failed to create a proxy to the Manager interface.')
17977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
18077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
18177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # Listen to the adapter added and removed signals.
18277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._manager.connect_to_signal(
18377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                'AdapterAdded',
18477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                lambda adapter: self.register_adapter(str(adapter)))
18577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._manager.connect_to_signal(
18677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                'AdapterRemoved',
18777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                lambda adapter: self.unregister_adapter(str(adapter)))
18877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
18977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # See if there are any adapters and create proxies for each.
19077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapters = self._get_adapters()
19177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if adapters:
19277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            for adapter in adapters:
19377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                self.register_adapter(adapter)
19477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
19577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def register_adapter(self, adapter):
19677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
19777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Registers an adapter proxy with the given object path and subscribes to
19877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter signals.
19977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
20077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param adapter: string, containing the adapter's D-Bus object path.
20177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
20277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
20377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Added adapter: ' + adapter)
20477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy = self._get_adapter_proxy(adapter)
20577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._adapters[adapter] = adapter_proxy
20677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
20777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # Tag found/lost currently don't get fired. Monitor property changes
20877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        # instead.
20977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if self._adapter_property_handler_matches.get(adapter, None) is None:
21077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self._adapter_property_handler_matches[adapter] = (
21177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                    adapter_proxy.connect_to_signal(
21277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                            'PropertyChanged',
21377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                            (lambda name, value:
21477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                                    self._adapter_property_changed_signal(
21577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                                            adapter, name, value))))
21677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
21777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def unregister_adapter(self, adapter):
21877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
21977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Removes the adapter proxy for the given object path from the internal
22077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        cache of adapters.
22177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
22277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param adapter: string, containing the adapter's D-Bus object path.
22377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
22477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
22577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Removed adapter: ' + adapter)
22677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        match = self._adapter_property_handler_matches.get(adapter, None)
22777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if match is not None:
22877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            match.remove()
22977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self._adapter_property_handler_matches.pop(adapter)
23077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._adapters.pop(adapter)
23177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
23277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _adapter_property_changed_signal(self, adapter, name, value):
23377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if name == 'Tags' or name == 'Devices':
23477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Found ' + name + ': ' +
23577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                          self._dbus_array_to_string(value))
23677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
23777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
23877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def show_adapters(self):
23977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
24077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Prints the D-Bus object paths of all adapters that are available.
24177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
24277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
24377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapters = self._get_adapters()
24477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not adapters:
24577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('No adapters found.')
24677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
24777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for adapter in adapters:
24877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('  ' + str(adapter), newlines=0)
24977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print
25077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
25177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _dbus_array_to_string(self, array):
25277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        string = '[ '
25377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for value in array:
25477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            string += ' ' + str(value) + ', '
25577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        string += ' ]'
25677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return string
25777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
25877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def print_adapter_status(self, adapter):
25977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
26077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Prints the properties of the given adapter.
26177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
26277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param adapter: string, containing the adapter's D-Bus object path.
26377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
26477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
26577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        props = self._get_adapter_properties(adapter)
26677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not props:
26777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
26877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Status ' + adapter + ': ', newlines=0)
26977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for key, value in props.iteritems():
27077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if type(value) == dbus.Array:
27177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                value = self._dbus_array_to_string(value)
27277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            else:
27377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                value = str(value)
27477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('  ' + key + ' = ' + value, newlines=0)
27577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print
27677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
27777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
27877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def set_powered(self, adapter, powered):
27977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
28077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Enables or disables the adapter.
28177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
28277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param adapter: string, containing the adapter's D-Bus object path.
28377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param powered: boolean that dictates whether the adapter will be
28477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                enabled or disabled.
28577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
28677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
28777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy = self._get_cached_adapter_proxy(adapter)
28877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not adapter_proxy:
28977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
29077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy.SetProperty('Powered', powered)
29177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
29277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
29377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def start_polling(self, adapter):
29477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
29577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Starts polling for nearby tags and devices in "Initiator" mode.
29677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
29777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param adapter: string, containing the adapter's D-Bus object path.
29877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
29977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
30077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy = self._get_cached_adapter_proxy(adapter)
30177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy.StartPollLoop('Initiator')
30277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Started polling.')
30377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
30477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
30577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def stop_polling(self, adapter):
30677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
30777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Stops polling for nearby tags and devices.
30877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
30977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param adapter: string, containing the adapter's D-Bus object path.
31077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
31177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
31277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy = self._get_cached_adapter_proxy(adapter)
31377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        adapter_proxy.StopPollLoop()
31477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._polling_stopped = True
31577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Stopped polling.')
31677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
31777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
31877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def show_tag_data(self, tag):
31977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
32077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Prints the properties of the given tag, as well as the contents of any
32177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        records associated with it.
32277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
32377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param tag: string, containing the tag's D-Bus object path.
32477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
32577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
32677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        tag_proxy = self._get_tag_proxy(tag)
32777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not tag_proxy:
32877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Tag "' + tag + '" not found.')
32977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
33077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        props = tag_proxy.GetProperties()
33177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Tag ' + tag + ': ', newlines=1)
33277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for key, value in props.iteritems():
33377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if key != 'Records':
33477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                print_message('  ' + key + ' = ' + str(value), newlines=0)
33577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        records = props['Records']
33677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not records:
33777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
33877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Records: ', newlines=1)
33977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for record in records:
34077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self.show_record_data(str(record))
34177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print
34277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
34377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
34477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def show_device_data(self, device):
34577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
34677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Prints the properties of the given device, as well as the contents of
34777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        any records associated with it.
34877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
34977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param device: string, containing the device's D-Bus object path.
35077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
35177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
35277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        device_proxy = self._get_device_proxy(device)
35377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not device_proxy:
35477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Device "' + device + '" not found.')
35577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
35677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        records = device_proxy.GetProperties()['Records']
35777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not records:
35877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('No records on device.')
35977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
36077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Records: ', newlines=1)
36177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for record in records:
36277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self.show_record_data(str(record))
36377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print
36477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
36577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
36677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def show_record_data(self, record):
36777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
36877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Prints the contents of the given record.
36977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
37077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param record: string, containing the record's D-Bus object path.
37177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
37277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
37377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        record_proxy = self._get_record_proxy(record)
37477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not record_proxy:
37577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Record "' + record + '" not found.')
37677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
37777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        props = record_proxy.GetProperties()
37877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Record ' + record + ': ', newlines=1)
37977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for key, value in props.iteritems():
38077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print '  ' + key + ' = ' + value
38177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print
38277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
38377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _create_record_data(self, record_type, params):
38477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if record_type == 'Text':
38577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            possible_keys = [ 'Encoding', 'Language', 'Representation' ]
38677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            tag_data = { 'Type': 'Text' }
38777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        elif record_type == 'URI':
38877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            possible_keys = [ 'URI' ]
38977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            tag_data = { 'Type': 'URI' }
39077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        else:
39177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Writing record type "' + record_type +
39277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                          '" currently not supported.')
39377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return None
39477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        for key, value in params.iteritems():
39577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if key in possible_keys:
39677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                tag_data[key] = value
39777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return tag_data
39877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
39977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
40077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def write_tag(self, tag, record_type, params):
40177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
40277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Writes an NDEF record to the given tag.
40377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
40477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param tag: string, containing the tag's D-Bus object path.
40577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param record_type: The type of the record, e.g. Text or URI.
40677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param params: dictionary, containing the parameters of the NDEF.
40777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
40877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
40977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        tag_data = self._create_record_data(record_type, params)
41077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not tag_data:
41177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
41277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        tag_proxy = self._get_tag_proxy(tag)
41377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not tag_proxy:
41477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Tag "' + tag + '" not found.')
41577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
41677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        tag_proxy.Write(tag_data)
41777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Tag written!')
41877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
41977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    @handle_errors
42077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def push_to_device(self, device, record_type, params):
42177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
42277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Pushes an NDEF record to the given device.
42377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
42477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param device: string, containing the device's D-Bus object path.
42577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param record_type: The type of the record, e.g. Text or URI.
42677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param params: dictionary, containing the parameters of the NDEF.
42777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
42877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
42977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        record_data = self._create_record_data(record_type, params)
43077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not record_data:
43177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
43277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        device_proxy = self._get_device_proxy(device)
43377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not device_proxy:
43477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Device "' + device + '" not found.')
43577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
43677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        device_proxy.Push(record_data)
43777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('NDEF pushed to device!')
43877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
43977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
44077486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayclass NfcConsole(cmd.Cmd):
44177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
44277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    Interactive console to interact with the NFC daemon.
44377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
44477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """
44577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def __init__(self):
44677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        cmd.Cmd.__init__(self)
44777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self.prompt = PROMPT
44877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
44977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def begin(self):
45077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
45177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Starts the interactive shell.
45277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
45377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
45477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('NFC console! Run "help" for a list of commands.',
45577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      newlines=1)
45677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client = NfcClient()
45777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.begin()
45877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self.cmdloop()
45977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
46077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def can_exit(self):
46177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Override"""
46277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return True
46377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
46477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_initialize(self, args):
46577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "initialize"."""
46677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if args:
46777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Command "initialize" expects no arguments.')
46877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
46977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.restart()
47077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
47177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_initialize(self):
47277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "initialize"."""
47377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Initializes the neard D-Bus client. This can be '
47477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      'run many times to restart the client in case of '
47577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      'neard failures or crashes.')
47677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
47777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_adapters(self, args):
47877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "adapters"."""
47977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if args:
48077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Command "adapters" expects no arguments.')
48177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
48277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.show_adapters()
48377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
48477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_adapters(self):
48577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "adapters"."""
48677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Displays the D-Bus object paths of the available '
48777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      'adapter objects.')
48877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
48977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_adapter_status(self, args):
49077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "adapter_status"."""
49177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
49277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
49377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: adapter_status <adapter>')
49477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
49577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.print_adapter_status(NEARD_PATH + args[0])
49677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
49777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_adapter_status(self):
49877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "adapter_status"."""
49977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Returns the properties of the given NFC adapter.\n\n'
50077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      '    Ex: "adapter_status nfc0"')
50177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
50277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_enable_adapter(self, args):
50377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "enable_adapter"."""
50477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
50577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
50677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: enable_adapter <adapter>')
50777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
50877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.set_powered(NEARD_PATH + args[0], True)
50977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
51077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_enable_adapter(self):
51177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "enable_adapter"."""
51277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Powers up the adapter. Ex: "enable_adapter nfc0"')
51377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
51477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_disable_adapter(self, args):
51577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "disable_adapter"."""
51677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
51777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
51877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: disable_adapter <adapter>')
51977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
52077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.set_powered(NEARD_PATH + args[0], False)
52177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
52277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_disable_adapter(self):
52377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "disable_adapter"."""
52477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Powers down the adapter. Ex: "disable_adapter nfc0"')
52577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
52677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_start_poll(self, args):
52777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "start_poll"."""
52877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
52977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
53077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: start_poll <adapter>')
53177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
53277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.start_polling(NEARD_PATH + args[0])
53377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
53477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_start_poll(self):
53577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "start_poll"."""
53677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Initiates a poll loop.\n\n    Ex: "start_poll nfc0"')
53777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
53877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_stop_poll(self, args):
53977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "stop_poll"."""
54077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.split(' ')
54177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
54277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: stop_poll <adapter>')
54377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
54477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.stop_polling(NEARD_PATH + args[0])
54577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
54677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_stop_poll(self):
54777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "stop_poll"."""
54877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Stops a poll loop.\n\n    Ex: "stop_poll nfc0"')
54977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
55077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_read_tag(self, args):
55177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "read_tag"."""
55277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
55377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
55477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage read_tag <tag>')
55577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
55677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.show_tag_data(NEARD_PATH + args[0])
55777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
55877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_read_tag(self):
55977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "read_tag"."""
56077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Reads the contents of a tag.  Ex: read_tag nfc0/tag0')
56177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
56277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def _parse_record_args(self, record_type, args):
56377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if record_type == 'Text':
56477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if len(args) < 5:
56577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                print_message('Usage: write_tag <tag> Text <encoding> '
56677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                              '<language> <representation>')
56777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                return None
56877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if args[2] not in [ 'UTF-8', 'UTF-16' ]:
56977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                print_message('Encoding must be one of "UTF-8" or "UTF-16".')
57077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                return None
57177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return {
57277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                'Encoding': args[2],
57377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                'Language': args[3],
57477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                'Representation': ' '.join(args[4:])
57577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            }
57677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if record_type == 'URI':
57777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            if len(args) != 3:
57877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                print_message('Usage: write_tag <tag> URI <uri>')
57977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                return None
58077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return {
58177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                'URI': args[2]
58277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            }
58377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Only types "Text" and "URI" are supported by this '
58477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      'script.')
58577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return None
58677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
58777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_write_tag(self, args):
58877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "write_tag"."""
58977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
59077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) < 3:
59177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: write_tag <tag> [params]')
59277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
59377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        record_type = args[1]
59477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        params = self._parse_record_args(record_type, args)
59577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not params:
59677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
59777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.write_tag(NEARD_PATH + args[0],
59877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                                   record_type, params)
59977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
60077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_write_tag(self):
60177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "write_tag"."""
60277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Writes the given data to a tag. Usage:\n'
60377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      '  write_tag <tag> Text <encoding> <language> '
60477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      '<representation>\n  write_tag <tag> URI <uri>')
60577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
60677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_read_device(self, args):
60777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "read_device"."""
60877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
60977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) != 1 or not args[0]:
61077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage read_device <device>')
61177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
61277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.show_device_data(NEARD_PATH + args[0])
61377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
61477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_read_device(self):
61577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "read_device"."""
61677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Reads the contents of a device.  Ex: read_device '
61777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      'nfc0/device0')
61877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
61977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_push_to_device(self, args):
62077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles "push_to_device"."""
62177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        args = args.strip().split(' ')
62277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if len(args) < 3:
62377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Usage: push_to_device <device> [params]')
62477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
62577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        record_type = args[1]
62677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        params = self._parse_record_args(record_type, args)
62777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if not params:
62877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
62977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        self._nfc_client.push_to_device(NEARD_PATH + args[0],
63077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                                        record_type, params)
63177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
63277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_push_to_device(self):
63377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Prints the help message for "push_to_device"."""
63477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Pushes the given data to a device. Usage:\n'
63577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      '  push_to_device <device> Text <encoding> <language> '
63677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray                      '<representation>\n  push_to_device <device> URI <uri>')
63777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
63877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def do_exit(self, args):
63977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
64077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        Handles the 'exit' command.
64177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
64277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        @param args: Arguments to the command. Unused.
64377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
64477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """
64577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if args:
64677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Command "exit" expects no arguments.')
64777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return
64877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        resp = raw_input('Are you sure? (yes/no): ')
64977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if resp == 'yes':
65077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Goodbye!')
65177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            self._nfc_client.end()
65277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            return True
65377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        if resp != 'no':
65477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray            print_message('Did not understand: ' + resp)
65577486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        return False
65677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
65777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    def help_exit(self):
65877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        """Handles the 'help exit' command."""
65977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray        print_message('Exits the console.')
66077486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
66177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    do_EOF = do_exit
66277486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    help_EOF = help_exit
66377486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
66477486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
66577486dc43e91aea97510b3443d2c83b199768fbfArman Uguraydef main():
66677486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    """Main function."""
66777486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    NfcConsole().begin()
66877486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
66977486dc43e91aea97510b3443d2c83b199768fbfArman Uguray
67077486dc43e91aea97510b3443d2c83b199768fbfArman Ugurayif __name__ == '__main__':
67177486dc43e91aea97510b3443d2c83b199768fbfArman Uguray    main()
672