Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how about add 'escape' supporting #9

Open
dotnfc opened this issue Jul 1, 2024 · 0 comments
Open

how about add 'escape' supporting #9

dotnfc opened this issue Jul 1, 2024 · 0 comments

Comments

@dotnfc
Copy link

dotnfc commented Jul 1, 2024

for some ccid devices, we have to control it using escape channel.
and the PcscPlatform has only transmit method, so, how about add a escape() method?

just like

  Future<List<int>> escape(
    int hCard, List<int> commandBytes,
      {bool newIsolate = false}) {
    throw UnimplementedError('escapeCommand() has not been implemented.');
  }

for flutter_pcsc_windows

  @override
  Future<List<int>> escape(
      int hCard, List<int> commandBytes, { bool newIsolate = false}) {
    return _binding.escapeCommand(hCard, commandBytes, newIsolate: newIsolate);
  }

for pcsc_binds.dart

  Future<Uint8List> escapeCommand(
      int hCard, List<int> sendCommand,
      {bool newIsolate = false}) {
    if (newIsolate) {
      return _escapeCommandInNewIsolate(hCard, sendCommand);
    } else {
      return _escapeCommandInSameIsolate(hCard, sendCommand);
    }
  }

  Future<Uint8List> _escapeCommandInNewIsolate(
      int hCard, List<int> sendCommand) {
    return compute(_computeFunctionEscapeCommand, {
      'h_card': hCard,
      'command': sendCommand
    });
  }

  Future<Uint8List> _escapeCommandInSameIsolate(
      int hCard, List<int> sendCommand) {
    var nativeSendCommand = _allocateNative(sendCommand);

    var pcbRecvLength = calloc<DWORD>();
    pcbRecvLength.value = PcscConstants.MAX_BUFFER_SIZE;
    var pbRecvBuffer = calloc<ffi.Uint8>(pcbRecvLength.value);

    // #define IOCTL_CCID_ESCAPE   SCARD_CTL_CODE(3500)
    int dwControlCode = 0x310000 + 3500*4;

    try {

      var res = _nlwinscard.SCardControl(hCard, dwControlCode, nativeSendCommand.cast(),
          sendCommand.length, pbRecvBuffer.cast(), pcbRecvLength.value, pcbRecvLength);
      _checkAndThrow(res, 'Error while transmitting to ccid device');

      Uint8List response = _asUint8List(pbRecvBuffer, pcbRecvLength.value);

      return Future.value(response);
    } finally {
      calloc.free(nativeSendCommand);
      calloc.free(pcbRecvLength);
      calloc.free(pbRecvBuffer);
    }
  }

and when we connect a device, we should do

pcscCard = await Pcsc.cardConnect(pcscCtx, readerName, PcscShare.direct, PcscProtocol.undefined);

at the same time, a reset() method can be implemented to do a cold/warm reseting a card.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant