In the laboratory of the university I belong to, the system was built by throwing the fact that the door of the room was unlocked and closed by the ancestor to Slack by pressing the Amazon Dash button. However, the notification did not fly as soon as the internal button reached the end of its life this year. I had an idea to change the button or change the battery, but anyway, if I can check the occupancy status using not only the room door but also the student ID as a development of these in my graduation research, the battery is dead etc. The system will not stop working, and I think that checking the occupancy status will make it easier to manage the keys, so I will collaborate with my friends to check the occupancy status in the laboratory as part of my graduation research. Of the systems, I will be in charge of the system for "reading the student ID number from the student ID card". I will leave it in the article as a memorandum. Even so, the precedents (Shizuoka University and Aizu University 02 / nfcpy% E3% 82% 92% E4% BD% BF% E3% 81% A3% E3% 81% A6% E5% AD% A6% E7% 94% 9F% E8% A8% BC% E3% 81% 8B% E3% 82% 89% E5% AD% A6% E7% B1% 8D% E7% 95% AA% E5% 8F% B7% E3% 82% 92% E8% AA% AD% E3% 81% BF% Since there is an example of E5% 8F% 96% E3% 82% 8B), we built it based on that.)
I'm a complete amateur when it comes to Python. As part of the seminar, I moved it from GPIO to LED or tact switch.
--Server (Raspberry Pi this time)
Since I was provided with Raspberry Pi 4 as a server from the laboratory side this time, I searched for a library for various NFC card readers with Python, and since all articles use nfcpy (there is no other choice) nfcpy I decided to move it in various ways using. Also, most of the card readers used Sony's PaSoRi, so I bought it on my own for research.
Construction started in July because the start time was significantly different due to a new virus. At that stage, there was no example of using Raspberry Pi 4, but the result was successful.
First, insert nfcpy. It won't start without this.
sudo pip install --upgrade pip
// update pip
sudo pip install nfcpy
// Install nfcpy
If nfcpy appears in pip show nfcpy
, the installation is successful.This article has been changed to Reference.
You should get an error when you type python -m nfc
.
Type the following command (long)
sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"06c3\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
According to the article, port100 is doing something wrong.
sudo udevadm control -R
sudo modprobe -r port100
sudo sh -c 'echo blacklist port100 >> /etc/modprobe.d/blacklist-nfc.conf'
This will prevent port100 from booting.
You can recognize PaSoRi by typing python -m nfc
.
Now you are ready to read the NFC card reader.
After completing the above preparations, I will write a program to read my student ID card.
NFC cards such as student ID cards do not store data as they are (naturally), so it is necessary to find out in which area the target data is located. Although the target is different, there was a pioneer who wrote a program that dumps in the same way, so here is the code I used it to dump my student ID. The extracted data is as follows, but since it may lead to my personal information as the author, I will omit the part other than the student ID number part which is the core of this time.
Type3Tag 'FeliCa Standard (RC-SA00/1)' ID=0116040086180701 PMM=033242828247AAFF SYS=809E
System 809E (unknown)
Area 0000--FFFE
Area 1000--10FF
Random Service 64: write with key & read w/o key (0x1008 0x100B)
Area 2000--20FF
Random Service 128: write with key & read w/o key (0x2008 0x200B)
0000: XX XX XX XX 32 31 31 35 00 00 00 00 00 00 00 00 |*XXX2115........|
Area 3000--30FF
Random Service 192: write with key & read w/o key (0x3008 0x300B)
Area 4000--40FF
Random Service 256: write with key & read w/o key (0x4008 0x400B)
System FE00 (Common Area)
Area 0000--FFFE
Area 1A80--1AFF
Area 1A81--1AFF
Random Service 106: write with key & read w/o key (0x1A88 0x1A8B)
Looking at the above results, it was found that our university stores it as an ASCII code in the service code 0x200B of the system code: 0x809E (If you give out the student ID number as it is, it will lead to personal injury, so the first 4 characters are hidden. Therefore, when you read the NFC card, you can get the student ID number by reading out those block codes and extracting them.
Below is a program that reads the student ID number using nfcpy.
read_nfc.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import binascii
import nfc
#Service code that stores the student ID number of our student ID card
service_code = 0x200B
def connected(tag):
if isinstance(tag, nfc.tag.tt3.Type3Tag):
try:
#16-bit service_code to service>>Extract the upper 10 bits with 6 and service_code &&Extract the lower 6 bits with 0x3f
svcd = nfc.tag.tt3.ServiceCode(service_code >> 6, service_code & 0x3f)
#service is read_without_encryption argument service_Index in list
blcd = nfc.tag.tt3.BlockCode(0,service=0)
#read_without_Read the block data in the information of the specified part of the tag by encryption
block_data = tag.read_without_encryption([svcd], [blcd])
#This time, it is stored in the 1st to 8th characters of the block data, it is converted to a character string and utf-Decode at 8
student_id = str(block_data[0:8].decode("utf-8"))
print(student_id)
except Exception as e:
print("Error:%s" % e)
else:
print("Error:tag isn't Type3Tag")
#If the value is returned as True, it will be processed only once until it is touched and released.
return True
clf = nfc.ContactlessFrontend('usb')
def main():
while True:
#Wait until you read your student ID
clf.connect(rdwr={'on-connect': connected,})
try:
main()
except KeyboardInterrupt:
print("Forced termination")
clf.close()
sys.exit(0)
To be honest, I can't do much commentary because of lack of skills, but it's a memorandum, so it's a personal memo. Reference
First of all, clf = nfc.ContactlessFrontend ('usb')
means to open an NFC reader with a USB connection, which is just a declaration to use PaSoRi.
Start the NFC card reader with clf.connect and wait until the NFC touch is done. Among the arguments of connect, there are callbacks such as on-startup at startup, on-connect when touched, and on-release when the card is released. By specifying a callback function for each, the behavior can be changed by the action. This time, specify the function connected (tag) for on-connect.
In the connected that is called when the card is touched to the reader, a tag that represents the object of that tag is passed. After that, the tag is used to communicate with the NFC tag.
The NFC service code itself is a 16-bit value, with the upper 10 bits being the service number and the lower 6 bits being the attribute value. In this case, since the service code to be examined has already been obtained (0x200B), there is a high possibility that it will work even if you do not put it in the honest variable, and it seems that you do not need to take extra memory, but when using multiple service codes I think it will be more efficient to look up using an array.
nfc.tag.tt3.ServiceCode (service_code >> 6, service_code & 0x3f)
is a way to create a ServiceCode object from a 16-bit integer service. Extract the upper 10 bits with service_code >> 6. Extract the lower 6 bits with service_code & 0x3f.
Next, I will read the data block, but the document of read_without_encryption According to this, service = 0
passed when generating the Blockcode is not the service code itself, but the index in the argument service_list
of the argument of read_without_encryption
. Each service has a block with a size of 16 bytes, and serial numbers are assigned from 0 in the service. In this case, it is in the 0th to 7th, but if you set student_id = str (block_data [0: 8] .decode ("utf-8 "))
here, the last data will be Be careful as it will be cut off. Regarding the character code, I think it depends on the OS used in the system, but our student ID card is Shift_JIS (~~ I want you to perish ~~), and there are too many inconveniences for Linux systems such as Raspberry OS. , Basically, it is safe to decode to utf-8.
Finally, if the return value of connected is set to True
, processing will be performed only once until the card is touched and released. On the contrary, if it is False
, the process of reading it will occur many times, so it will be inconvenient for this system, so let's set it to True
properly.
This time I started from a state where I didn't know much about Python, so I wrote the program with great reference to the source article, but it works unexpectedly. Since it is still in the prototype stage, we will make various improvements so that it can be announced as a graduation research.
(2020/10/16 19:36) I received a report that there was a part where I forgot to hide the block data, so I reflected it.
Recommended Posts