SCM reader with PN533 not supported

Asked by André Cruz

Hello.

I have an SCM reader SCL3711, which works with libnfc (it is reported as SCM Micro / SCL3711-NFC&RW - PN533 v2.7 (0x07)), but nfcpy does not run:

LookupError: couldn't find any usable nfc reader

Since this uses the PN533 chipset is it a question of including its description in the library or is it really not supported? I'm trying to use nfcpy to establish p2p communication with a Nexus S.

Thank you.

Question information

Language:
English Edit question
Status:
Solved
For:
nfcpy Edit question
Assignee:
No assignee Edit question
Solved by:
Stephen Tiedemann
Solved:
Last query:
Last reply:
Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#1

Hello Andre,

the SCL3711 requires a PC/SC stack, i.e. the PN53x chip is not directly accessible via USB. The libnfc relies on PC/SC Lite for addressing this reader. This is not supported by nfcpy, where the reader chip needs to be accessible directly on the USB interface, the pn53x.py module uses the chip's native command set for simplicity and speed. It should be possible to run nfcpy on top of libnfc without too much effort, using the Python bindings that exist for libnfc.

/Stephen

Revision history for this message
neomilium (neomilium) said :
#2

Hello,

The SCL3711 does not requires PC/SC stack. To use it with libnfc, you have to remove SCL drivers for PC/SC. The SCL3711 is a PN533 2.7 directly connected to USB bus.

neomilium

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#3

Hello neomilium,

many thanks for the info, I didn't know that.

In that case the SCL 3711 should just work with nfcpy, would only need to add the USB Vendor/Product ID. According to libnfc the SCL3711 has Vendor ID 0x04E6 and Product ID 0x5591. Unfortunately I have no SCL 3711 to test but if someone would like to test, the right place is in nfc/dev/pn53x.py, line 41:

supported_devices.append((0x04e6,0x5591)) # SCL 3711

If confirmed I'd push that into trunk. Guess I'll also try to get hold of a reader but this might take a little while.

/Stephen

Revision history for this message
André Cruz (andrefcruz) said :
#4

I can try it, I have one just here. But what should I expect to see? :)

Revision history for this message
André Cruz (andrefcruz) said :
#5

I also added:

@@ -144,7 +145,8 @@

         fw = self.get_firmware_version()
         if ((dev.idVendor, dev.idProduct) == (0x04cc, 0x0531) or
- (dev.idVendor, dev.idProduct) == (0x054c, 0x0193)):
+ (dev.idVendor, dev.idProduct) == (0x054c, 0x0193) or
+ (dev.idVendor, dev.idProduct) == (0x04e6,0x5591)):
             self.ic = "PN531"

When I run helloworld with a tag near the reader I get nothing:

$ python helloworld.py
Please touch a tag to send a hello to the world

If I use libnfc:

$ nfc-list
nfc-list use libnfc 1.5.0 (rexported)
Connected to NFC device: SCM Micro / SCL3711-NFC&RW - PN533 v2.7 (0x07)
1 ISO14443A passive target(s) found:
    ATQA (SENS_RES): 03 44
       UID (NFCID1): 04 4e 54 31 d5 1b 80
      SAK (SEL_RES): 20
                ATS: 75 77 81 02 80

When I tried the LLCP server with my Nexus S I got:

$ ./llcp-test-server.py
searching for a usb tty reader
searching for a usb bus reader
trying reader at usb port 029:002
chipset is a PN531 version 51.2
ATR_RES(nfcid3=eb9f6fdc2e99bcf3379a, did=00, bs=00, br=00, to=0e, pp=32, gb=46666d01011003020001040196)
running on Initiator
recv-lto: 1500
recv-miu: 128
recv-wks: 3
send-agf: True
send-lsc: 3
send-lto: 1000
send-miu: 128
send-wks: 1
connectionless server bound to port 16
connectionless server recv queue size is 2
connectionmode server bound to port 17
connectionmode server recv window is 2
shutdown on link disruption
remote side closed logical data link
close connless echo server socket
nfc.llcp.Error: [EPIPE] Broken pipe
I was the Initiator
$

