3 unstable releases

0.2.1 Feb 1, 2023
0.2.0 Jan 18, 2023
0.1.0 Jan 12, 2023

#705 in Hardware support

MIT/Apache

57KB
857 lines

Library for RFID readers by MicroEM company

The library allows control of RFID readers produced by MicroEM company by implementing a protocol used in these readers.

The crate comes with basic objects and a send method used to interact with a reader. The byte sequences used in this method should conform with official documentation for the reader which can be found on MicroEM website.

Currently the crate has been tested with LibUsb on Debian 11.5 x64 and Windows 7x64.

Note that in order to work with Windows you need to install libusb driver first.

On Linux you need to add write permissions to the device you want to use, e.g.:

sudo chmod o+w /dev/bus/usb/002/008

Usage

    use uem_reader::{
        reader::{
            UemReaderInternal,
            usb::find_usb_readers
        },
        commands::{
            UemCommandsTrait,
            reader::UemCommandsReaderTrait, 
            cards::{
                UemCommandsCardsTrait,
                UemActivateParameters,
                mifare::{
                    UemCommandsCardsMifareTrait,
                    classic::UemCommandsCardsMifareClassicTrait
                },
            },
        },
    };

    // Search system for USB readers
    let mut uem_readers = find_usb_readers();

    // Quit if no readers found
    if uem_readers.is_empty() {
        return;
    }

    // Pick the first reader in the vector
    let uem_reader = uem_readers.get_mut(0);

    // Check if the vector returned an option with valid reader object
    if uem_reader.is_none() {
        return;
    }

    // Unwrap the option
    let uem_reader = uem_reader.unwrap();
    
    // Open USB interface connection
    if uem_reader.open().is_err() {
        return;
    }

    // Beep 1 time using command byte vector
    if uem_reader.send(&vec![0x05_u8, 0x01_u8]).is_err() {
        return;
    }

    // Beep 5 times using command grouping objects as separate variables
    let mut uem_cmds = uem_reader.commands();
    let mut uem_cmds_reader = uem_cmds.reader();
    if uem_cmds_reader.beep(5).is_err() {
        return;
    }

    // Beep 3 times using command grouping objects inline
    if uem_reader.commands().reader().beep(3).is_err() {
        return;
    }

    let card = uem_reader.commands().cards().activate_a(&UemActivateParameters{
        // switch_to_tcl: true,
        ..Default::default()
    });

    if card.is_err() {
        uem_reader.close();
        return;
    }

    let card = card.unwrap();

    let res = uem_reader.commands().cards().mifare().classic()
        .authenticate_key_a(
            &card, 
            &[0xFF; 6], 
            1
        );

    if res.is_err() {
        uem_reader.close();
        return;
    }

    let res = uem_reader.commands().cards().mifare().classic()
        .read(1, 1);

    if res.is_err() {
        uem_reader.close();
        return;
    }

    let prev_data = res.unwrap();
    let mut new_data = prev_data.clone();
    new_data[0] = 0xFF;

    let res = uem_reader.commands().cards().mifare().classic()
        .write(new_data.clone(), 1, 1);

    if res.is_err() {
        uem_reader.close();
        return;
    }

    let res = uem_reader.commands().cards().mifare().classic()
        .read(1, 1);

    if res.is_err() {
        uem_reader.close();
        return;
    }

    if res.unwrap() != new_data {
        println!("error!");
        uem_reader.close();
        return;
    }

    let res = uem_reader.commands().cards().mifare().classic()
        .write(prev_data.clone(), 1, 1);

    if res.is_err() {
        uem_reader.close();
        return;
    }

    let res = uem_reader.commands().cards().mifare().classic()
        .read(1, 1);

    if res.is_err() {
        uem_reader.close();
        return;
    }

    if res.unwrap() != prev_data {
        println!("error!");
        uem_reader.close();
        return;
    }

    if uem_reader.close().is_err() {
        return;
    };

License

This work is dual-licensed under MIT or Apache 2.0. You can choose between one of them if you use this work.

SPDX-License-Identifier: MIT OR Apache-2.0

Dependencies

~2.1–3MB
~60K SLoC