protected override void init() { queryLogConfigTask = new TimedTask <byte[]>(); createLoggerTask = new TimedTask <byte>(); queryEntriesTask = new TimedTask <byte[]>(); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, Util.setRead(TRIGGER)), response => queryLogConfigTask.SetResult(response)); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, TRIGGER), response => createLoggerTask.SetResult(response[2])); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, READOUT_NOTIFY), response => { void processLogData(byte[] logEntry, int offset) { byte logId = (byte)(logEntry[0 + offset] & 0x1f), resetUid = (byte)((logEntry[0 + offset] & ~0x1f) >> 5); uint tick = BitConverter.ToUInt32(logEntry, 1 + offset); if (!rollbackTimestamps.TryGetValue(resetUid, out uint rollback) || rollback < tick) { var timestamp = computeTimestamp(resetUid, tick); byte[] logData = new byte[LOG_ENTRY_SIZE]; Array.Copy(logEntry, 5 + offset, logData, 0, LOG_ENTRY_SIZE); if (dataLoggers.TryGetValue(logId, out var logger)) { logger.handleLogMessage(bridge, logId, timestamp, logData, errorHandler); } else { errorHandler?.Invoke(LogDownloadError.UNKNOWN_LOG_ENTRY, logId, timestamp, logData); } } }; processLogData(response, 2); if (response.Length == 20) { processLogData(response, 11); } }); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, Util.setRead(TIME)), response => { // if in the middle of a log download, don't update the reference // rollbackTimestamps var is cleared after readout progress hits 0 if (rollbackTimestamps.Count == 0) { uint tick = BitConverter.ToUInt32(response, 2); byte resetUid = (response.Length > 6) ? response[6] : (byte)0xff; latestReference = new TimeReference { resetUid = resetUid, tick = tick, timestamp = DateTime.Now }; if (resetUid != 0xff) { logReferenceTicks[resetUid] = latestReference; } } if (queryTimeTask != null) { queryTimeTask.SetResult(true); queryTimeTask = null; } }); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, Util.setRead(LENGTH)), response => queryEntriesTask.SetResult(response)); }
protected override void init() { queryLogConfigTask = new TimedTask <byte[]>(); createLoggerTask = new TimedTask <byte>(); if (rollbackTimestamps == null) { rollbackTimestamps = new Dictionary <byte, uint>(); } bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, Util.setRead(TRIGGER)), response => queryLogConfigTask.SetResult(response)); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, TRIGGER), response => createLoggerTask.SetResult(response[2])); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, READOUT_NOTIFY), response => { processLogData(response, 2); if (response.Length == 20) { processLogData(response, 11); } }); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, READOUT_PROGRESS), response => { uint nEntriesLeft = BitConverter.ToUInt32(response, 2); if (nEntriesLeft == 0) { rollbackTimestamps.Clear(); downloadTask.SetResult(true); downloadTask = null; } else { updateHandler?.Invoke(nEntriesLeft, nLogEntries); } }); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, Util.setRead(TIME)), response => { // if in the middle of a log download, don't update the reference // rollbackTimestamps var is cleared after readout progress hits 0 if (rollbackTimestamps.Count == 0) { uint tick = BitConverter.ToUInt32(response, 2); byte resetUid = (response.Length > 6) ? response[6] : (byte)0xff; latestReference = new TimeReference(resetUid, tick, DateTime.Now); if (resetUid != 0xff) { logReferenceTicks[resetUid] = latestReference; } } if (queryTimeTask != null) { queryTimeTask.SetResult(true); queryTimeTask = null; } }); bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, Util.setRead(LENGTH)), response => { int payloadSize = response.Length - 2; nLogEntries = BitConverter.ToUInt32(response, 2); if (nLogEntries == 0) { rollbackTimestamps.Clear(); downloadTask.SetResult(true); downloadTask = null; } else { updateHandler?.Invoke(nLogEntries, nLogEntries); uint nEntriesNotify = nUpdates == 0 ? 0 : (uint)(nLogEntries * (1.0 / nUpdates)); // In little endian, [A, B, 0, 0] is equal to [A, B] byte[] command = new byte[payloadSize + sizeof(uint)]; Array.Copy(response, 2, command, 0, payloadSize); Array.Copy(BitConverter.GetBytes(nEntriesNotify), 0, command, payloadSize, sizeof(uint)); bridge.sendCommand(LOGGING, READOUT, command); } }); if (bridge.lookupModuleInfo(LOGGING).revision >= REVISION_EXTENDED_LOGGING) { bridge.addRegisterResponseHandler(Tuple.Create((byte)LOGGING, READOUT_PAGE_COMPLETED), response => bridge.sendCommand(new byte[] { (byte)LOGGING, READOUT_PAGE_CONFIRM })); } }