An open API service indexing awesome lists of open source software.

https://github.com/somq/nfccard-tool

💳 🛠️ The missing toolbox for reading and writing NFC cards
https://github.com/somq/nfccard-tool

javascript ndef nfc nodejs ntag

Last synced: about 1 year ago
JSON representation

💳 🛠️ The missing toolbox for reading and writing NFC cards

Awesome Lists containing this project

README

          

# nfccard-tool

> The toolbox for reading and writing nfc cards.
> Parse card header, ndef message and records, prepare ndef records for writing...

## Table of Contents

* [Install](#install)
* [Features](#features)
* [Quick start examples](#quick-start-examples-with-the-help-of-nfc-pcsc)
* [Usage](#usage)
* [1 - Require the lib:](#1---require-the-lib)
* [2 - Parse a card header:](#2---parse-a-card-header)
* [3 - Parse a NDEF message:](#3---parse-a-ndef-message)
* [4 - Prepare a NDEF message:](#4---prepare-a-ndef-message)
* [API](#api)
* [Methods](#methods)
* [tag object](#tag-object)
* [Troubleshoot](#troubleshoot)
* [Third party](#thirdparty)
* [License](#license)

## Install

[npm](https://www.npmjs.com/):

```sh
npm install nfccard-tool --save
```

[yarn](https://yarnpkg.com/):

```sh
yarn add nfccard-tool --save
```

## Features

* Parse a card header and wrap raw and human readable data in a object:
* Locks states
* Capability Container
* Magic number
* Spec version
* Max NDEF length
* Read and write accesses
* NDEF message detection and length
* Parse and prepare a NDEF message of types:
* Text
* Uri
* Android App Record

## Quick start examples (with the help of [nfc-pcsc](https://github.com/pokusew/nfc-pcsc))
### Read a card header and parse a NDEF message

```
npm run read-nfcpcsc
```
### Write a NDEF message

```
npm run write-nfcpcsc
```

## Usage
### 1 - Require the lib:

```js
const ndef = require('nfccard-tool');
```

### 2 - Parse a card header:

With the card reader of your choice, read from block 0 until end of block 4. Which means a 20 bytes long read.

> Note: before any NDEF parsing or preparing we need to parse the card header first using a **read** command.

```js
// Starts reading in block 0 for 20 bytes long
const cardHeader = await reader.read(0, 20);

const tag = nfcCard.parseInfo(cardHeader);
console.log('tag info:', JSON.stringify(tag));
```
Which logs:
```json
tag info:
{
"headerValues":{
"raw":{
"Lock":{
"LOCK0":0,
"LOCK1":0
},
"capabilityContainer":{
"MAGIC_NUMBER":225,
"SPEC_VERSION":16,
"MAX_NDEF_LENGTH":109,
"READ_ACCESS":0,
"WRITE_ACCESS":0
},
"NDEFMessageHeader":{
"HAS_NDEF":3,
"MESSAGE_LENGTH":86
}
},
"string":{
"Lock":{
"LOCK0":"0",
"LOCK1":"0"
},
"capabilityContainer":{
"MAGIC_NUMBER":"E1",
"SPEC_VERSION":"10",
"MAX_NDEF_LENGTH":"6D",
"READ_ACCESS":"0",
"WRITE_ACCESS":"0"
},
"NDEFMessageHeader":{
"HAS_NDEF":"3",
"MESSAGE_LENGTH":"56"
}
}
},
"parsedHeader":{
"isFormatedAsNDEF":true,
"type2SpecVersion":"1.0",
"maxNDEFMessageSize":872,
"hasReadPermissions":true,
"getReadPermissionsType":"HAS_READ_ACCESS",
"hasWritePermissions":true,
"writePermissionsType":"HAS_WRITE_ACCESS",
"hasNDEFMessage":true,
"NDEFMessageLength":86,
"lengthToReadFromBlock4":88
}

}
```

### 3 - Parse a NDEF message:
> If card header parsing let us know *there might be* a NDEF message we can try to parse it:

```js
// There might be a NDEF message and we are able to read the tag
if(nfcCard.isFormatedAsNDEF() && nfcCard.hasReadPermissions() && nfcCard.hasNDEFMessage()) {

// Read the appropriate length to get the NDEF message as buffer
const NDEFRawMessage = await reader.read(4, nfcCard.getNDEFMessageLengthToRead()); // starts reading in block 0 until 6

// Parse the buffer as a NDEF raw message
const NDEFMessage = nfcCard.parseNDEF(NDEFRawMessage);

console.log('NDEFMessage:', NDEFMessage);

} else {
console.log('Could not parse anything from this tag: \n The tag is either empty, locked, has a wrong NDEF format or is unreadable.')
}
```

### 4 - Prepare a NDEF message:
> We can use the convenient method *prepareBytesToWrite* to get the appropriate Buffer we need to write a ndef message.
```js
// 1 - READ HEADER

// Starts reading in block 0 until end of block 4
const cardHeader = await reader.read(0, 20);

const tag = nfcCard.parseInfo(cardHeader);
console.log('tag info:', JSON.stringify(tag));

// 2 - WRITE A NDEF MESSAGE AND ITS RECORDS

const message = [
{ type: 'text', text: 'I\'m a text message', language: 'en' },
{ type: 'uri', uri: 'https://github.com/somq' },
{ type: 'aar', packageName: 'https://github.com/somq' },
]

// Prepare the buffer to write on the card
const rawDataToWrite = nfcCard.prepareBytesToWrite(message);

// Write the buffer on the card starting at block 4
const preparationWrite = await reader.write(4, rawDataToWrite.preparedData);

// Success !
if (preparationWrite) {
console.log('Data have been written successfully.')
}
```
Which logs:
```js
NDEFMessage:
[
{ NDEFLibRecord:
{ LanguageCode: null,
text: null,
_typeNameFormat: 1,
_type: [Array],
_id: [],
_payload: [Array] },
type: 'text',
text: 'I\'m a text message',
language: 'en' },
{ NDEFLibRecord:
{ RawUri: [],
Uri: '',
_typeNameFormat: 1,
_type: [Array],
_id: [],
_payload: [Array],
type: 'U' },
type: 'uri',
uri: 'https://github.com/somq' },
{ NDEFLibRecord:
{ packageName: '',
_typeNameFormat: 4,
_type: [Array],
_id: [],
_payload: [Array],
type: 'android.com:pkg' },
type: 'aar',
packageName: 'https://github.com/somq' }
]
```
---

## API

### Methods
```js
// Magic number
nfcCard.isFormatedAsNDEF();

// Type 2 Tag Specification version, eg. 1.0
nfcCard.getType2SpecVersion();

// Max NDEF size for the current tag
nfcCard.getMaxNDEFMessageLength();

// Read locked ?
nfcCard.hasReadPermissions();

// Read types: HAS_READ_ACCESS, RFU, PROPRIETARY, UNKNOWN
nfcCard.getReadPermissionsType();

// Write locked ?
nfcCard.hasWritePermissions();

// Write types: HAS_READ_ACCESS, RFU, PROPRIETARY, UNKNOWN
nfcCard.getWritePermissionsType();

// NDEF message flag is present ?
nfcCard.hasNDEFMessage();

// NDEF message length on exists on the tag
nfcCard.getNDEFMessageLength();

```
### tag *object*

```js
{
"headerValues":{
"raw":{ // Raw buffer values
"Lock":{
"LOCK0":0, // Lock 0 status - block 2, byte 2
"LOCK1":0 // Lock 1 status - block 2, byte 3
},
"capabilityContainer":{
"MAGIC_NUMBER":225, // magic number - block 3, byte 0 (CC0)
"SPEC_VERSION":16, // type 2 spec version - block 3, byte 1 (CC1)
"MAX_NDEF_LENGTH":109, // max ndef message length - block 3, byte 2 (CC2)
"READ_ACCESS":0, // read access - block 3, byte 3 (CC3)
"WRITE_ACCESS":0 // write access - block 3, byte 3 (CC3)
},
"NDEFMessageHeader":{
"HAS_NDEF":3, // NDEF header 0 - block 4, byte 0
"MESSAGE_LENGTH":86 // NDEF header 1 - block 4, byte 1
}
},
"string":{ // Hex string values
"Lock":{
"LOCK0":"0",
"LOCK1":"0"
},
"capabilityContainer":{
"MAGIC_NUMBER":"E1",
"SPEC_VERSION":"10",
"MAX_NDEF_LENGTH":"6D",
"READ_ACCESS":"0",
"WRITE_ACCESS":"0"
},
"NDEFMessageHeader":{
"HAS_NDEF":"3",
"MESSAGE_LENGTH":"56"
}
}
},
"parsedHeader":{
"isFormatedAsNDEF":true, // magic number - block 3, byte 0 (CC0)
"type2SpecVersion":"1.0", // type 2 spec version - block 3, byte 1 (CC1)
"maxNDEFMessageSize":872, // max ndef message length - block 3, byte 2
"hasReadPermissions":true, // read access - block 3, byte 3 (CC3)
"getReadPermissionsType":"HAS_READ_ACCESS",
"hasWritePermissions":true, // write access - block 3, byte 3 (CC3)
"writePermissionsType":"HAS_WRITE_ACCESS",
"hasNDEFMessage":true, // NDEF header 0 - block 4, byte 0
"NDEFMessageLength":86, // NDEF header 1 - block 4, byte 1
"lengthToReadFromBlock4":88 // NDEFMessageLength + 2
}

}
```

## Compatibility

Only a part of [Type 2 tag specification](docs/NFCForum-TS-Type-2-Tag_1.1.pdf) is implemented.

This lib does not support yet:
* Dynamical memory structure
* Lock preparing
* *... some are probably missing*

## Troubleshoot
>Error: *path*\node_modules\@pokusew\pcsclite\build\Release\ **pcsclite.node**

```
npm rebuild
```

## Third party
We are natively using [ndef-lib](https://github.com/somq/ndef-lib) for parsing but you could give a try at https://github.com/TapTrack/NdefJS or have a deep look at https://github.com/googlearchive/chrome-nfc

If you are looking for a nfc tag reading library take a look at https://github.com/pokusew/nfc-pcsc

## License

[MIT](LICENSE) © somq