Revision history for this message
Best Stephen Tiedemann (stephen-tiedemann) said :
#6

Thanks Andre, seems the reader is working. Great you've found the place around firmware determination, I've missed to mention that. Actually it should fall under the elif branch which is for readers 532 and above. I'll commit the necessary changes tomorrow..

The helloworld example does not work simply because nfcpy does currently only handle NFC Forum Type 3 Tags (aka FeliCa). You've touched a 14443A tag according to libnfc output. I'm still hoping for volunteers to help with the other tag types, my knowledge is with Felica technology and that is what I can contribute to the community.

Your LLCP output looks excellent, you should only need to add the command line parameter "--quirks android". Background is that the LLCP implementation on Nexus S has two flaws, an NFC-DEP Initiator needs to wait 100ms after links setup before sending the first LLC PDU and the it does not implement PDU aggregation. I hope these will be fixed with the next Android update, Google knows about the issue. For the time being, the quirks flag will do the necessary adjustments.

/Stephen

Revision history for this message
André Cruz (andrefcruz) said :
#7

Thanks Stephen Tiedemann, that solved my question.

Revision history for this message
Gopalsridhara (gsridhara) said :
#8

Hello Stephen

I am trying to help with Mifare classic tags. I have done coding, but running into some issues on Mifare classic.
May be You can help and together we can resolve this.

one of the question is I am getting this from your code.

following piece of code ( line number 274 and 275 )
         self.dev.write("\xD4\x32\x82"+chr(self._rwt)+chr(self._wtx)+"\x08")
         self.dev.read(timeout=100)

Gives me error. and I searched documentation for this and I could not find any info in PN533 manuals.

error is

DEBUG:nfc.dev.pn53x:write 6 byte
  0000: d4 32 82 08 01 08 .2....
DEBUG:nfc.dev.pn53x:read 1 byte
  0000: 7f .
DEBUG:nfc.dev.pn53x:write 5 byte

Also. Iam getting error for

DEBUG:nfc.dev.pn53x:write 18 byte
  0000: d4 06 a0 1b a0 1c a0 1d a0 1e a0 1f a0 20 a0 21 ............. .!
  0010: a0 22 ."
DEBUG:nfc.dev.pn53x:read 11 byte
  0000: d5 07 00 85 0a b2 85 04 da 02 32 ..........2
DEBUG:nfc.clf:using driver <nfc.dev.pn53x.device object at 0x178dfd0>
DEBUG:nfc.dev.pn53x:polling a mifare tag similar to type 1 tag
DEBUG:nfc.dev.pn53x:write 4 byte
  0000: d4 32 01 00 .2..
DEBUG:nfc.dev.pn53x:read 2 byte
  0000: d5 33 .3
DEBUG:nfc.dev.pn53x:write 3 byte
  0000: d4 58 00 .X.
DEBUG:nfc.dev.pn53x: Something wrong in USB reading
DEBUG:nfc.dev.pn53x:write 0 byte
DEBUG:nfc.dev.pn53x:write 4 byte
  0000: d4 4a 01 00 .J..
DEBUG:nfc.dev.pn53x:read 12 byte
  0000: d5 4b 01 01 00 04 08 04 8d 93 a0 23 .K.........#
DEBUG:nfc.dev.pn53x:rsp: 00 04 08 04 8d 93 a0 23
DEBUG:nfc.clf:Got tag 000408048d93a023
DEBUG:nfc.clf:got type Mifare Tag
DEBUG:nfc.clf:ATQA : 00 04
DEBUG:nfc.clf:SKA : 08
DEBUG:nfc.clf:UID : 8d 93 a0 23
DEBUG:nfc.mfc: SAK : 08
Tagsize : 1024
DEBUG:nfc.mfc:to authenticate data : 01 61 00 ff ff ff ff ff ff 8d 93 a0 23
DEBUG:nfc.dev.pn53x:mfc_exchange
DEBUG:nfc.dev.pn53x:write 4 byte
  0000: d4 4a 01 00 .J..
