open method

  1. @override
Future<void> open()
override

Open the transport (idempotent).

Implementation

@override
Future<void> open() async {
  if (_open) return;
  if (_closed) throw StateError('VectorXlCanTransport already closed');

  if (!Platform.isWindows) {
    throw UnsupportedError(
        'VectorXlCanTransport: Vector XL Driver Library is Windows-only');
  }

  final bindings = VectorXlBindings.load(overridePath: libraryPath);
  _bindings = bindings;

  var st = bindings.xlOpenDriver();
  if (st != VectorXlStatus.success) {
    throw StateError('xlOpenDriver failed status=$st');
  }

  final namePtr = appName.toNativeUtf8().cast<Uint8>();
  final portHandlePtr = malloc<Int32>();
  final permPtr = malloc<Uint64>()..value = 0;
  try {
    st = bindings.xlOpenPort(
      portHandlePtr,
      namePtr,
      accessMask,
      permPtr,
      rxQueueSize,
      VectorXlInterfaceVersion.v4,
      VectorXlBusType.can,
    );
    if (st != VectorXlStatus.success) {
      throw StateError(
          'xlOpenPort failed status=$st accessMask=0x${accessMask.toRadixString(16)}');
    }
    _portHandle = portHandlePtr.value;
  } finally {
    malloc.free(namePtr);
    malloc.free(portHandlePtr);
    malloc.free(permPtr);
  }

  final port = _portHandle!;
  st = bindings.xlCanSetChannelBitrate(port, accessMask, bitrate);
  if (st != VectorXlStatus.success) {
    // Roll back the open before throwing.
    bindings.xlClosePort(port);
    bindings.xlCloseDriver();
    _portHandle = null;
    throw StateError('xlCanSetChannelBitrate failed status=$st');
  }

  st = bindings.xlActivateChannel(
      port, accessMask, VectorXlBusType.can, 0);
  if (st != VectorXlStatus.success) {
    bindings.xlClosePort(port);
    bindings.xlCloseDriver();
    _portHandle = null;
    throw StateError('xlActivateChannel failed status=$st');
  }

  _rxEvents = malloc<VectorXlEvent>(_kRxBatch);
  _rxCount = malloc<Uint32>();
  _rxCtrl = StreamController<CanFrame>.broadcast();
  _open = true;
  _startPolling(bindings, port);
}