~webreg-fd/nfcpy/dev-lites

« back to all changes in this revision

Viewing changes to examples/npp-test-server.py

  • Committer: frank.dawidowsky at sony
  • Date: 2013-10-01 07:35:34 UTC
  • mfrom: (143.1.29 trunk)
  • Revision ID: frank.dawidowsky@eu.sony.com-20131001073534-69pu292zbyelihwx
merged with main branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
# -*- coding: latin-1 -*-
3
 
# -----------------------------------------------------------------------------
4
 
# Copyright 2011 Stephen Tiedemann <stephen.tiedemann@googlemail.com>
5
 
#
6
 
# Licensed under the EUPL, Version 1.1 or - as soon they 
7
 
# will be approved by the European Commission - subsequent
8
 
# versions of the EUPL (the "Licence");
9
 
# You may not use this work except in compliance with the
10
 
# Licence.
11
 
# You may obtain a copy of the Licence at:
12
 
#
13
 
# http://www.osor.eu/eupl
14
 
#
15
 
# Unless required by applicable law or agreed to in
16
 
# writing, software distributed under the Licence is
17
 
# distributed on an "AS IS" basis,
18
 
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
19
 
# express or implied.
20
 
# See the Licence for the specific language governing
21
 
# permissions and limitations under the Licence.
22
 
# -----------------------------------------------------------------------------
23
 
 
24
 
import logging
25
 
log = logging.getLogger()
26
 
 
27
 
import os
28
 
import sys
29
 
import time
30
 
import string
31
 
import threading
32
 
 
33
 
sys.path.insert(1, os.path.split(sys.path[0])[0])
34
 
import nfc
35
 
import nfc.npp
36
 
import nfc.ndef
37
 
 
38
 
terminate = threading.Event()
39
 
 
40
 
def make_printable(data):
41
 
    printable = string.digits + string.letters + string.punctuation + ' '
42
 
    return ''.join([c if c in printable else '.' for c in data])
43
 
 
44
 
def format_data(data):
45
 
    s = []
46
 
    for i in range(0, len(data), 16):
47
 
        s.append("  %04x: " % i)
48
 
        s[-1] += ' '.join(["%02x" % ord(c) for c in data[i:i+16]]) + ' '
49
 
        s[-1] += (8 + 16*3 - len(s[-1])) * ' '
50
 
        s[-1] += make_printable(data[i:i+16])
51
 
    return '\n'.join(s)
52
 
 
53
 
class NdefPushServer(nfc.npp.NPPServer):
54
 
    def __init__(self):
55
 
        super(NdefPushServer, self).__init__()
56
 
 
57
 
    def process(self, ndef_message_data):
58
 
        log.info("ndef push server got message")
59
 
        if options.binary:
60
 
            sys.stdout.write(ndef_message_data)
61
 
            sys.stdout.flush()
62
 
        else:
63
 
            print ndef_message_data.encode("hex")
64
 
        log.info(format_data(ndef_message_data))
65
 
        ndef_message = nfc.ndef.Message(ndef_message_data)
66
 
        log.info("NDEF records:")
67
 
        for index, record in enumerate(ndef_message):
68
 
            record_type = record.type
69
 
            record_name = record.name
70
 
            record_data = make_printable(record.data)
71
 
            log.info("  [%d] type = %s" %(index, record_type))
72
 
            log.info("  [%d] name = %s" %(index, record_name))
73
 
            log.info("  [%d] data = %s" %(index, record_data))
74
 
        if options.onemessage is True:
75
 
            terminate.set()
76
 
 
77
 
def main():
78
 
    llcp_config = {'recv-miu': options.link_miu, 'send-lto': 1000}
79
 
    if options.quirks == "android":
80
 
        llcp_config['send-agf'] = False
81
 
 
82
 
    for device in options.device:
83
 
        try: clf = nfc.ContactlessFrontend(device); break
84
 
        except LookupError: pass
85
 
    else: return
86
 
 
87
 
    try:
88
 
        while True:
89
 
            general_bytes = nfc.llcp.startup(llcp_config)
90
 
            peer = llcp_connect(clf, general_bytes)
91
 
            if peer is None: break
92
 
 
93
 
            nfc.llcp.activate(peer)
94
 
            try:
95
 
                ndef_push_server = NdefPushServer()
96
 
                ndef_push_server.start()
97
 
                while nfc.llcp.connected() and not terminate.is_set():
98
 
                    terminate.wait(1)
99
 
            except KeyboardInterrupt:
100
 
                log.info("aborted by user")
101
 
                break
102
 
            finally:
103
 
                nfc.llcp.shutdown()
104
 
                log.info("I was the " + peer.role)
105
 
                if options.loopmode is False:
106
 
                    break
107
 
    finally:
108
 
        clf.close()
109
 
 
110
 
def llcp_connect(clf, general_bytes):
111
 
    try:
