apdu library

ISO 7816-4 command APDUs, status words, and response chaining.

Like the NDEF codec, none of this needs a tag: CommandApdu encodes, StatusWord decodes, and both can be exercised in a unit test on a machine with no NFC radio at all. Iso7816Chaining does talk to a card, but only through a function you hand it, so it belongs to neither platform and works with both.

What the platform libraries give you is a way to move bytes -- Iso7816.sendCommandRaw on iOS, IsoDep.transceive on Android. What they do not give you is the protocol: nothing builds an extended-length APDU, nothing tells you what 6A82 means, and nothing follows a 61xx chain, so a caller who does not know to loop gets a silently truncated answer. This library is that missing half.

import 'package:nfc_util/apdu.dart';
import 'package:nfc_util/ios.dart' as ios;

final card = ios.Iso7816.from(tag)!;
final response = await Iso7816Chaining(card.sendCommandRaw).sendCommand(
  CommandApdu(
    instructionClass: 0x00,
    instructionCode: 0xA4,
    p1Parameter: 0x04,
    p2Parameter: 0x00,
    data: applicationId,
    expectedResponseLength: 256,
  ),
);

if (response.status case StatusWordError(reason: final reason)) {
  throw StateError('SELECT refused: ${reason ?? response.status}');
}

Classes

CommandApdu
One ISO 7816-4 command APDU, and the rules for putting it on the wire.
Iso7816Chaining
ISO 7816-4 response chaining, wrapped around a transceive function you already have.
Iso7816ResponseApdu
The two status bytes an ISO 7816 card answers with, plus its payload.
StatusWord
What a card said in its two status bytes, decoded.
StatusWordError
SW1 in 64..6F: the card refused the command and ran nothing.
StatusWordMoreData
61xx. The command completed and remainingBytes more bytes are waiting behind a GET RESPONSE.
StatusWordSuccess
9000. The command completed and the card has nothing further to hand over.
StatusWordUnrecognised
A status word that fits none of the shapes ISO 7816-4 defines.
StatusWordWarning
62xx and 63xx. The command ran, with something the caller should know about.
StatusWordWrongLength
6Cxx. The Le the command carried was wrong, and correctLength is the one to re-send it with. The card ran nothing and answered with no data.

Enums

StatusWordErrorReason
The status words worth branching on by name, ordered as the specification numbers them.