Skip to content

Commit

Permalink
Fix response parsing in reader.read and reader.write (add checks for …
Browse files Browse the repository at this point in the history
…minimal length)

Improve and fix logging
Add nfc.readers to expose all currently connected readers
  • Loading branch information
pokusew committed Dec 28, 2018
1 parent dfa2efe commit 02d0ef4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 33 deletions.
8 changes: 4 additions & 4 deletions src/ACR122Reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class ACR122Reader extends Reader {

response = await this.control(packet, 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);

// Red OFF Green OFF 0x00
// Red ON Green OFF 0x01
Expand Down Expand Up @@ -130,7 +130,7 @@ class ACR122Reader extends Reader {

response = await this.control(packet, 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);

// Red OFF Green OFF 0x00
// Red ON Green OFF 0x01
Expand Down Expand Up @@ -174,7 +174,7 @@ class ACR122Reader extends Reader {

response = await this.control(packet, 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);


} catch (err) {
Expand Down Expand Up @@ -213,7 +213,7 @@ class ACR122Reader extends Reader {

response = await this.control(packet, 1);

this.logger.info('response received', response);
this.logger.debug('response received', response);


} catch (err) {
Expand Down
10 changes: 6 additions & 4 deletions src/NFC.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class NFC extends EventEmitter {

this.pcsc.on('reader', (reader) => {

this.logger.info('New reader detected', reader.name);
this.logger.debug('new reader detected', reader.name);

// create special object for ARC122U reader with commands specific to this reader
if (reader.name.toLowerCase().indexOf('acr122') !== -1) {
Expand All @@ -57,18 +57,20 @@ class NFC extends EventEmitter {

this.pcsc.on('error', (err) => {

this.logger.info('PCSC error', err.message);
this.logger.error('PCSC error', err.message);

this.emit('error', err);

});

}

close() {
get readers() {
return this.pcsc.readers;
}

close() {
this.pcsc.close();

}

}
Expand Down
62 changes: 37 additions & 25 deletions src/Reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import {
} from './errors';


export const TAG_ISO_14443_3 = 'TAG_ISO_14443_3';
export const TAG_ISO_14443_4 = 'TAG_ISO_14443_4';
export const TAG_ISO_14443_3 = 'TAG_ISO_14443_3'; // ISO/IEC 14443-3 tags
export const TAG_ISO_14443_4 = 'TAG_ISO_14443_4'; // ISO/IEC 14443-4 tags

export const KEY_TYPE_A = 0x60;
export const KEY_TYPE_B = 0x61;
Expand Down Expand Up @@ -146,7 +146,7 @@ class Reader extends EventEmitter {

if ((changes & this.reader.SCARD_STATE_EMPTY) && (status.state & this.reader.SCARD_STATE_EMPTY)) {

this.logger.info('card removed');
this.logger.debug('card removed');

if (this.card) {
this.emit('card.off', { ...this.card });
Expand All @@ -170,7 +170,7 @@ class Reader extends EventEmitter {

const atr = status.atr;

this.logger.info('card inserted', atr);
this.logger.debug('card inserted', atr);

this.card = {};

Expand Down Expand Up @@ -204,7 +204,7 @@ class Reader extends EventEmitter {

this.reader.on('end', () => {

this.logger.info('reader removed');
this.logger.debug('reader removed');

this.emit('end');

Expand All @@ -223,7 +223,7 @@ class Reader extends EventEmitter {
throw new ConnectError('invalid_mode', 'Invalid mode')
}

this.logger.info('trying to connect', mode, modes[mode]);
this.logger.debug('trying to connect', mode, modes[mode]);

return new Promise((resolve, reject) => {

Expand All @@ -244,7 +244,7 @@ class Reader extends EventEmitter {
protocol: protocol,
};

this.logger.info('connected', this.connection);
this.logger.debug('connected', this.connection);

return resolve(this.connection);

Expand All @@ -260,7 +260,7 @@ class Reader extends EventEmitter {
throw new DisconnectError('not_connected', 'Reader in not connected. No need for disconnecting.')
}

this.logger.info('trying to disconnect', this.connection);
this.logger.debug('trying to disconnect', this.connection);

return new Promise((resolve, reject) => {

Expand All @@ -275,7 +275,7 @@ class Reader extends EventEmitter {

this.connection = null;

this.logger.info('disconnected');
this.logger.debug('disconnected');

return resolve(true);

Expand All @@ -293,7 +293,7 @@ class Reader extends EventEmitter {

return new Promise((resolve, reject) => {

this.logger.log('transmitting', data, responseMaxLength);
this.logger.debug('transmitting', data, responseMaxLength);

this.reader.transmit(data, responseMaxLength, this.connection.protocol, (err, response) => {

Expand All @@ -318,7 +318,7 @@ class Reader extends EventEmitter {

return new Promise((resolve, reject) => {

this.logger.log('transmitting control', data, responseMaxLength);
this.logger.debug('transmitting control', data, responseMaxLength);

this.reader.control(data, this.reader.IOCTL_CCID_ESCAPE, responseMaxLength, (err, response) => {

Expand Down Expand Up @@ -374,7 +374,7 @@ class Reader extends EventEmitter {

response = await this.transmit(packet, 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);


} catch (err) {
Expand Down Expand Up @@ -470,7 +470,7 @@ class Reader extends EventEmitter {

response = await this.transmit(packet, 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);


} catch (err) {
Expand All @@ -496,7 +496,7 @@ class Reader extends EventEmitter {
throw new ReadError(CARD_NOT_CONNECTED);
}

this.logger.info('reading data from card', this.card);
this.logger.debug('reading data from card', this.card);

if (length > packetSize) {

Expand Down Expand Up @@ -539,14 +539,18 @@ class Reader extends EventEmitter {

response = await this.transmit(packet, length + 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);

} catch (err) {

throw new ReadError(null, null, err);

}

if (response.length < 2) {
throw new ReadError(OPERATION_FAILED, `Read operation failed: Invalid response length ${response.length}. Expected minimal length is 2 bytes.`);
}

const statusCode = response.slice(-2).readUInt16BE(0);

if (statusCode !== 0x9000) {
Expand All @@ -555,7 +559,7 @@ class Reader extends EventEmitter {

const data = response.slice(0, -2);

this.logger.info('data', data);
this.logger.debug('data', data);

return data;

Expand All @@ -567,7 +571,7 @@ class Reader extends EventEmitter {
throw new WriteError(CARD_NOT_CONNECTED);
}

this.logger.info('writing data to card', this.card);
this.logger.debug('writing data to card', this.card);

if (data.length < blockSize || data.length % blockSize !== 0) {
throw new WriteError('invalid_data_length', 'Invalid data length. You can only update the entire data block(s).');
Expand Down Expand Up @@ -619,7 +623,7 @@ class Reader extends EventEmitter {

response = await this.transmit(packet, 2);

this.logger.info('response received', response);
this.logger.debug('response received', response);


} catch (err) {
Expand All @@ -628,7 +632,11 @@ class Reader extends EventEmitter {

}

const statusCode = response.readUInt16BE(0);
if (response.length < 2) {
throw new WriteError(OPERATION_FAILED, `Write operation failed: Invalid response length ${response.length}. Expected minimal length is 2 bytes.`);
}

const statusCode = response.slice(-2).readUInt16BE(0);

if (statusCode !== 0x9000) {
throw new WriteError(OPERATION_FAILED, `Write operation failed: Status code: 0x${statusCode.toString(16)}`);
Expand All @@ -644,7 +652,7 @@ class Reader extends EventEmitter {
return false;
}

this.logger.info('handling tag', this.card);
this.logger.debug('handling tag', this.card);

switch (this.card.standard) {

Expand All @@ -668,7 +676,7 @@ class Reader extends EventEmitter {
return false;
}

this.logger.info('processing ISO 14443-3 tag', this.card);
this.logger.debug('processing ISO 14443-3 tag', this.card);

// APDU CMD: Get Data
const packet = Buffer.from([
Expand All @@ -685,7 +693,7 @@ class Reader extends EventEmitter {

if (response.length < 2) {

const error = new GetUIDError('invalid_response', `Invalid response length ${response.length}. Expected minimal length was 2 bytes.`);
const error = new GetUIDError('invalid_response', `Invalid response length ${response.length}. Expected minimal length is 2 bytes.`);
this.emit('error', error);

return;
Expand Down Expand Up @@ -730,7 +738,7 @@ class Reader extends EventEmitter {
return false;
}

this.logger.info('processing ISO 14443-4 tag', this.card);
this.logger.debug('processing ISO 14443-4 tag', this.card);

if (!this.aid) {
this.emit('error', new Error('Cannot process ISO 14443-4 tag because AID was not set.'));
Expand Down Expand Up @@ -770,7 +778,7 @@ class Reader extends EventEmitter {

if (response.length < 2) {

const err = new Error(`Invalid response length ${response.length}. Expected minimal length was 2 bytes.`);
const err = new Error(`Invalid response length ${response.length}. Expected minimal length is 2 bytes.`);
this.emit('error', err);

return;
Expand All @@ -791,7 +799,7 @@ class Reader extends EventEmitter {
// strip out the status code
const data = response.slice(0, -2);

this.logger.info('Data cropped', data);
this.logger.debug('Data cropped', data);

this.emit('card', {
...this.card,
Expand All @@ -814,6 +822,10 @@ class Reader extends EventEmitter {

}

toString() {
return this.name;
}

}

export default Reader;

0 comments on commit 02d0ef4

Please sign in to comment.