Adriel García
Adriel García

Reputation: 1

Can't make my ACR1255U-J1 to work properly with my NFC Mifare Ultralight card

I've been trying for days to make my ARC1255U-J1 Bluetooth NFC Reader to read my NFC Mifare Ultralight card to open a simple URL on my phone, but it has been impossible. The only output I get it's the extact same result for having a NFC card on top of the reader as off the reader.

Example:

With NFC Card

Running "NFCReaderApp" with {"rootTag":141,"initialProps":{},"fabric":true} NFCReader.js:54 Connected device: ACR1255U-J1-035094 NFCReader.js:150 Comando enviado: ff 00 00 00 00 NFCReader.js:150 Comando enviado: ff 00 00 02 01 NFCReader.js:150 Comando enviado: ff 00 00 03 01 NFCReader.js:82 Reader Initialized NFCReader.js:100 Raw data: 05 00 07 52 00 00 00 00 01 53 07 0a

Without NFC Card

Running "NFCReaderApp" with {"rootTag":141,"initialProps":{},"fabric":true} NFCReader.js:54 Connected device: ACR1255U-J1-035094 NFCReader.js:150 Comando enviado: ff 00 00 00 00 NFCReader.js:150 Comando enviado: ff 00 00 02 01 NFCReader.js:150 Comando enviado: ff 00 00 03 01 NFCReader.js:82 Reader Initialized NFCReader.js:100 Raw data: 05 00 07 52 00 00 00 00 01 53 07 0a

What could be happening?

import base64 from 'base-64';
import { BleManager } from 'react-native-ble-plx';

class NFCReaderApp {
constructor(onCardStatusChange) {
this.bleManager = new BleManager();
this.SERVICE_UUID = "3c4afff0-4783-3de5-a983-d348718ef133";
this.WRITE_CHARACTERISTIC = "3c4afff1-4783-3de5-a983-d348718ef133";
this.NOTIFY_CHARACTERISTIC = "3c4afff2-4783-3de5-a983-d348718ef133";
this.scanning = false;
this.onDeviceFound = null;
this.onError = null;
this.lastCardStatus = false;
this.onCardStatusChange = onCardStatusChange;
}

    async checkBluetoothState() {
        try {
            const state = await this.bleManager.state();
            return state === 'PoweredOn';
        } catch (error) {
            console.error('Error checking Bluetooth:', error);
            return false;
        }
    }
    
    startScanning() {
        if (this.scanning) return;
        
        this.scanning = true;
        this.bleManager.startDeviceScan(null, null, (error, device) => {
            if (error) {
                this.scanning = false;
                if (this.onError) this.onError('Scanning error: ' + error);
                return;
            }
    
            if (device?.name?.includes('ACR1255U')) {
                this.stopScanning();
                this.connectToDevice(device);
            }
        });
    }
    
    stopScanning() {
        if (this.scanning) {
            this.bleManager.stopDeviceScan();
            this.scanning = false;
        }
    }
    
    async connectToDevice(device) {
        try {
            console.log('Connecting to device:', device.name);
            const connectedDevice = await device.connect();
            await connectedDevice.discoverAllServicesAndCharacteristics();
            
            if (this.onDeviceFound) {
                this.onDeviceFound(device);
            }
    
            await this.initializeReader(connectedDevice);
            await this.setupCardDetection(connectedDevice);
        } catch (error) {
            console.error('Connection error:', error);
            if (this.onError) this.onError('Connection error: ' + error);
        }
    }
    
    async initializeReader(device) {
        try {
            const initCommands = [
                [0xFF, 0x00, 0x00, 0x00, 0x00], // Reset
                [0xFF, 0x00, 0x00, 0x02, 0x01], // Auto polling on
                [0xFF, 0x00, 0x00, 0x03, 0x01]  // Set operation mode
            ];
    
            for (const cmd of initCommands) {
                await this.sendCommand(device, cmd);
                await new Promise(resolve => setTimeout(resolve, 300));
            }
            console.log('Reader initialized');
        } catch (error) {
            console.error('Error initializing reader:', error);
        }
    }
    
    async setupCardDetection(device) {
        return device.monitorCharacteristicForService(
            this.SERVICE_UUID,
            this.NOTIFY_CHARACTERISTIC,
            (error, characteristic) => {
                if (error) {
                    console.error('Error monitoring characteristic:', error);
                    return;
                }
    
                if (characteristic?.value) {
                    const rawData = this.base64ToArray(characteristic.value);
                    console.log('Raw data:', this.bytesToHex(rawData));
                    this.analyzeResponse(rawData);
                }
            }
        );
    }
    
    analyzeResponse(data) {
        if (!data || data.length === 0) return;
    
        switch(data[0]) {
            case 0x61: // Card status response
                const cardPresent = this.validateCardPresence(data);
                if (cardPresent !== this.lastCardStatus) {
                    this.lastCardStatus = cardPresent;
                    console.log(cardPresent ? '✅ CARD DETECTED' : '❌ NO CARD');
                    if (this.onCardStatusChange) {
                        this.onCardStatusChange(cardPresent);
                    }
                }
                break;
                
            case 0x4E: // No card
                if (this.lastCardStatus) {
                    this.lastCardStatus = false;
                    console.log('❌ NO CARD');
                    if (this.onCardStatusChange) {
                        this.onCardStatusChange(false);
                    }
                }
                break;
        }
    }
    
    validateCardPresence(data) {
        // Specific validation for Mifare Ultralight
        if (data.length < 3) return false;
        
        // Check if there are valid card data
        return data[1] !== 0x00 || data[2] !== 0x00;
    }
    
    async sendCommand(device, command) {
        try {
            const encodedCommand = this.arrayToBase64(command);
            await device.writeCharacteristicWithResponseForService(
                this.SERVICE_UUID,
                this.WRITE_CHARACTERISTIC,
                encodedCommand
            );
            console.log('Command sent:', this.bytesToHex(command));
        } catch (error) {
            console.error('Error sending command:', error);
        }
    }
    
    bytesToHex(bytes) {
        return Array.from(bytes)
            .map(byte => byte.toString(16).padStart(2, '0'))
            .join(' ');
    }
    
    arrayToBase64(array) {
        return base64.encode(String.fromCharCode(...array));
    }
    
    base64ToArray(str) {
        return new Uint8Array(base64.decode(str).split('').map(c => c.charCodeAt(0)));
    }
    
    cleanup() {
        this.stopScanning();
        this.bleManager.destroy();
    }

}

export default NFCReaderApp;

I've tried to test the stuff with differente cards (both Ultralight) and there's no change on the output. Also, I'm sure the reader is working cause when I try to connect it to the BLETest.apk app made by acs, it works fine and even make sounds when gotten closer to the NFC card. The NFC card is working fine as well when put closer to the NFC reader in the phone.

Upvotes: 0

Views: 21

Answers (0)

Related Questions