summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Guiter <olivier.guiter@linux.intel.com>2013-09-02 12:32:18 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2013-09-02 15:56:28 +0200
commitb42a9e6b128c4928c37b91d38a6ca7d5fd52e10c (patch)
tree6df9ad4ef31a48f91b538c4df17fee5d92f3afa0
parent70062ada138de92fd70e85d1242c8f2df6dfe071 (diff)
downloadneard-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.am5
-rw-r--r--doc/phdc-api.txt80
-rwxr-xr-xtest/phdc-simple-manager193
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')