nfc.snep

The nfc.snep module implements the NFC Forum Simple NDEF Exchange Protocol (SNEP) specification and provides a server and client class for applications to easily send or receive SNEP messages.

nfc.snep.SnepClient

class nfc.snep.SnepClient(llc, default_service_name='urn:nfc:sn:snep')

Bases: object

Simple NDEF exchange protocol - client implementation

connect(service_name=None)

Connect to a SNEP server. This needs only be called to connect to a server other than the Default SNEP Server at urn:nfc:sn:snep or if the client wants to send multiple requests with a single connection.

close()

Close the data link connection with the SNEP server.

get_records(records=None, acceptable_length=1024, timeout=1.0)

Get NDEF message records from a SNEP Server.

New in version 0.13.

The ndef.Record list given by records is encoded as the request message octets input to get_octets(). The return value is an ndef.Record list decoded from the response message octets returned by get_octets(). Same as:

import ndef
send_octets = ndef.message_encoder(records)
rcvd_octets = snep_client.get_octets(send_octets, timeout)
records = list(ndef.message_decoder(rcvd_octets))
get_octets(octets=None, acceptable_length=1024, timeout=1.0)

Get NDEF message octets from a SNEP Server.

New in version 0.13.

If the client has not yet a data link connection with a SNEP Server, it temporarily connects to the default SNEP Server, sends the message octets, disconnects after the server response, and returns the received message octets.

put_records(records, timeout=1.0)

Send NDEF message records to a SNEP Server.

New in version 0.13.

The ndef.Record list given by records is encoded and then send via put_octets(). Same as:

import ndef
octets = ndef.message_encoder(records)
snep_client.put_octets(octets, timeout)
put_octets(octets, timeout=1.0)

Send NDEF message octets to a SNEP Server.

New in version 0.13.

If the client has not yet a data link connection with a SNEP Server, it temporarily connects to the default SNEP Server, sends the message octets and disconnects after the server response.

nfc.snep.SnepServer

The SnepServer implemements protocol handling for the Simple NDEF Exchange Protocol (SNEP) Get and Put messages. An application must set callbacks for get_records or get_octets and put_records or put_octets to customize it’s behavior. The default implementation returns the SNEP “Not Implemented” response for Get requests and the SNEP “Success” response for Put requests. A SNEP Server instance must be created before and started during LLCP link establishment by the application.

import nfc
import ndef

def put_records(request_records):
    for record in request_records:
        print(record)

def get_records(request_records):
    if request_records and request_records[0].name == b'temperature':
        return [ndef.TextRecord('25.1')]
    else:
        raise nfc.snep.SnepError(nfc.snep.NotFound)

def on_startup(llc):
    snep_server = nfc.snep.SnepServer(llc)
    snep_server.set_callback(put_records=put_records)
    snep_server.set_callback(get_records=get_records)
    llc.private.snep_server = snep_server
    return llc

def on_connect(llc):
    llc.private.snep_server.start()
    return True

clf = nfc.ContactlessFrontend('udp::54321')
clf.connect(llcp={'on-startup': on_startup, 'on-connect': on_connect})

More control over the generated response data and processing of request data can be achieved with the get_octets and put_octets callback functions. For example, the get_octets callback receives an additional argument that indicates the maximum number of response data octets which the client is able to process. This may allow an advanced server implementation to return a shorter version of the requested information to a limited client.

def get_octets(request_octets, acceptable_length):
    request_records = list(ndef.message_decoder(request_octets))
    if request_records and request_records[0].name == 'temperature':
        text = '25.1' if acceptable_length <= 16 else 'Temperature is 25.1 degree'
        return b''.join(ndef.message_encoder([ndef.TextRecord(text)]))
    raise nfc.snep.SnepError(0xC0)  # Not Found

def put_octets(request_octets):
    for record in ndef.message_decoder(request_octets):
        print(record)

def on_startup(llc):
    snep_server = nfc.snep.SnepServer(llc)
    snep_server.set_callback(put_octets=put_octets)
    snep_server.set_callback(get_octets=get_octets)
    llc.private.snep_server = snep_server
    return llc

def on_connect(llc):
    llc.private.snep_server.start()
    return True

clf = nfc.ContactlessFrontend('udp::54322')
clf.connect(llcp={'on-startup': on_startup, 'on-connect': on_connect})
class nfc.snep.SnepServer(llc, **kwargs)

Bases: threading.Thread

Simple NDEF Exchange Protocol (SNEP) server implementation. A SnepServer must be instantiated before LLCP Link activation (usually within the ‘on-startup’ callback) with the LogicalLinkController instance as the first argument. Additional keyword arguments may be:

Parameters:
  • service_name (bytes) – The service name under which this SnepServer will be registered. Defaults to b'urn:nfc:sn:snep'.
  • max_acceptable_length (int) – The maximum number of SNEP request information octets the server will accept. Defaults to 1000000 octets.
  • recv_miu (int) – The maximum number of information octets to receive within a single LLCP Information PDU on the data link connection established by a remote SNEP Client. Defaults to 1984 octets.
  • recv_buf (int) – The number of receive buffers (receive window size) for the data link connection established by a remote SNEP Client. Defaults to 15 buffers.
  • get_records (function) – Same as in set_callback()
  • put_records (function) – Same as in set_callback()
  • get_octets (function) – Same as in set_callback()
  • put_octets (function) – Same as in set_callback()
set_callback(**kwargs)

Set callback functions for handling SNEP Get or Put requests. A callback operates on either an ndef.Record list or octet string.

Parameters:
  • get_records (function) – A function to process a SNEP Get request. The function receives the Get request information field as a ndef.Record list and must return an ndef.Record list or raise SnepError. The default implementation ignores the request data and always returns “Not Implemented” to the client.
  • put_records (function) – A function to process a SNEP Put request. The function receives the Put request information field as a ndef.Record list and should raise SnepError if processing errors are encountered. The default implementation ignores the request data and always returns “Success” to the client.
  • get_octets (function) – A function to process a SNEP Get request. The function receives the Get request information field as a bytes string and must return a bytes string as content for the SNEP Get response information field or raise SnepError. The default implementation calls get_records() with the request_octets decoded into NDEF Records and returns the octet representation of the NDEF Records returned by get_octets(). The get_octets() function receives as a second argument the maximum number of octets that the client is able to accept as response information field.
  • put_octets (function) – A function to process a SNEP Put request. The function receives the Put request information field as a bytes string and may raise SnepError if a processing error occured. The default implementation calls put_records() with the request_octets decoded into NDEF Records.

PEP 484 annotated callback function signatures:

get_records(request_records: List[ndef.Record]) -> List[ndef.Record]
put_records(request_records: List[ndef.Record]) -> None
get_octets(request_octets: bytes, acceptable_length: int) -> bytes
put_octets(request_octets: bytes) -> bytes
class nfc.snep.SnepError(err)

Bases: exceptions.Exception