0
votes

I have LibNFC working from the Linux terminal recognising my ACR122U Reader, and I wanted to know if there was a method for it to work through Chrome on a Linux Desktop as it is really similar to Android Support, with all the NFC device handling done by libnfc and the browser just has to know about this library instead of every type usb or other device than can do NFC.

I have tried using the WebNFC API to connect it :

document.getElementById("scanButton").addEventListener("click", async () => {
    log.innerHTML = "NFC Register started...";

    try {
      const ndef = new NDEFReader();
      await ndef.scan();
      log.innerHTML = ("> Scan started");
  
      ndef.addEventListener("readingerror", () => {
        log.innerHTML = ("Argh! Cannot read data from the NFC tag. Try another one?");
      });
  
      ndef.addEventListener("reading", ({ message, serialNumber }) => {
        log.innerHTML = ("ID  ${serialNumber} logged @" + dt.toLocaleTimeString());   });
    } catch (error) {
      log.innerHTML = (error);
    }
  });

  document.getElementById("stopButton").onclick = function(){
    log.innerHTML = "NFC Register stopped @ " + new Date().toLocaleTimeString();
    }; 

but I'm met with Error: NFC Permission Request denied

and the WebUSB API to connect it:

var usbd = {};
let device;
let deviceEndpoint = 0x02;

let powerUpDevice = new Uint8Array([0x62,0x00, 0x00, 0x00, 0x00,0x00,0x00,0x01,0x00, 0x00]).buffer;
let getCardUID = new Uint8Array([0xff,0xca,0x00,0x00,0x04]).buffer;

(function() {
    'use strict';

    usbd.authorize = function(){
        navigator.usb.requestDevice({ filters: [{ vendorId: 0x072f }] })
            .then(selectedDevice => {
                device = selectedDevice;
                console.log(device.configuration.interfaces[0].interfaceNumber);
                console.log(device.manufacturerName);
                console.log(device.productName);
                console.log(device);
                return device.open()
                    .then(() => {
                        if (device.configuration === null) {
                            return device.selectConfiguration(1);
                        }
                    });
            })
            .then(() => device.claimInterface(0))

but I'm met with Error: ...blocked because it implements a protected interface class i.e. not supported, so that's a no go.

Is there a way to incorporate the libusb/libnfc libraries or any other method to directly connect an NFC reader to read into a web browser/application?

1
You'll need users to download or run a program that runs a localhost webserver which your web-application can connect to to use local hardware - this is how Dell's Service Tag lookup feature works, for example.Dai
Ooh, thanks for that and the great example; I think that might be my plan B perhaps, but I really wanted it to be a standalone web application without extra programs to install. At least then it would be able to run on multiple platforms but yes thank you so much for that solution -- I'll fall back on that if all else fails :)rxm
Have you tried running your WebNFC example in an https:// web-app (e.g. using letsencrypt free certificates)? As far as I understand, you need to be in a secure context in order to access the NFC reader (that's why the WebNFC online experiment should work from this https:// configured website googlechrome.github.io/samples/web-nfc )FSp
@FSp yeah I use the application in both a localhost environment and a https domain address for testing the application. I think it's mainly the ACR122U reader that's the issue...rxm

1 Answers

2
votes

Web NFC is supported on Android only as of February 2021. See https://web.dev/nfc/

The WebUSB error suggests you're requesting an interface that implements a protected class (among those below):

  // USB Class Codes are defined by the USB-IF:
  // https://www.usb.org/defined-class-codes
  const uint8_t kProtectedClasses[] = {
      0x01,  // Audio
      0x03,  // HID
      0x08,  // Mass Storage
      0x0B,  // Smart Card
      0x0E,  // Video
      0x10,  // Audio/Video
      0xE0,  // Wireless Controller (Bluetooth and Wireless USB)
  };

I wonder if that's a linux thing though as I was able to communicate with the ACR122U and SCL3711 NFC reader USB devices through WebUSB. See https://github.com/beaufortfrancois/chrome-nfc

Did you give a try to WebHID by any chance first? See https://web.dev/hid