diff options
author | Olivier Guiter <olivier.guiter@linux.intel.com> | 2013-09-02 12:32:18 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-09-02 15:56:28 +0200 |
commit | b42a9e6b128c4928c37b91d38a6ca7d5fd52e10c (patch) | |
tree | 6df9ad4ef31a48f91b538c4df17fee5d92f3afa0 | |
parent | 70062ada138de92fd70e85d1242c8f2df6dfe071 (diff) | |
download | neard-b42a9e6b128c4928c37b91d38a6ca7d5fd52e10c.tar.gz neard-b42a9e6b128c4928c37b91d38a6ca7d5fd52e10c.tar.bz2 neard-b42a9e6b128c4928c37b91d38a6ca7d5fd52e10c.zip |
phdc: API documentation and sample code
This sample code publishes two phdc Managers, to validate the phdc
driver. It relies on nfcpy test code for simulating a phdc thermometer.
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | doc/phdc-api.txt | 80 | ||||
-rwxr-xr-x | test/phdc-simple-manager | 193 |
3 files changed, 276 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 175cf07..175c09c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,7 +72,7 @@ build_plugindir = $(plugindir) endif doc_files = doc/manager-api.txt doc/tag-api.txt doc/device-api.txt \ - doc/adapter-api.txt doc/agent-api.txt + doc/adapter-api.txt doc/agent-api.txt doc/phdc-api.txt EXTRA_DIST = src/genbuiltin $(doc_files) @@ -81,7 +81,8 @@ dist_man_MANS = doc/neard.8 doc/neard.conf.5 doc/nfctool.1 test_scripts = test/disable-adapter test/enable-adapter test/list-adapters \ test/dump-device test/dump-tag test/dump-record \ test/monitor-near test/start-poll test/stop-poll test/write-tag \ - test/push-device test/bt-handover test/handover-agent + test/push-device test/bt-handover test/handover-agent \ + test/phdc-simple-manager if TEST testdir = $(pkglibdir)/test diff --git a/doc/phdc-api.txt b/doc/phdc-api.txt new file mode 100644 index 0000000..1dc7983 --- /dev/null +++ b/doc/phdc-api.txt @@ -0,0 +1,80 @@ +PHDC hierarchy +============== +Service org.neard +Interface org.neard.PHDC +Object path / + +Methods void RegisterAgent(dict values) + + Register new PHDC agent. + + PHDC Manager or Agent implementations calls this + method in order to register themselves against neard. + PHDC Managers will be notified through their + NewConnection method of new PHDC Agents connections. + PHDC Agents will be nnotified through their + NewConnection method when a connection to a PHDC Manager + succeeded. + + Possible Errors: org.neard.Error.OutOfMemory + org.neard.Error.InvalidArguments + org.neard.Error.AlreadyExists + + void UnregisterAgent(object path, string role) + + Unregister an existing agent. + + Possible Errors: org.neard.Error.OutOfMemory + org.neard.Error.InvalidArguments + + +Fields string Role + + "Agent" or "Manager" (mandatory) + + object Path + + Agent or Manager path (mandatory) + + string ServiceName + + NFC urn to connect or to listen to + (default: "urn:nfc:sn:phdc"). + + +PHDC Manager hierarchy +====================== +Service unique name +Interface org.neard.PHDC.Manager +Object path freely definable + + +Methods: void NewConnection(fd agent) + + This method gets called when a PHDC Agent connects + using the p2p service name. The Phdc Manager uses + the given agent file descriptor to exchange data + with the Agent. + + void Disconnection(fd agent, error) + + This method is called when a PHDC Agent closes the + file descriptoer. + + void Release() + + This method is called when the service daemon + unregisters the agent. An agent can use it to do + cleanup tasks. + There is no need to unregister the agent, because + when this method gets called it has already been + unregistered. + + +PHDC Agent hierarchy +==================== +Service unique name +Interface org.neard.PHDC.Agent +Object path freely definable + +Methods: NOT YET IMPLEMENTED diff --git a/test/phdc-simple-manager b/test/phdc-simple-manager new file mode 100755 index 0000000..5317f25 --- /dev/null +++ b/test/phdc-simple-manager @@ -0,0 +1,193 @@ +#!/usr/bin/env python2.7 + +import sys +import dbus +import dbus.service +import dbus.glib +import gobject +import socket +import string +import struct +import threading +from threading import Thread +import time +from dbus.mainloop.glib import DBusGMainLoop + +# IDs specific to Linux nfc +AF_NFC = 39 +SOL_NFC = 280 +NFC_LLCP_MIUX = 1 + +# Sample test code - compliant with nfcpy phdc test agent +thermometer_assoc_req = \ + "E200 0032 8000 0000" \ + "0001 002A 5079 0026" \ + "8000 0000 A000 8000" \ + "0000 0000 0000 0080" \ + "0000 0008 3132 3334" \ + "3536 3738 0320 0001" \ + "0100 0000 0000" + +thermometer_assoc_res = \ + "E300 002C 0003 5079" \ + "0026 8000 0000 8000" \ + "8000 0000 0000 0000" \ + "8000 0000 0008 3837" \ + "3635 3433 3231 0000" \ + "0000 0000 0000 0000" \ + +assoc_release_req = "E40000020000" +assoc_release_res = "E50000020000" + +#======================================== +# Display helper +def hexdump( chars, sep, width ): + while chars: + line = chars[:width] + chars = chars[width:] + line = line.ljust( width, '\000' ) + print "%s%s%s" % ( sep.join( "%02x" % ord(c) for c in line ), + sep, quotechars( line )) + + +def quotechars( chars ): + return ''.join( ['.', c][c.isalnum()] for c in chars ) + +#======================================== +class PhdcPeerManager: + def __init__(self, agent_fd): + #Grab the agent .... + print 'Init PhdcPeerManager thread' + self.r_fd = agent_fd.take() + print 'Agent fd:', str(self.r_fd) + + def run( self): + print 'Run PhdcPeerManager thread: ', str(self.r_fd) + self.sock = socket.fromfd(self.r_fd, AF_NFC, socket.SOCK_STREAM) + try: + while True: + miu = self.sock.getsockopt(SOL_NFC, NFC_LLCP_MIUX) + print 'MIU=', miu + + while True: + data = self.sock.recv(16) + if data == None: + print 'no data' + break + + #analyze frame + print 'analyze' + size = struct.unpack(">H", data[0:2])[0] + apdu = data[2:] + + #should i read more data ? + while len(apdu) < size: + data = self.sock.recv(10) + if data == None: break + hexdump(data, ':', 16) + apdu += data + print "[ieee] <<< {0}".format(str(apdu).encode("hex")) + if apdu.startswith("\xE2\x00"): + apdu = bytearray.fromhex(thermometer_assoc_res) + elif apdu.startswith("\xE4\x00"): + apdu = bytearray.fromhex(assoc_release_res) + else: + apdu = apdu[::-1] + time.sleep(0.2) + print "[ieee] >>> {0}".format(str(apdu).encode("hex")) + data = struct.pack(">H", len(apdu)) + apdu + for i in range(0, len(data), miu): + self.sock.send(str(data[i:i+miu])) + + print "remote peer {0} closed connection".format(agent_fd) + print "leaving ieee manager" + self.sock.close() + + except IOError as e: + if e.errno == errno.EPIPE: + print 'Remote disconnect' + else: + print "I/O error({0}): {1}".format(e.errno, e.strerror) + finally: + print 'Finally exit' + stop() + + def stop(self): + print 'Stop PhdcPeerManager:', str(self.r_fd) + self._Thread__stop() + +#=================================================== +''' Phdc Manager Class +''' +class SimplePhdcManager(dbus.service.Object): + + @dbus.service.method('org.neard.PHDC.Manager', + in_signature='', + out_signature='') + def Release(self): + print 'Release' + mainloop.quit() + + + ''' Called on incoming agents + ''' + @dbus.service.method('org.neard.PHDC.Manager', + in_signature='h', + out_signature='') + def NewConnection(self, agent_fd): + print'Launch Phdc Manager thread for fd:', str(agent_fd) + self.server = PhdcPeerManager(agent_fd) + print'Run Server' + self.server.run() + print'Leave Server' + return + + ''' Called when the agent ends (from phdc_close) + ''' + @dbus.service.method('org.neard.PHDC.Manager', + in_signature='hi', out_signature='') + def Disconnection(self,agent_fd, i_err): + print'Stop Phdc Manager thread' + self.server.stop() + return + +''' Main loop +This sample installs two PHDC Managers: + * Simple: simulates a thermometer data exchange + * Validation: Validation Manager for NFC Forum PHDC) +''' +if "__main__" == __name__: + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + print 'PHDC Simple Manager Test' + bus = dbus.SystemBus() + neard_manager = dbus.Interface(bus.get_object('org.neard', '/'), + 'org.neard.PHDC') + + simple_path = '/Simple' + valid_path = '/Validation' + + print 'Creating & registering PHDC Simple Manager' + simpleobject = SimplePhdcManager(bus, simple_path) + + d = dbus.Dictionary({'Role': 'Manager', 'Path': simple_path, + 'ServiceName': 'urn:nfc:sn:phdc' }, signature='sv') + neard_manager.RegisterAgent(d) + + print 'Creating & Registering Validation Manager' + + validationobj= SimplePhdcManager(bus, valid_path) + d = dbus.Dictionary({'Role': 'Manager', 'Path': valid_path, + 'ServiceName': 'urn:nfc:xsn:nfc-forum.org:phdc-validation' }, + signature='sv') + neard_manager.RegisterAgent(d) + + mainloop = gobject.MainLoop() + +try: + mainloop.run() + +except(KeyboardInterrupt): + #Call for unregister... + neard_manager.UnregisterAgent(simple_path, 'Manager') + neard_manager.UnregisterAgent(valid_path, 'Manager') |