112
 
        while True:
113
 
            if options.mode == "target" or options.mode is None:
114
 
                listen_time = 250 + ord(os.urandom(1))
115
 
                peer = clf.listen(listen_time, general_bytes)
116
 
                if isinstance(peer, nfc.DEP):
117
 
                    if peer.general_bytes.startswith("Ffm"):
118
 
                        return peer
119
 
            if options.mode == "initiator" or options.mode is None:
120
 
                peer = clf.poll(general_bytes)
121
 
                if isinstance(peer, nfc.DEP):
122
 
                    if peer.general_bytes.startswith("Ffm"):
123
 
                        if options.quirks == "android":
124
 
                            # Google Nexus S does not receive the first
125
 
                            # packet if we send immediately.
126
 
                            time.sleep(0.1)
127
 
                        return peer
128
 
    except KeyboardInterrupt:
129
 
        log.info("aborted by user")
130
 
 
131
 
if __name__ == '__main__':
132
 
    from optparse import OptionParser, OptionGroup
133
 
    usage = "Usage: %prog [options] > message.ndef"
134
 
    parser = OptionParser(usage)
135
 
    parser.add_option("-b", default=False,
136
 
                      action="store_true", dest="binary",
137
 
                      help="write binary ndef to stdout")
138
 
    parser.add_option("-1", default=False,
139
 
                      action="store_true", dest="onemessage",
140
 
                      help="terminate when an ndef message arrived")
141
 
    parser.add_option("-l", default=False,
142
 
                      action="store_true", dest="loopmode",
143
 
                      help="run in endless loop (Ctrl-C to abort)")
144
 
    parser.add_option("-q", default=True,
145
 
                      action="store_false", dest="verbose",
146
 
                      help="be quiet, only print errors")
147
 
    parser.add_option("-d", type="string", default=[],
148
 
                      action="append", dest="debug", metavar="MODULE",
149
 
                      help="print debug messages for MODULE")
150
 
    parser.add_option("-f", type="string",
151
 
                      action="store", dest="logfile",
152
 
                      help="write log messages to LOGFILE")
153
 
    parser.add_option("--device", type="string", default=[],
154
 
                      action="append", dest="device", metavar="SPEC",
155
 
                      help="use only device(s) according to SPEC: "\
156
 
                          "usb[:vendor[:product]] (vendor and product in hex) "\
157
 
                          "usb[:bus[:dev]] (bus and device number in decimal) "\
158
 
                          "tty[:(usb|com)[:port]] (usb virtual or com port)")
159
 
    parser.add_option("--mode", type="choice", default=None,
160
 
                      choices=["target", "initiator"],
161
 
                      action="store", dest="mode",
162
 
                      help="restrict mode to 'target' or 'initiator'")
163
 
    parser.add_option("--link-miu", type="int", default=1024,
164
 
                      action="store", dest="link_miu", metavar="MIU",
165
 
                      help="set maximum information unit size to MIU")
166
 
    parser.add_option("--quirks", type="string",
167
 
                      action="store", dest="quirks", metavar="choice",
168
 
                      help="quirks mode, choices are 'android'")
169
 
 
170
 
    global options
171
 
    options, args = parser.parse_args()
172
 
 
173
 
    verbosity = logging.INFO if options.verbose else logging.ERROR
174
 
    logging.basicConfig(level=verbosity, format='%(message)s')
175
 
 
176
 
    if options.logfile:
177
 
        logfile_format = '%(asctime)s %(levelname)-5s [%(name)s] %(message)s'
178
 
        logfile = logging.FileHandler(options.logfile, "w")
179
 
        logfile.setFormatter(logging.Formatter(logfile_format))
180
 
        logfile.setLevel(logging.DEBUG)
181
 
        logging.getLogger('').addHandler(logfile)
182
 
 
183
 
    import inspect, os, os.path
184
 
    nfcpy_path = os.path.dirname(inspect.getfile(nfc))
185
 
    for name in os.listdir(nfcpy_path):
186
 
        if os.path.isdir(os.path.join(nfcpy_path, name)):
187
 
            logging.getLogger("nfc."+name).setLevel(verbosity)
188
 
        elif name.endswith(".py") and name != "__init__.py":
189
 
            logging.getLogger("nfc."+name[:-3]).setLevel(verbosity)
190
 
            
191
 
    if options.debug:
192
 
        logging.getLogger('').setLevel(logging.DEBUG)
193
 
        logging.getLogger('nfc').setLevel(logging.DEBUG)
194
 
        for module in options.debug:
195
 
            log.info("enable debug output for module '{0}'".format(module))
196
 
            logging.getLogger(module).setLevel(logging.DEBUG)
197
 
 
198
 
    if len(options.device) == 0:
199
 
        # search and use first
200
 
        options.device = ["",]
201
 
        
202
 
    main()