chariotsolutions / phonegap-nfc

PhoneGap NFC Plugin
MIT License
704 stars 550 forks source link

Different UIDs on iOS / Android with ISO15693 Tag #446

Closed aaronbach closed 3 years ago

aaronbach commented 3 years ago

I'm using the following code to read out the UID in iOS / Android within an ionic app. With the most NFC Tags everything is working as expected.

But with ISO15693 Tags I get the wrong UID for iOS. I checked the UID with the iOS/Android App NFC-Tools. There both UIDs are the same.

With the plugin I get an other UID. Any Idea, what I am doing wrong?

if (this.platform.is('ios')) {
  // Handling iOS
  try {
    const nfcTag = await this.nfc.scanTag();
    return this.nfc.bytesToHexString(nfcTag.id);
  } catch (e) {
    // ...
  }
} else {
  // Handling Android
  return new Promise((resolve, reject) => {
    let flags = this.nfc.FLAG_READER_NFC_A | this.nfc.FLAG_READER_NFC_V;
    const subscription = this.nfc.readerMode(flags).subscribe(
      nfcTag => {
        const uid = this.nfc.bytesToHexString(nfcTag.id);
        subscription.unsubscribe();
        resolve(uid);
      },
      err => {
        // ...
      }
    );
  });
}

Example for the same ISO15693 Tag:

// ios
// Raw: [224, 4, 1, 80, 118, 210, 129, 5]
// nfc.bytesToHexString: e004015076d28105

// android
// Raw: [5, -127, -46, 118, 80, 1, 4, -32]
// nfc.bytesToHexString: 0581d276500104e0

Thanks

erikm30 commented 3 years ago

Actually ir is the same UID. It is just in MSB re sp. LSB representation.

In other words, if you read the array on Android from back to front, you get the same representation.

Aaron Bach notifications@github.com schrieb am So., 28. Feb. 2021, 19:11:

I'm using the following code to read out the UID in iOS / Android within an ionic app. With the most NFC Tags everything is working as expected.

But with ISO15693 Tags I get the wrong UID for iOS. I checked the UID with the iOS/Android App NFC-Tools. There both UIDs are the same.

With the plugin I get an other UID. Any Idea, what I am doing wrong?

if (this.platform.is('ios')) { // Handling iOS try { const nfcTag = await this.nfc.scanTag(); return this.nfc.bytesToHexString(nfcTag.id); } catch (e) { // ... } } else { // Handling Android return new Promise((resolve, reject) => { let flags = this.nfc.FLAG_READER_NFC_A | this.nfc.FLAG_READER_NFC_V; const subscription = this.nfc.readerMode(flags).subscribe( nfcTag => { const uid = this.nfc.bytesToHexString(nfcTag.id); subscription.unsubscribe(); resolve(uid); }, err => { // ... } ); }); }

Example for the same ISO15693 Tag:

// ios // Raw: [224, 4, 1, 80, 118, 210, 129, 5] // nfc.bytesToHexString: e004015076d28105

// android // Raw: [5, -127, -46, 118, 80, 1, 4, -32] // nfc.bytesToHexString: 0581d276500104e0

Thanks

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/chariotsolutions/phonegap-nfc/issues/446, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGEY4MO5T6SRJJDPNFMFZDTBKBO3ANCNFSM4YLJRKVQ .

aaronbach commented 3 years ago

@erikm30 thanks a lot 👍

Do you have any Idea, how I can detect, if I have to use MSB or LSB?

My approach would be to detect the Tagtype ISO15693. Any better Idea?

My goal is, that the same NFC-Tags are readable from different devices over their UID (iOS / Android).

Thanks

erikm30 commented 3 years ago

First it should be consistent, and secondly you can go for the e0 which is constant as defined in the standard.

Aaron Bach notifications@github.com schrieb am So., 28. Feb. 2021, 21:13:

@erikm30 https://github.com/erikm30 thanks a lot 👍

Do you have any Idea, how I can detect, if I have to use MSB or LSB?

My approach would be to detect the Tagtype ISO15693. Any better Idea?

My goal is, that the same NFC-Tags are readable from different devices over their UID (iOS / Android).

Thanks

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/chariotsolutions/phonegap-nfc/issues/446#issuecomment-787514835, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGEY4MOIPBIK75OJDHBD63TBKPVZANCNFSM4YLJRKVQ .

aaronbach commented 3 years ago

I wrapped my code with the following function to gather the correct uid. Not every NFC-tag used with our app is ISO conform, so I think the function should do the trick:

getUid (byteArray: number[]) {
  const uid = this.nfc.bytesToHexString(byteArray);
  // If UID is not starting with 'e0' => reverse the byte array
  if (uid.substr(0, 2).toLowerCase() !== 'e0') {
    const revUid = this.nfc.bytesToHexString(byteArray.reverse());
    if (revUid.substr(0, 2).toLowerCase() === 'e0') {
      return revUid;
    }
  }
  return uid;
}

thank you @erikm30

mameier commented 1 year ago

As the lower 6 Byte are simply a serial number, and the standard does'n mention that 0x0E is forbidden as last byte of the serial number, probaly every 256th ID might be misinterpreted.

It's better to check the os. If its Android, reverse the bytes.

amalg commented 11 months ago

"secondly you can go for the e0 which is constant as defined in the standard"

This statement is not accurate at all. The first byte of the UID, in this case, 0xE0 is a manufacturer's byte. Texas Instrument ISO15693 cards start with 0x01 while NXP cards start with 0xE0. Do not use this as a method for detecting byte order. Simply understand that Android (the reader platform you're using) uses LSB order to output the UID of ISO15693 cards.

Android does this because it's trying to be helpful. When you issue addressed commands to an ISO15693 card in the field, you must use LSB byte order. Unfortunately it's inconsistent with how every other reader (that I've encountered anyway) reports the UID - in MSB order. An eight byte ISO15693 UID is comprised with the following structure;

Byte 1: This is the Manufacturer code. It is assigned by the NFC Forum to each manufacturer. For example, Texas Instruments has the manufacturer code 0x01, NXP Semiconductors has 0x04, and so on.

Byte 2-3: These bytes represent the chip type. This is a unique code assigned by the manufacturer to each type of chip they produce.

Byte 4-8: These bytes represent the chip serial number. This is a unique number assigned by the manufacturer to each chip. It ensures that each chip produced by the manufacturer has a unique identifier.

minorityuk commented 8 months ago

Did you ever have a solution for this. I have an android app which reads it one way and I checked with another NFC app and its the same but on Apple or on a NFC reader pen which acts like it typing on a keyboard its in reverse?

My solution is to check for the EO at the start and reverse but this thread said it not always there.....it is on all the rfid tags I have tried but I am concerned if it is not.

My only solution on android that I can think of to match the pen is:

if tech type contains android.nfc.tech.NfcV then reverse the byte before converting to string.

alternative is look for E0 and if it exists from the pen then reverse the id.

I have no idea what safer as if the person who enters the ID into the system use IOS they get them in one order if they use Android its a different order.....