DEBUG:nfc.dev.pn53x:read 12 byte
  0000: d5 4b 01 01 00 04 08 04 8d 93 a0 23 .K.........#
DEBUG:nfc.dev.pn53x:write 15 byte
  0000: d4 40 01 61 00 ff ff ff ff ff ff 8d 93 a0 23 .@.a..........#
DEBUG:nfc.dev.pn53x:read 3 byte
  0000: d5 41 00 .A.
DEBUG:nfc.dev.pn53x:Response MFC_excange : d5 41 00
DEBUG:nfc.mfc: Auth resp: d5 41 00
DEBUG:nfc.mfc: Auth resp: d5 41 00
Authenticated tag
DEBUG:nfc.dev.pn53x:mfc InJumpForPSL
DEBUG:nfc.dev.pn53x:data for InJumpPSL : d4 56 00 00 01
DEBUG:nfc.dev.pn53x:write 5 byte
  0000: d4 56 00 00 01 .V...
DEBUG:nfc.dev.pn53x:read 3 byte
  0000: d5 57 01 .W.

Also I have created 2 files which is work in progress

here is a sample changes to pn533.py
which is also wip.

gsridhara@GS-Notebook:~/NFC-dev/nfcpy/nfc/dev$ diff pn53x.py pn53x.py.orig
32d31
< import struct
75,76c74
< #if self.write("\xD4\x4A" + chr(max_tg) + chr(br_ty) + initiator_data):
< if self.write("\xD4\x4A\x01\x00"):
---
> if self.write("\xD4\x4A" + chr(max_tg) + chr(br_ty) + initiator_data):
78c76
< rsp = self.read(timeout=400)
---
> rsp = self.read(timeout=500)
81,84d78
< if nb_tg == 0:
< if self.write("\xD4\x4A\x01\x00"):
< rsp = self.read(timeout=500)
< nb_tg = ord(rsp[2])
89,94c83,84
< if ( len(rsp) > 5+nfcid_length):
< ats_length = ord(rsp[5 + nfcid_length])
< else:
< ats_length = 0
< #targets.append(rsp[1:5+nfcid_length+ats_length])
< targets.append(rsp[1:])
---
> ats_length = ord(rsp[5] + nfcid_length)
> targets.append(rsp[1:5+nfcid_length+ats_length])
101c91
< #rsp = rsp[1+len(targets[-1]):]
---
> rsp = rsp[1+len(targets[-1]):]
187,189c177
< except usb.USBError:
< log.debug(" Something wrong in USB reading ")
< return None
---
> except usb.USBError: return None
272,273c260
< #self.dev.write("\xD4\x32\x05\xFF\xFF\x00")
< self.dev.write("\xD4\x32\x05\x00\x00\x04")
---
> self.dev.write("\xD4\x32\x05\xFF\xFF\x00")
300c287
< self.dev.write("\xD4\x58\x00")
---
> self.dev.write("\xD4\x18\x01")
316,326c303
< #pass
< log.debug("polling for a type 1 tag")
< if self.dev.ic == "PN533":
< self._pn533_reset_mode()
<
< initator_data = ""
< try: rsp = self.dev.in_list_passive_target(1, br, initator_data)[0]
< except IndexError: pass
< if ord(rsp[2]) == 1:
< log.debug("target found, ATQA(SENS_RES) : {0} ; SAK (SEL_RES) : {1}".format(rsp[1:2])+format(rsp[3]))
< return rsp[2:]
---
> pass
331,348d307
< def poll_mfc(self):
< log.debug("polling a mifare tag similar to type 1 tag")
< if self.dev.ic == "PN533" :
< self._pn533_reset_mode()
<
< poll_ffff = ""
< br_ty = "106A" # For RFA or ISO-14443A type tags
< try:
< rsp = self.dev.in_list_passive_target(1,br_ty,None)[0]
< except:
< print "Index error for polling"
< raise IOError("Index Polling")
< else:
< if rsp:
< log.debug("rsp: " + ' '.join(["%02x" % ord(x) for x in rsp]))
< return rsp
<
<
357c316
< for br in ( "424F", "212F"):
---
> for br in ("424F", "212F"):
461,528c420
< log.debug("tt1_exchange")
< if self.dev.write("\xD4\x42" + cmd):
< resp = self.dev.read(timeout)
< if resp is None:
< raise IOError(0, "no response")
< if not resp.startswith("\xD5\x43"):
< raise IOError(0, "invalid response")
< if not ord(resp[2]) & 0x3F == 0:
< raise IOError(ord(resp[2]) & 0x3F, "hardware error")
< return resp[3:]
<
< def mfc_getGeneralStatus(self):
< log.debug("Getgeneral Status")
< if self.dev.write("\xD4\x04" ):
< resp = self.dev.read(timeout=500)
< if resp is None:
< raise IOError(0, "no response")
< if not resp.startswith("\xD5\x05"):
< raise IOError(0, "invalid response")
< #if not ord(resp[2]) & 0xFF == 0:
< # raise IOError(ord(resp[2]) & 0xFF, "hardware error")
< return resp[3:]
<
< def mfc_in_jump_for_psl(self,inJumpPSLData):
< log.debug("mfc InJumpForPSL")
< cmd = "\xD4\x56"
< actpass = "\x00" ## 0x00 for passive 0x01 for active
< br = "\x00" # 0x00 for 106 kbps, 0x01 = 212kbps, 0x02 = 424kbps
< next = "\x01" # Next indicates optional fields present or not b0 = passive initiator data,NFCId or Gi present
< passiveinitiatordata = "" # Optional field , contains NFCId or length etc.
< nfcid3 = "" # Optional field
< #data = cmd + actpass + br + next + passiveinitiatordata
< data = cmd + actpass + br +next
< log.debug("data for InJumpPSL : "+''.join([" %02x" % ord(x) for x in data]))
< if self.dev.write(data):
< resp = self.dev.read(timeout=400)
< log.debug("Response for InJumpPSL : "+''.join([" %02x" % ord(x) for x in resp]))
< if not resp.startswith("\xD5\x47"):
< raise " Error bad communication"
< elif ord(resp[2]) & 0x3F != 0:
< raise " Some error in tag activation in RF field"
< else:
< return resp
<
< def mfc_exchange(self, cmd):
< log.debug("mfc_exchange")
< resp = self.dev.in_list_passive_target(1,"106A",None)
< # Do in select now it is checking but later on do a
< # right implementation
< # Do general status first.
< #if self.dev.write("\xD4\x04"):
< # statusresp = self.dev.read(timeout=400)
< # log.debug("Response for general status check : "+''.join([" %02x" % ord(x) for x in statusresp]))
< # if not statusresp.startswith("\xD5\x05") or (statusresp[2] != "\x00"):
< # #raise "Error : Response is "+''.join([" %02x" % ord(x) for x in statusresp])
< # raise "Error : Response is bad "
< if self.dev.write("\xD4\x40" + cmd):
< resp = self.dev.read(timeout=400)
< log.debug("Response MFC_excange : "+''.join([" %02x" % ord(x) for x in resp]))
< if resp is None:
< raise IOError(0, "no response")
< if not resp.startswith("\xD5\x41"):
< raise IOError(0, "invalid response")
< if not ord(resp[2]) & 0x3F == 0:
< #raise IOError(ord(resp[2]) & 0x3F, "hardware error")
< return resp
< #return resp[3:]
< return resp[0:]
---
> raise NotImplemented
532,554d423
<
< def mfc_diagnose(self, testnum ):
< log.debug("mfc_diagnose")
< if self.dev.write("\xD4\x00" + struct.pack('B',testnum)):
< resp = self.dev.read(timeout=400)
< if resp is None:
< raise IOError(0, "no response")
< if not resp.startswith("\xD5\x01"):
< raise IOError(0, "invalid response")
< return resp[3:]
<
< def mfc_commthru(self, cmd, timeout=800):
< log.debug("mfc_commthru")
< resp = self.dev.in_list_passive_target(1,"106A",None)
< if self.dev.write("\xD4\x42" + cmd):
< resp = self.dev.read(timeout)
< if resp is None:
< raise IOError(0, "no response")
< if not resp.startswith("\xD5\x43"):
< raise IOError(0, "invalid response")
< if not ord(resp[2]) & 0x3F == 0:
< raise IOError(ord(resp[2]) & 0x3F, "hardware error")
< return resp[3:]

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#9

