Merge lp:~andrefcruz/nfcpy/npp-1.0 into lp:nfcpy

Proposed by André Cruz
Status: Merged
Merged at revision: 78
Proposed branch: lp:~andrefcruz/nfcpy/npp-1.0
Merge into: lp:nfcpy
Diff against target: 103 lines (+23/-13)
1 file modified
nfc/npp/server.py (+23/-13)
To merge this branch: bzr merge lp:~andrefcruz/nfcpy/npp-1.0
Reviewer Review Type Date Requested Status
Stephen Tiedemann Approve
Review via email: mp+64703@code.launchpad.net

Description of the change

I implemented the ability for the NPP server to run in single-threaded mode and be stopped by the return of the process() method.

In my scenario this is useful because I only want to receive a message, process it, and continue the program without the NPP server (the Android API only allows the phone to send 1 message per LLCP link establishment).

If you find this useful then merge...

To post a comment you must log in.
lp:~andrefcruz/nfcpy/npp-1.0 updated
75. By André Cruz

Support python 2.6.

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) wrote :

Andre, I wouldn't mind to make the NPP server single-threaded/single-connection *onyly*. As implemented in Android, it is always *one* system client that opens *one* connection to send NDEF data, An NPP server should actually never need to handle more than one connection at a time (in practice not even during the same session). And I don't think there will be much evolution of the NPP specification; I rather dare to predict a forthcoming Android release will support the NFC Forum way of getting NDEF across LLCP.

lp:~andrefcruz/nfcpy/npp-1.0 updated
76. By André Cruz

Make single-threaded the default behavior.

Revision history for this message
André Cruz (andrefcruz) wrote :

I agree, I made "single-thread" the default behavior. I didn't remove the multi-threaded code since someone may still find a use for it, if they decide to use the NPP protocol using only nfcpy and not Android devices.

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) wrote :

Merged to trunk with a few modifications:
- parameter in __init__ renamed 'threaded'
- set listen socket backlog to 0 for non-threaded operation
- rejected server termination by return value from process()
- added option for example npp server to terminate after receipt of one ndef message

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nfc/npp/server.py'
2--- nfc/npp/server.py 2011-06-15 08:40:42 +0000
3+++ nfc/npp/server.py 2011-06-23 13:55:11 +0000
4@@ -12,10 +12,11 @@
5 import nfc.llcp
6
7 class NPPServer(Thread):
8- """ Simple NPP server
9+ """ Simple NPP server. If single_threaded is True then a new thread will not be spawned.
10 """
11- def __init__(self):
12+ def __init__(self, single_threaded=True):
13 super(NPPServer, self).__init__()
14+ self.single_threaded = single_threaded
15
16 def run(self):
17 socket = nfc.llcp.socket(nfc.llcp.DATA_LINK_CONNECTION)
18@@ -27,9 +28,15 @@
19 nfc.llcp.listen(socket, backlog=2)
20 while True:
21 client_socket = nfc.llcp.accept(socket)
22- client_thread = Thread(target=NPPServer.serve,
23+ if self.single_threaded:
24+ log.debug("got client in single_threaded mode")
25+ if NPPServer.serve(client_socket, self):
26+ break
27+ else:
28+ log.debug("got client, will spawn thread")
29+ client_thread = Thread(target=NPPServer.serve,
30 args=[client_socket, self])
31- client_thread.start()
32+ client_thread.start()
33 except nfc.llcp.Error as e:
34 log.error(str(e))
35 finally:
36@@ -45,20 +52,20 @@
37 if data is None:
38 log.debug("connection closed, no data")
39 return
40-
41+
42 while nfc.llcp.poll(socket, "recv"):
43 data += nfc.llcp.recv(socket)
44
45- log.debug("got {:d} octets data".format(len(data)))
46+ log.debug("got {0:d} octets data".format(len(data)))
47 if len(data) < 10:
48 log.debug("npp msg initial fragment too short")
49 return # bail out, this is a bad client
50
51 version, num_entries = unpack(">BI", data[:5])
52- log.debug("version {:d}, {:d} entries"
53+ log.debug("version {0:d}, {1:d} entries"
54 .format(version, num_entries))
55 if (version >> 4) > 1:
56- log.debug("unsupported version {:d}".format(version>>4))
57+ log.debug("unsupported version {0:d}".format(version>>4))
58 return
59
60 if num_entries != 1:
61@@ -67,13 +74,13 @@
62
63 remaining = data[5:]
64 for i in range(num_entries):
65- log.debug("processing NDEF message #{:d}".format(i+1))
66+ log.debug("processing NDEF message #{0:d}".format(i+1))
67 if len(remaining) < 5:
68 log.debug("insufficient data for action code and ndef size")
69 return
70
71 action_code, length = unpack(">BI", remaining[:5])
72- log.debug("action code {:d}, ndef length {:d}"
73+ log.debug("action code {0:d}, ndef length {1:d}"
74 .format(action_code, length))
75
76 if action_code != 1:
77@@ -87,12 +94,14 @@
78
79 # message complete, now handle the request
80 ndef_message_data = remaining[:length]
81- log.debug("have complete ndef message, {:d} octets"
82+ log.debug("have complete ndef message, {0:d} octets"
83 .format(len(ndef_message_data)))
84- npp_server.process(ndef_message_data)
85+ if npp_server.process(ndef_message_data) and npp_server.single_threaded:
86+ return True
87
88 # prepare for next
89 remaining = remaining[length:]
90+ return
91
92 except nfc.llcp.Error as e:
93 log.debug("caught exception {0}".format(e))
94@@ -105,7 +114,8 @@
95 def process(self, ndef_message_data):
96 """Processes NDEF messages. This method should be overwritten by a
97 subclass of NPPServer to customize it's behavior. The default
98- implementation prints each record.
99+ implementation prints each record. If NPP server is single threaded
100+ and this method returns True, the server stops processing.
101 """
102 log.debug("ndef push server process message")
103 log.debug(ndef_message_data.encode("hex"))

Subscribers

People subscribed via source and target branches