private void DownstreamThreadProc() { while (!_disposed) { // Fetch a Telegram and Signal any waiting threads // (Note: this will always be a Scan-Data telegram because the thread will be suspended for all other communications.) _lastTelegram = _client.ReceiveTelegram(); _downstreamTurnstile.Set(); } }
protected override void UpdateImpl() { if ((null == _client) || (!_client.IsConnected) || (null == _downstreamTurnstile)) { throw new InvalidOperationException($"{Name} disconnected"); } try { // Wait for the next Scan-Data Telegram _downstreamTurnstile.WaitOne(); CoLaBTelegram scanDataTelegram = _lastTelegram; NetworkBinaryReader scanData = new NetworkBinaryReader(scanDataTelegram); // Miscellaneous Metadata UInt16 versionNumber = scanData.ReadUInt16(); if (1 != versionNumber) { log.Warn($"{Name}: unexpected version number in telegram: {versionNumber}"); } scanData.Skip(2); UInt32 serialNumber = scanData.ReadUInt32(); if (_serialNumber != serialNumber) { _serialNumber = serialNumber; base.serialNumber = serialNumber.ToString(); } scanData.Skip(1); byte deviceStatus = scanData.ReadByte(); if (0 != deviceStatus) { log.Error($"{Name}: unexpected device status: {deviceStatus}"); } scanData.Skip(2); _scanCounter = scanData.ReadUInt16(); scanData.Skip(4); _timeStamp = scanData.ReadUInt32(); // Skip: input states, output states, reserved bytes, frequency information, encoders scanData.Skip(2 + 2 + 2 + 4 + 4 + 2); // 16-bit Channels UInt16 channelCount16 = scanData.ReadUInt16(); if (1 != channelCount16) { log.Error($"{Name}: unexpected number of 16-bit channels: {channelCount16}"); } _channelName = scanData.ReadString(5); _scalingFactor = scanData.ReadSingle() * 0.001f; float scalingOffset = scanData.ReadSingle(); int startingAngle = scanData.ReadInt32(); int angularStepWidth = (int)scanData.ReadUInt16(); if ((_startingAngle != startingAngle) || (_angularStepWidth != angularStepWidth)) { _startingAngle = startingAngle; _angularStepWidth = angularStepWidth; _directions = null; } int dataCount = (int)scanData.ReadUInt16(); // Initialize or Reinitialize array of Polar Radii if (null == _radii) { _radii = new UInt16[dataCount]; _directions = null; } else if (_radii.Length != dataCount) { Array.Resize(ref _radii, dataCount); _directions = null; } // Read 16-bit unsigned pixels (reversed) for (int i = (dataCount - 1); i >= 0; --i) { _radii[i] = scanData.ReadUInt16(); } } catch (MetriCam2Exception) { // Pass MetriCam API Exceptions without alteration throw; } catch (Exception foreignException) { // Wrap and Throw other exceptions encountered during Connection throw ExceptionBuilder.Build(typeof(ImageAcquisitionFailedException), Name, foreignException.Message, foreignException); } }
protected override void ConnectImpl() { try { // Reinitialize a Disconnected Client if ((null != _client) && (!_client.IsConnected)) { _client.Dispose(); _client = null; } // Connect when necessary if (null == _client) { _client = CoLaBClient.Connect(_remoteEndPoint); log.Debug($"{Name}: connected to {_remoteEndPoint}"); try { // Request Scan-Data Telegrams CoLaBTelegram acknowledgement = _client.SendTelegram(CoLaCommandType.Event, "LMDscandata", (telegramWriter) => { telegramWriter.Write(0x01); }, acknowledgeTimeout: _timeoutMilliseconds); if (acknowledgement.Data[acknowledgement.Offset] != 0) { log.Debug($"{Name}: CoLa (binary) telegram subscription established"); } else { throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, "error_connectionFailed", "CoLa (binary) telegram subscription failed"); } } catch { // Dispose the TCP/IP Client immediately try { _client.Dispose(); _client = null; } catch { // Suppress secondary exceptions } // Rethrow the original exception throw; } // Begin receiving telegrams in a background thread _downstreamThread = new Thread(DownstreamThreadProc); _downstreamThread.Name = Name; _downstreamThread.IsBackground = true; _downstreamThread.Start(); } } catch (MetriCam2Exception) { // Pass MetriCam API Exceptions without alteration throw; } catch (Exception foreignException) { // Wrap and Throw other exceptions encountered during Connection throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, foreignException.Message, foreignException); } }