Hi Gopalsridhara,

thanks for your help with the Mifare tags. As I learned recently, there are some subtle parameter differences between PN533v1.48 and PN533v2.7 (as in the SCL3711). I'm working on an update of pn53x to handle those differences but I'm pretty busy this week for an NFC Forum meeting.

The "\xD4\x32\x82" command is indeed specific to PN533V1.48

For the following error, why are you using RF Regulation Test? The USB read error may actually be correct as the RF Regulation Test command does not have a response.

DEBUG:nfc.dev.pn53x:write 3 byte
  0000: d4 58 00 .X.
DEBUG:nfc.dev.pn53x: Something wrong in USB reading

Revision history for this message
Gopalsridhara (gsridhara) said :
#10

Hello

I am almost complete with my Mifare support for nfcpy.
I will send you code in couple of days.

Code consists of mfc.py ( a MFC class and MFCNDEF class)

MFC class will have similar methods to android.nfc.miFare class and also all
methods
just like tt3 tag in your implementation.

Also in few weeks I will try to get you similar to tt2 and may be tt1.

Let us keep in touch and make this nfcpy a accepted code base for NFC.

Thanks
Gopal

On Thu, Jun 9, 2011 at 8:01 AM, Stephen Tiedemann <
<email address hidden>> wrote:

> Question #158104 on nfcpy changed:
> https://answers.launchpad.net/nfcpy/+question/158104
>
> Stephen Tiedemann posted a new comment:
> Hi Gopalsridhara,
>
> thanks for your help with the Mifare tags. As I learned recently, there
> are some subtle parameter differences between PN533v1.48 and PN533v2.7
> (as in the SCL3711). I'm working on an update of pn53x to handle those
> differences but I'm pretty busy this week for an NFC Forum meeting.
>
> The "\xD4\x32\x82" command is indeed specific to PN533V1.48
>
> For the following error, why are you using RF Regulation Test? The USB
> read error may actually be correct as the RF Regulation Test command
> does not have a response.
>
> DEBUG:nfc.dev.pn53x:write 3 byte
> 0000: d4 58 00 .X.
> DEBUG:nfc.dev.pn53x: Something wrong in USB reading
>
> --
> You received this question notification because you are a direct
> subscriber of the question.
>

--
Gopal Sridhara
<email address hidden>

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#11

Hi Gopal,

that's fantastic, many thanks for your help. When you're ready to send please tell me also the Bazaar revision number of pn53x.py your code is based on., as I'll be checking in new revisions to better deal with the firmware differences.

/Stephen

Revision history for this message
martial19n (martial19n) said :
#12

hi everyone... am currently working on P2P between Nexus S and SCL3711 and am unable to acheive anything.. so i kindly require helps from u guys.. could u help me with documents regarding this..

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#13

Your question is a bit unspecific. If you need some basic pointers to get
started, have a look at https://answers.launchpad.net/nfcpy/+question/183886
.
/Stephen