From caf7f499bde60d7e689f65f95c516fbbe6471e3a Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Thu, 25 Mar 2021 17:26:50 +0100 Subject: [PATCH] Use common logging provider (#1497) * Use common logging provider for Arduino binding * Use common logging for card reader * Use common logging for Pn532 * Use common logging for Pn5180 * Use common logging for Mfrc522 --- eng/Versions.props | 1 + src/devices/Arduino/ArduinoBoard.cs | 34 +++-- .../Arduino/ArduinoGpioControllerDriver.cs | 8 +- .../Arduino/samples/Arduino.Monitor.cs | 1 - .../Arduino/samples/Arduino.Monitor.csproj | 1 + src/devices/Arduino/samples/Arduino.sample.cs | 11 +- .../Arduino/samples/Arduino.sample.csproj | 2 + .../Arduino/tests/Arduino.Tests.csproj | 2 + .../Arduino/tests/FirmataTestFixture.cs | 12 +- src/devices/Card/Card.sln | 33 ++++- src/devices/Card/CreditCard/CreditCard.cs | 21 +-- .../CreditCard/CreditCardProcessing.csproj | 1 + src/devices/Card/LogInfo.cs | 84 ----------- src/devices/Card/Mifare/Mifare.csproj | 1 + src/devices/Card/Mifare/MifareCard.cs | 7 +- .../Card/Ndef/samples/NdefSamples.csproj | 3 + src/devices/Card/Ndef/samples/Program.cs | 18 ++- .../Iot/Device/Common/DebuggerOutputLogger.cs | 55 +++++++ .../Common/DebuggerOutputLoggerProvider.cs | 29 ++++ .../Common/samples/Common.Samples.csproj | 2 +- src/devices/Mfrc522/Mfrc522.cs | 10 +- src/devices/Pn5180/Pn5180.cs | 137 ++++++------------ src/devices/Pn532/Pn532.cs | 128 +++++++--------- src/devices/Pn532/Pn532.csproj | 1 + src/devices/Pn532/samples/Pn532sample.csproj | 2 +- src/devices/Pn532/samples/Program.cs | 20 ++- 26 files changed, 318 insertions(+), 306 deletions(-) delete mode 100644 src/devices/Card/LogInfo.cs create mode 100644 src/devices/Common/Iot/Device/Common/DebuggerOutputLogger.cs create mode 100644 src/devices/Common/Iot/Device/Common/DebuggerOutputLoggerProvider.cs diff --git a/eng/Versions.props b/eng/Versions.props index 8cf9fde7..4403e2c3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,6 +13,7 @@ 4.5.4 4.3.0 4.77.0 + 5.0.0 5.0.0 5.0.0 1.0.2 diff --git a/src/devices/Arduino/ArduinoBoard.cs b/src/devices/Arduino/ArduinoBoard.cs index d8ae41c1..fc4126e5 100644 --- a/src/devices/Arduino/ArduinoBoard.cs +++ b/src/devices/Arduino/ArduinoBoard.cs @@ -17,6 +17,8 @@ using System.IO; using System.IO.Ports; using System.Threading; using System.Linq; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; using UnitsNet; namespace Iot.Device.Arduino @@ -44,6 +46,8 @@ namespace Iot.Device.Arduino private object _initializationLock = new object(); + private ILogger _logger; + /// /// Creates an instance of an Ardino board connection using the given stream (typically from a serial port) /// @@ -54,6 +58,7 @@ namespace Iot.Device.Arduino public ArduinoBoard(Stream serialPortStream) { _dataStream = serialPortStream ?? throw new ArgumentNullException(nameof(serialPortStream)); + _logger = this.GetCurrentClassLogger(); } /// @@ -67,12 +72,13 @@ namespace Iot.Device.Arduino { _dataStream = null; _serialPort = new SerialPort(portName, baudRate); + _logger = this.GetCurrentClassLogger(); } /// - /// Attach to this event to retrieve log messages. The Exception argument may be null if it is only an informational message. + /// The board logger. /// - public event Action? LogMessages; + protected ILogger Logger => _logger; /// /// Searches the given list of com ports for a firmata device. @@ -202,21 +208,21 @@ namespace Iot.Device.Arduino throw new NotSupportedException($"Firmata version on board is {_firmataVersion}. Expected {_firmata.QuerySupportedFirmataVersion()}. They must be equal."); } - Log($"Firmata version on board is {_firmataVersion}."); + Logger.LogInformation($"Firmata version on board is {_firmataVersion}."); _firmwareVersion = _firmata.QueryFirmwareVersion(out var firmwareName); _firmwareName = firmwareName; - Log($"Firmware version on board is {_firmwareVersion}"); + Logger.LogInformation($"Firmware version on board is {_firmwareVersion}"); _firmata.QueryCapabilities(); _supportedPinConfigurations = _firmata.PinConfigurations.AsReadOnly(); - Log("Device capabilities: "); + Logger.LogInformation("Device capabilities: "); foreach (var pin in _supportedPinConfigurations) { - Log(pin.ToString()); + Logger.LogInformation(pin.ToString()); } _firmata.EnableDigitalReporting(); @@ -291,14 +297,16 @@ namespace Iot.Device.Arduino } } - internal void Log(string message) - { - LogMessages?.Invoke(message, null); - } - - private void FirmataOnError(string message, Exception? innerException) + private void FirmataOnError(string message, Exception? exception) { - LogMessages?.Invoke(message, innerException); + if (exception != null) + { + Logger.LogError(exception, message); + } + else + { + Logger.LogInformation(message); + } } /// diff --git a/src/devices/Arduino/ArduinoGpioControllerDriver.cs b/src/devices/Arduino/ArduinoGpioControllerDriver.cs index e0899b7c..e48b2b04 100644 --- a/src/devices/Arduino/ArduinoGpioControllerDriver.cs +++ b/src/devices/Arduino/ArduinoGpioControllerDriver.cs @@ -7,6 +7,8 @@ using System.Collections.Generic; using System.Device.Gpio; using System.Linq; using System.Threading; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; namespace Iot.Device.Arduino { @@ -18,6 +20,7 @@ namespace Iot.Device.Arduino private readonly ConcurrentDictionary _pinModes; private readonly object _callbackContainersLock; private readonly AutoResetEvent _waitForEventResetEvent; + private readonly ILogger _logger; internal ArduinoGpioControllerDriver(ArduinoBoard arduinoBoard, IReadOnlyCollection supportedPinConfigurations) { @@ -27,6 +30,7 @@ namespace Iot.Device.Arduino _waitForEventResetEvent = new AutoResetEvent(false); _callbackContainersLock = new object(); _pinModes = new ConcurrentDictionary(); + _logger = this.GetCurrentClassLogger(); PinCount = _supportedPinConfigurations.Count; _arduinoBoard.Firmata.DigitalPortValueUpdated += FirmataOnDigitalPortValueUpdated; @@ -66,12 +70,14 @@ namespace Iot.Device.Arduino firmataMode = SupportedMode.DigitalInput; break; default: + _logger.LogError($"Mode {mode} is not supported as argument to {nameof(SetPinMode)}"); throw new NotSupportedException($"Mode {mode} is not supported for this operation"); } var pinConfig = _supportedPinConfigurations.FirstOrDefault(x => x.Pin == pinNumber); if (pinConfig == null || !pinConfig.PinModes.Contains(firmataMode)) { + _logger.LogError($"Mode {mode} is not supported on Pin {pinNumber}"); throw new NotSupportedException($"Mode {mode} is not supported on Pin {pinNumber}."); } @@ -104,7 +110,7 @@ namespace Iot.Device.Arduino ret = PinMode.Input; break; default: - _arduinoBoard.Log($"Unexpected pin mode found: {mode}. Is the pin not set to GPIO?"); + _logger.LogError($"Unexpected pin mode found: {mode}. Is the pin not set to GPIO?"); ret = PinMode.Input; break; } diff --git a/src/devices/Arduino/samples/Arduino.Monitor.cs b/src/devices/Arduino/samples/Arduino.Monitor.cs index cc941583..ae6dba2d 100644 --- a/src/devices/Arduino/samples/Arduino.Monitor.cs +++ b/src/devices/Arduino/samples/Arduino.Monitor.cs @@ -54,7 +54,6 @@ namespace Arduino.Samples ArduinoBoard board = new ArduinoBoard(port.BaseStream); try { - board.LogMessages += BoardOnLogMessages; Console.WriteLine($"Firmware version: {board.FirmwareVersion}, Builder: {board.FirmwareName}"); DisplayModes(board); } diff --git a/src/devices/Arduino/samples/Arduino.Monitor.csproj b/src/devices/Arduino/samples/Arduino.Monitor.csproj index 35a0ce43..0bf30e90 100644 --- a/src/devices/Arduino/samples/Arduino.Monitor.csproj +++ b/src/devices/Arduino/samples/Arduino.Monitor.csproj @@ -5,6 +5,7 @@ net5.0;netcoreapp2.1 Iot.Device.Arduino.Sample false + Arduino.Monitor diff --git a/src/devices/Arduino/samples/Arduino.sample.cs b/src/devices/Arduino/samples/Arduino.sample.cs index 3014a9b3..faa44f24 100644 --- a/src/devices/Arduino/samples/Arduino.sample.cs +++ b/src/devices/Arduino/samples/Arduino.sample.cs @@ -18,6 +18,8 @@ using Iot.Device.Adc; using Iot.Device.Arduino; using Iot.Device.Bmxx80; using Iot.Device.Bmxx80.PowerMode; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; using UnitsNet; namespace Arduino.Samples @@ -38,6 +40,14 @@ namespace Arduino.Samples string portName = args[0]; + var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole(); + }); + + // Statically register our factory. Note that this must be done before instantiation of any class that wants to use logging. + LogDispatcher.LoggerFactory = loggerFactory; + using (var port = new SerialPort(portName, 115200)) { Console.WriteLine($"Connecting to Arduino on {portName}"); @@ -54,7 +64,6 @@ namespace Arduino.Samples ArduinoBoard board = new ArduinoBoard(port.BaseStream); try { - board.LogMessages += BoardOnLogMessages; // This implicitly connects Console.WriteLine($"Connecting... Firmware version: {board.FirmwareVersion}, Builder: {board.FirmwareName}"); while (Menu(board)) diff --git a/src/devices/Arduino/samples/Arduino.sample.csproj b/src/devices/Arduino/samples/Arduino.sample.csproj index 262cd065..cad3e185 100644 --- a/src/devices/Arduino/samples/Arduino.sample.csproj +++ b/src/devices/Arduino/samples/Arduino.sample.csproj @@ -5,9 +5,11 @@ net5.0;netcoreapp2.1 Iot.Device.Arduino.Sample false + Arduino.sample + diff --git a/src/devices/Arduino/tests/Arduino.Tests.csproj b/src/devices/Arduino/tests/Arduino.Tests.csproj index 4277925d..ea5d2630 100644 --- a/src/devices/Arduino/tests/Arduino.Tests.csproj +++ b/src/devices/Arduino/tests/Arduino.Tests.csproj @@ -11,6 +11,8 @@ + + diff --git a/src/devices/Arduino/tests/FirmataTestFixture.cs b/src/devices/Arduino/tests/FirmataTestFixture.cs index f3ed85a7..aa621a15 100644 --- a/src/devices/Arduino/tests/FirmataTestFixture.cs +++ b/src/devices/Arduino/tests/FirmataTestFixture.cs @@ -8,6 +8,8 @@ using System.Net; using System.Net.Sockets; using System.Text; using Iot.Device.Arduino; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; using Xunit; namespace Arduino.Tests @@ -21,6 +23,13 @@ namespace Arduino.Tests { try { + var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole().AddProvider(new DebuggerOutputLoggerProvider()); + }); + + // Statically register our factory. Note that this must be done before instantiation of any class that wants to use logging. + LogDispatcher.LoggerFactory = loggerFactory; _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(IPAddress.Loopback, 27016); _socket.NoDelay = true; @@ -32,8 +41,6 @@ namespace Arduino.Tests throw new NotSupportedException("Very old firmware found"); } - Board.LogMessages += (x, y) => Console.WriteLine(x); - return; } catch (SocketException) @@ -48,7 +55,6 @@ namespace Arduino.Tests } Board = board; - Board.LogMessages += (x, y) => Console.WriteLine(x); } public ArduinoBoard? Board diff --git a/src/devices/Card/Card.sln b/src/devices/Card/Card.sln index d970a9aa..70cbfed9 100644 --- a/src/devices/Card/Card.sln +++ b/src/devices/Card/Card.sln @@ -1,13 +1,15 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31105.61 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardRfid", "CardRfid.csproj", "{2B97523A-956B-4C88-8931-28C1AF88012C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CardRfid", "CardRfid.csproj", "{2B97523A-956B-4C88-8931-28C1AF88012C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreditCardProcessing", "CreditCard\CreditCardProcessing.csproj", "{A9AC5868-77E7-4742-AF7E-E140F2CFF79B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreditCardProcessing", "CreditCard\CreditCardProcessing.csproj", "{A9AC5868-77E7-4742-AF7E-E140F2CFF79B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mifare", "Mifare\Mifare.csproj", "{81A964D2-BA4B-4769-A630-084D8C4BEBDA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mifare", "Mifare\Mifare.csproj", "{81A964D2-BA4B-4769-A630-084D8C4BEBDA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonHelpers", "..\Common\CommonHelpers.csproj", "{03F9B2A3-4B73-4D39-872B-BB0D81F3593E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,9 +20,6 @@ Global Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2B97523A-956B-4C88-8931-28C1AF88012C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2B97523A-956B-4C88-8931-28C1AF88012C}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -58,5 +57,23 @@ Global {81A964D2-BA4B-4769-A630-084D8C4BEBDA}.Release|x64.Build.0 = Release|Any CPU {81A964D2-BA4B-4769-A630-084D8C4BEBDA}.Release|x86.ActiveCfg = Release|Any CPU {81A964D2-BA4B-4769-A630-084D8C4BEBDA}.Release|x86.Build.0 = Release|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Debug|x64.ActiveCfg = Debug|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Debug|x64.Build.0 = Debug|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Debug|x86.ActiveCfg = Debug|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Debug|x86.Build.0 = Debug|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Release|Any CPU.Build.0 = Release|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Release|x64.ActiveCfg = Release|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Release|x64.Build.0 = Release|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Release|x86.ActiveCfg = Release|Any CPU + {03F9B2A3-4B73-4D39-872B-BB0D81F3593E}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D4095E39-2A90-408C-900D-6596AAC77EDA} EndGlobalSection EndGlobal diff --git a/src/devices/Card/CreditCard/CreditCard.cs b/src/devices/Card/CreditCard/CreditCard.cs index b885a96d..fb8ebc8c 100644 --- a/src/devices/Card/CreditCard/CreditCard.cs +++ b/src/devices/Card/CreditCard/CreditCard.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Reflection.PortableExecutable; using System.Text; using Iot.Device.Common; +using Microsoft.Extensions.Logging; namespace Iot.Device.Card.CreditCardProcessing { @@ -36,6 +37,7 @@ namespace Iot.Device.Card.CreditCardProcessing private CardTransceiver _nfc; private bool _alreadyReadSfi = false; private byte _target; + private ILogger _logger; /// /// The size of the tailer elements. Some readers add an extra byte @@ -68,6 +70,7 @@ namespace Iot.Device.Card.CreditCardProcessing Tags = new List(); LogEntries = new List(); TailerSize = tailerSize; + _logger = this.GetCurrentClassLogger(); } /// @@ -354,7 +357,7 @@ namespace Iot.Device.Card.CreditCardProcessing List appTemplates = Tag.SearchTag(Tags, 0x61); if (appTemplates.Count > 0) { - LogInfo.Log($"Number of App Templates: {appTemplates.Count}", LogLevel.Debug); + _logger.LogDebug($"Number of App Templates: {appTemplates.Count}"); foreach (var app in appTemplates) { // Find the Application Identifier 0x4F @@ -369,7 +372,7 @@ namespace Iot.Device.Card.CreditCardProcessing } // do we have a PDOL tag 0x9F38 - LogInfo.Log($"APPID: {BitConverter.ToString(appIdentifier.Data)}, Priority: {appPriotity.Data[0]}", LogLevel.Debug); + _logger.LogDebug($"APPID: {BitConverter.ToString(appIdentifier.Data)}, Priority: {appPriotity.Data[0]}"); var ret = Select(appIdentifier.Data); if (ret == ErrorType.ProcessCompletedNormal) { @@ -504,7 +507,7 @@ namespace Iot.Device.Card.CreditCardProcessing for (byte record = detail.Start; record < detail.End + 1; record++) { ret = ReadRecord(detail.Sfi, record); - LogInfo.Log($"Read record {record}, SFI {detail.Sfi}, status: {ret}", LogLevel.Debug); + _logger.LogDebug($"Read record {record}, SFI {detail.Sfi}, status: {ret}"); } } @@ -522,7 +525,7 @@ namespace Iot.Device.Card.CreditCardProcessing for (byte sfi = 1; sfi < 11; sfi++) { ret = ReadRecord(sfi, record); - LogInfo.Log($"Read record {record}, SFI {sfi}, status: {ret}", LogLevel.Debug); + _logger.LogDebug($"Read record {record}, SFI {sfi}, status: {ret}"); } } @@ -545,11 +548,11 @@ namespace Iot.Device.Card.CreditCardProcessing var appSfi = Tag.SearchTag(Tags, 0x88).FirstOrDefault(); if (appSfi is object) { - LogInfo.Log($"AppSFI: {appSfi.Data[0]}", LogLevel.Debug); + _logger.LogDebug($"AppSFI: {appSfi.Data[0]}"); for (byte record = 1; record < 10; record++) { var ret = ReadRecord(appSfi.Data[0], record); - LogInfo.Log($"Read record {record}, SFI {appSfi.Data[0]}, status: {ret}", LogLevel.Debug); + _logger.LogDebug($"Read record {record}, SFI {appSfi.Data[0]}, status: {ret}"); } _alreadyReadSfi = true; @@ -567,7 +570,7 @@ namespace Iot.Device.Card.CreditCardProcessing for (byte record = 1; record < numberOfRecords + 1; record++) { var ret = ReadRecord(sfi, record, true); - LogInfo.Log($"Read record {record}, SFI {sfi},status: {ret}", LogLevel.Debug); + _logger.LogDebug($"Read record {record}, SFI {sfi},status: {ret}"); } } @@ -718,11 +721,11 @@ namespace Iot.Device.Card.CreditCardProcessing } FillTagList(Tags, received.Slice(0, ret - TailerSize)); - LogInfo.Log($"{BitConverter.ToString(received.Slice(0, ret).ToArray())}", LogLevel.Debug); + _logger.LogDebug($"{BitConverter.ToString(received.Slice(0, ret).ToArray())}"); var ber = new BerSplitter(received.Slice(0, ret - TailerSize)); foreach (var b in ber.Tags) { - LogInfo.Log($"DataType: {dataType}, Tag: {b.TagNumber.ToString("X4")}, Data: {BitConverter.ToString(b.Data)}", LogLevel.Debug); + _logger.LogDebug($"DataType: {dataType}, Tag: {b.TagNumber.ToString("X4")}, Data: {BitConverter.ToString(b.Data)}"); } return new ProcessError(received.Slice(ret - TailerSize)).ErrorType; diff --git a/src/devices/Card/CreditCard/CreditCardProcessing.csproj b/src/devices/Card/CreditCard/CreditCardProcessing.csproj index 6a45c3f3..8e9fdb6f 100644 --- a/src/devices/Card/CreditCard/CreditCardProcessing.csproj +++ b/src/devices/Card/CreditCard/CreditCardProcessing.csproj @@ -10,6 +10,7 @@ + diff --git a/src/devices/Card/LogInfo.cs b/src/devices/Card/LogInfo.cs deleted file mode 100644 index 8e6f81d1..00000000 --- a/src/devices/Card/LogInfo.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; - -namespace Iot.Device.Card -{ - /// - /// The log level - /// - public enum LogLevel - { - /// - /// No log level - /// - None = 0, - - /// - /// Only information - /// - Info = 1, - - /// - /// Deep log for debug purpose - /// - Debug = 2 - } - - /// - /// Output where to log the information - /// - [Flags] - public enum LogTo - { - /// - /// Log to console - /// - Console = 0b0000_00001, - - /// - /// Log to debug - /// - Debug = 0b0000_0010 - } - - /// - /// Simple log class to help in debugging the communication - /// between the PN532 and the host - /// - public class LogInfo - { - /// - /// Log Level - /// - public static LogLevel LogLevel { get; set; } - - /// - /// Log to - /// - public static LogTo LogTo { get; set; } = LogTo.Console; - - /// - /// Log something - /// - /// String to log - /// Log level - public static void Log(string toLog, LogLevel logLevel) - { - if (LogLevel >= logLevel) - { - if ((LogTo & LogTo.Console) == LogTo.Console) - { - Console.WriteLine(toLog); - } - - if ((LogTo & LogTo.Debug) == LogTo.Debug) - { - Debug.WriteLine(toLog); - } - } - } - } -} diff --git a/src/devices/Card/Mifare/Mifare.csproj b/src/devices/Card/Mifare/Mifare.csproj index ed56d164..d2654733 100644 --- a/src/devices/Card/Mifare/Mifare.csproj +++ b/src/devices/Card/Mifare/Mifare.csproj @@ -5,6 +5,7 @@ + diff --git a/src/devices/Card/Mifare/MifareCard.cs b/src/devices/Card/Mifare/MifareCard.cs index ec114740..8affa771 100644 --- a/src/devices/Card/Mifare/MifareCard.cs +++ b/src/devices/Card/Mifare/MifareCard.cs @@ -3,7 +3,9 @@ using System; using System.Linq; +using Iot.Device.Common; using Iot.Device.Ndef; +using Microsoft.Extensions.Logging; namespace Iot.Device.Card.Mifare { @@ -27,6 +29,8 @@ namespace Iot.Device.Card.Mifare // This is the actual RFID reader private CardTransceiver _rfid; + private ILogger _logger; + /// /// Default Key A /// @@ -98,6 +102,7 @@ namespace Iot.Device.Card.Mifare { _rfid = rfid; Target = target; + _logger = this.GetCurrentClassLogger(); } /// @@ -113,7 +118,7 @@ namespace Iot.Device.Card.Mifare } var ret = _rfid.Transceive(Target, Serialize(), dataOut.AsSpan()); - LogInfo.Log($"{nameof(RunMifareCardCommand)}: {Command}, Target: {Target}, Data: {BitConverter.ToString(Serialize())}, Success: {ret}, Dataout: {BitConverter.ToString(dataOut)}", LogLevel.Debug); + _logger.LogDebug($"{nameof(RunMifareCardCommand)}: {Command}, Target: {Target}, Data: {BitConverter.ToString(Serialize())}, Success: {ret}, Dataout: {BitConverter.ToString(dataOut)}"); if ((ret > 0) && (Command == MifareCardCommand.Read16Bytes)) { Data = dataOut; diff --git a/src/devices/Card/Ndef/samples/NdefSamples.csproj b/src/devices/Card/Ndef/samples/NdefSamples.csproj index c5c918f6..c41cc20e 100644 --- a/src/devices/Card/Ndef/samples/NdefSamples.csproj +++ b/src/devices/Card/Ndef/samples/NdefSamples.csproj @@ -5,6 +5,9 @@ net5.0 + + + diff --git a/src/devices/Card/Ndef/samples/Program.cs b/src/devices/Card/Ndef/samples/Program.cs index 2bd6723c..0867253c 100644 --- a/src/devices/Card/Ndef/samples/Program.cs +++ b/src/devices/Card/Ndef/samples/Program.cs @@ -9,12 +9,14 @@ using System.Text; using System.Threading; using Iot.Device.Card; using Iot.Device.Card.Mifare; +using Iot.Device.Common; using Iot.Device.Ft4222; using Iot.Device.Ndef; using Iot.Device.Pn5180; using Iot.Device.Pn532; using Iot.Device.Pn532.ListPassive; using Iot.Device.Rfid; +using Microsoft.Extensions.Logging; Pn5180 pn5180; Pn532 pn532; @@ -96,7 +98,15 @@ else Console.WriteLine("Do you want log level to Debug? Y/N"); var debugLevelConsole = Console.ReadKey(); Console.WriteLine(); - LogLevel debugLevel = debugLevelConsole is { KeyChar: 'Y' or 'y' } ? LogLevel.Debug : LogLevel.None; + LogLevel debugLevel = debugLevelConsole is { KeyChar: 'Y' or 'y' } ? LogLevel.Debug : LogLevel.Information; + + var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddFilter(x => x >= debugLevel); + builder.AddConsole(); + }); + + LogDispatcher.LoggerFactory = loggerFactory; switch (choiceInterface.KeyChar) { @@ -114,16 +124,16 @@ else return; } - pn532 = new Pn532(SpiDevice.Create(new SpiConnectionSettings(0)), pinSelect, logLevel: debugLevel); + pn532 = new Pn532(SpiDevice.Create(new SpiConnectionSettings(0)), pinSelect); break; case '2': - pn532 = new Pn532(I2cDevice.Create(new I2cConnectionSettings(1, Pn532.I2cDefaultAddress)), debugLevel); + pn532 = new Pn532(I2cDevice.Create(new I2cConnectionSettings(1, Pn532.I2cDefaultAddress))); break; default: Console.WriteLine("Please enter the serial port to use. ex: COM3 on Windows or /dev/ttyS0 on Linux"); var device = Console.ReadLine(); - pn532 = new Pn532(device!, debugLevel); + pn532 = new Pn532(device!); break; } diff --git a/src/devices/Common/Iot/Device/Common/DebuggerOutputLogger.cs b/src/devices/Common/Iot/Device/Common/DebuggerOutputLogger.cs new file mode 100644 index 00000000..75033ca8 --- /dev/null +++ b/src/devices/Common/Iot/Device/Common/DebuggerOutputLogger.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Iot.Device.Common +{ + /// + /// A logger that prints to the debug console + /// + public class DebuggerOutputLogger : ILogger + { + /// + /// Creates a new instance of the + /// + public DebuggerOutputLogger() + { + MinLogLevel = LogLevel.Debug; + } + + /// + /// Sets the minimum log level + /// + public LogLevel MinLogLevel + { + get; + set; + } + + /// + public IDisposable BeginScope(TState state) + { + return new LogDispatcher.ScopeDisposable(); + } + + /// + public bool IsEnabled(LogLevel logLevel) + { + return logLevel >= MinLogLevel; + } + + /// + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + string msg = formatter(state, exception); + Debug.WriteLine(msg); + } + } +} diff --git a/src/devices/Common/Iot/Device/Common/DebuggerOutputLoggerProvider.cs b/src/devices/Common/Iot/Device/Common/DebuggerOutputLoggerProvider.cs new file mode 100644 index 00000000..442ae0ea --- /dev/null +++ b/src/devices/Common/Iot/Device/Common/DebuggerOutputLoggerProvider.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Iot.Device.Common +{ + /// + /// Creates a debugger logger + /// + public class DebuggerOutputLoggerProvider : ILoggerProvider + { + /// + public ILogger CreateLogger(string categoryName) + { + return new DebuggerOutputLogger(); + } + + /// + public void Dispose() + { + } + } +} diff --git a/src/devices/Common/samples/Common.Samples.csproj b/src/devices/Common/samples/Common.Samples.csproj index 198a58a2..ba39a4a2 100644 --- a/src/devices/Common/samples/Common.Samples.csproj +++ b/src/devices/Common/samples/Common.Samples.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/devices/Mfrc522/Mfrc522.cs b/src/devices/Mfrc522/Mfrc522.cs index 4da22b9a..31907704 100644 --- a/src/devices/Mfrc522/Mfrc522.cs +++ b/src/devices/Mfrc522/Mfrc522.cs @@ -13,6 +13,8 @@ using System.Threading; using Iot.Device.Card; using Iot.Device.Rfid; using Iot.Device.Card.Mifare; +using Iot.Device.Common; +using Microsoft.Extensions.Logging; namespace Iot.Device.Mfrc522 { @@ -37,8 +39,9 @@ namespace Iot.Device.Mfrc522 private SerialPort? _serialPort; private GpioController? _controller; private bool _shouldDispose; + private ILogger _logger; - #region constructors + #region Constructors /// /// Constructor for MFRC5222 with SPI interface. @@ -51,6 +54,7 @@ namespace Iot.Device.Mfrc522 { _spiDevice = spiDevice; _pinReset = pinReset; + _logger = this.GetCurrentClassLogger(); HardReset(gpioController, shouldDispose); SetDefaultValues(); @@ -67,6 +71,7 @@ namespace Iot.Device.Mfrc522 { _i2CDevice = i2cDevice; _pinReset = pinReset; + _logger = this.GetCurrentClassLogger(); HardReset(gpioController, shouldDispose); SetDefaultValues(); @@ -93,6 +98,7 @@ namespace Iot.Device.Mfrc522 /// True to dispose the GpioController. public MfRc522(SerialPort serialPort, int pinReset = -1, GpioController? gpioController = null, bool shouldDispose = true) { + _logger = this.GetCurrentClassLogger(); _serialPort = serialPort; _serialPort.ReadTimeout = 1000; _serialPort.WriteTimeout = 1000; @@ -929,7 +935,7 @@ namespace Iot.Device.Mfrc522 status = SendAndReceiveData(MfrcCommand.Transceive, toSendFirst.ToArray(), null); if (status != Status.Ok) { - LogInfo.Log($"{nameof(TwoStepsIncDecRestore)} - Error {(MfrcCommand)dataToSend[0]}", LogLevel.Debug); + _logger.LogWarning($"{nameof(TwoStepsIncDecRestore)} - Error {(MfrcCommand)dataToSend[0]}"); return -1; } diff --git a/src/devices/Pn5180/Pn5180.cs b/src/devices/Pn5180/Pn5180.cs index 0166d637..275dfe61 100644 --- a/src/devices/Pn5180/Pn5180.cs +++ b/src/devices/Pn5180/Pn5180.cs @@ -13,7 +13,9 @@ using System.Threading; using System.Diagnostics.CodeAnalysis; using Iot.Device.Card; using Iot.Device.Card.Mifare; +using Iot.Device.Common; using Iot.Device.Rfid; +using Microsoft.Extensions.Logging; namespace Iot.Device.Pn5180 { @@ -33,6 +35,8 @@ namespace Iot.Device.Pn5180 private int _pinBusy; private int _pinNss; + private ILogger _logger; + /// /// A radio Frequency configuration element size is 5 bytes /// Byte 1 = Register Address @@ -50,24 +54,6 @@ namespace Iot.Device.Pn5180 /// public const SpiMode DefaultSpiMode = System.Device.Spi.SpiMode.Mode0; - /// - /// The Log level - /// - public LogLevel LogLevel - { - get => LogInfo.LogLevel; - set => LogInfo.LogLevel = value; - } - - /// - /// The location to log the info - /// - public LogTo LogTo - { - get => LogInfo.LogTo; - set => LogInfo.LogTo = value; - } - /// /// Create a PN5180 RFID/NFC reader /// @@ -76,8 +62,7 @@ namespace Iot.Device.Pn5180 /// The pin for the SPI select line. This has to be handle differently than thru the normal process as PN5180 has a specific way of working /// A GPIO controller, null will use a default one /// Dispose the SPI and the GPIO controller at the end if true - /// The log level - public Pn5180(SpiDevice spiDevice, int pinBusy, int pinNss, GpioController? gpioController = null, bool shouldDispose = true, LogLevel logLevel = LogLevel.None) + public Pn5180(SpiDevice spiDevice, int pinBusy, int pinNss, GpioController? gpioController = null, bool shouldDispose = true) { if (pinBusy < 0) { @@ -89,9 +74,8 @@ namespace Iot.Device.Pn5180 throw new ArgumentException(nameof(pinBusy), "Value must be a legal pin number. cannot be negative."); } - LogLevel = logLevel; - - LogInfo.Log($"Opening PN5180, pin busy: {pinBusy}, pin NSS: {pinNss}", LogLevel.Debug); + _logger = this.GetCurrentClassLogger(); + _logger.LogDebug($"Opening PN5180, pin busy: {pinBusy}, pin NSS: {pinNss}"); _spiDevice = spiDevice ?? throw new ArgumentNullException(nameof(spiDevice)); _gpioController = gpioController ?? new GpioController(PinNumberingScheme.Logical); _shouldDispose = shouldDispose || gpioController is null; @@ -206,22 +190,16 @@ namespace Iot.Device.Pn5180 dumpEeprom[0] = (byte)Command.READ_EEPROM; dumpEeprom[1] = (byte)address; dumpEeprom[2] = (byte)eeprom.Length; - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(ReadEeprom)}, {nameof(dumpEeprom)}: {BitConverter.ToString(dumpEeprom.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(ReadEeprom)}, {nameof(dumpEeprom)}: {BitConverter.ToString(dumpEeprom.ToArray())}"); try { SpiWriteRead(dumpEeprom, eeprom); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(ReadEeprom)}, {nameof(dumpEeprom)}: {BitConverter.ToString(dumpEeprom.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(ReadEeprom)}, {nameof(dumpEeprom)}: {BitConverter.ToString(dumpEeprom.ToArray())}"); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(ReadEeprom)}: {nameof(TimeoutException)} during {nameof(SpiWriteRead)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(ReadEeprom)}: {nameof(TimeoutException)} during {nameof(SpiWriteRead)}"); return false; } @@ -246,18 +224,12 @@ namespace Iot.Device.Pn5180 dumpEeprom[0] = (byte)Command.WRITE_EEPROM; dumpEeprom[1] = (byte)address; eeprom.CopyTo(dumpEeprom.Slice(2)); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(WriteEeprom)}, {nameof(eeprom)}: {BitConverter.ToString(eeprom.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(WriteEeprom)}, {nameof(eeprom)}: {BitConverter.ToString(eeprom.ToArray())}"); try { SpiWrite(dumpEeprom); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(WriteEeprom)}, {nameof(dumpEeprom)}: {BitConverter.ToString(dumpEeprom.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(WriteEeprom)}, {nameof(dumpEeprom)}: {BitConverter.ToString(dumpEeprom.ToArray())}"); Span irqStatus = stackalloc byte[4]; ret = GetIrqStatus(irqStatus); @@ -265,9 +237,9 @@ namespace Iot.Device.Pn5180 // Clear IRQ SpiWriteRegister(Command.WRITE_REGISTER, Register.IRQ_CLEAR, new byte[] { 0xFF, 0xFF, 0x0F, 0x00 }); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(WriteEeprom)}: {nameof(TimeoutException)} during {nameof(SpiWrite)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(WriteEeprom)}: {nameof(TimeoutException)} during {nameof(SpiWrite)}"); return false; } @@ -304,18 +276,15 @@ namespace Iot.Device.Pn5180 sendData[0] = (byte)Command.SEND_DATA; sendData[1] = (byte)(numberValidBitsLastByte == 8 ? 0 : numberValidBitsLastByte); toSend.CopyTo(sendData.Slice(2)); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(SendDataToCard)}: {nameof(sendData)}, {BitConverter.ToString(sendData.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(SendDataToCard)}: {nameof(sendData)}, {BitConverter.ToString(sendData.ToArray())}"); try { SpiWrite(sendData); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(SendDataToCard)}: {nameof(TimeoutException)} in {nameof(SpiWrite)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(SendDataToCard)}: {nameof(TimeoutException)} in {nameof(SpiWrite)}"); return false; } @@ -340,22 +309,16 @@ namespace Iot.Device.Pn5180 Span sendData = stackalloc byte[2]; sendData[0] = (byte)Command.READ_DATA; sendData[1] = 0x00; - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(ReadDataFromCard)}: {nameof(sendData)}, {BitConverter.ToString(sendData.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(ReadDataFromCard)}: {nameof(sendData)}, {BitConverter.ToString(sendData.ToArray())}"); try { SpiWriteRead(sendData, toRead); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(ReadDataFromCard)}: {nameof(toRead)}, {BitConverter.ToString(toRead.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(ReadDataFromCard)}: {nameof(toRead)}, {BitConverter.ToString(toRead.ToArray())}"); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(ReadDataFromCard)}: {nameof(TimeoutException)} in {nameof(SpiWriteRead)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(ReadDataFromCard)}: {nameof(TimeoutException)} in {nameof(SpiWriteRead)}"); return false; } @@ -376,19 +339,13 @@ namespace Iot.Device.Pn5180 var (numBytes, _) = GetNumberOfBytesReceivedAndValidBits(); if (numBytes == expectedToRead) { - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(ReadDataFromCard)}: right number of expected bytes to read", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(ReadDataFromCard)}: right number of expected bytes to read"); return ReadDataFromCard(toRead); } else if (numBytes > expectedToRead) { - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(ReadDataFromCard)}: wrong number of expected bytes, clearing the cache", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(ReadDataFromCard)}: wrong number of expected bytes, clearing the cache"); // Clear all ReadDataFromCard(new byte[numBytes]); @@ -408,7 +365,7 @@ namespace Iot.Device.Pn5180 /// detect a card, select it and then send data public bool ReadDataFromCard(Span toRead, out int bytesRead) { - LogInfo.Log($"{nameof(ReadDataFromCard)}: ", LogLevel.Debug); + _logger.LogDebug($"{nameof(ReadDataFromCard)}: "); var (numBytes, _) = GetNumberOfBytesReceivedAndValidBits(); if (numBytes < 0) { @@ -441,9 +398,9 @@ namespace Iot.Device.Pn5180 // from NXP documentation PN5180AXX-C3.pdf, Page 98 return ((status[0] + ((status[1] & 0x01) << 8)), (status[1] & 0b1110_0000) >> 5); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(SendDataToCard)}: {nameof(TimeoutException)} in {nameof(SpiReadRegister)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(SendDataToCard)}: {nameof(TimeoutException)} in {nameof(SpiReadRegister)}"); return (-1, -1); } } @@ -714,7 +671,7 @@ namespace Iot.Device.Pn5180 /// True if success public bool MifareAuthenticate(ReadOnlySpan key, MifareCardCommand mifareCommand, byte blockAddress, ReadOnlySpan cardUid) { - LogInfo.Log($"{nameof(MifareAuthenticate)}: ", LogLevel.Debug); + _logger.LogDebug($"{nameof(MifareAuthenticate)}: "); if (key.Length != 6) { throw new ArgumentException(nameof(key), "Value must be 6 bytes."); @@ -738,22 +695,16 @@ namespace Iot.Device.Pn5180 toAuthenticate[7] = (byte)(mifareCommand == MifareCardCommand.AuthenticationA ? 0x60 : 0x61); toAuthenticate[8] = blockAddress; cardUid.CopyTo(toAuthenticate.Slice(9)); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(MifareAuthenticate)}: {nameof(toAuthenticate)}: {BitConverter.ToString(toAuthenticate.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(MifareAuthenticate)}: {nameof(toAuthenticate)}: {BitConverter.ToString(toAuthenticate.ToArray())}"); try { SpiWriteRead(toAuthenticate, response); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(MifareAuthenticate)}: {nameof(response)}: {BitConverter.ToString(response.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(MifareAuthenticate)}: {nameof(response)}: {BitConverter.ToString(response.ToArray())}"); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(ReadDataFromCard)}: {nameof(TimeoutException)} in {nameof(SpiWriteRead)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(ReadDataFromCard)}: {nameof(TimeoutException)} in {nameof(SpiWriteRead)}"); return false; } @@ -1073,7 +1024,7 @@ namespace Iot.Device.Pn5180 if (numBytes != 5) { // This can happen if a card is pulled out of the field - LogInfo.Log($"SAK length not 5", LogLevel.Debug); + _logger.LogWarning($"SAK length not 5"); return false; } @@ -1436,7 +1387,7 @@ namespace Iot.Device.Pn5180 private bool GetRxStatus(Span rxStatus) { - LogInfo.Log($"{nameof(GetRxStatus)}", LogLevel.Debug); + _logger.LogDebug($"{nameof(GetRxStatus)}"); if (rxStatus.Length != 4) { throw new ArgumentException(nameof(rxStatus), "Value must be 4 bytes."); @@ -1445,14 +1396,11 @@ namespace Iot.Device.Pn5180 try { SpiReadRegister(Register.RX_STATUS, rxStatus); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(GetRxStatus)}: {nameof(rxStatus)}: {BitConverter.ToString(rxStatus.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(GetRxStatus)}: {nameof(rxStatus)}: {BitConverter.ToString(rxStatus.ToArray())}"); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(GetRxStatus)}: {nameof(TimeoutException)} in {nameof(SpiReadRegister)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(GetRxStatus)}: {nameof(TimeoutException)} in {nameof(SpiReadRegister)}"); return false; } @@ -1461,7 +1409,7 @@ namespace Iot.Device.Pn5180 private bool GetIrqStatus(Span irqStatus) { - LogInfo.Log($"{nameof(GetIrqStatus)}", LogLevel.Debug); + _logger.LogDebug($"{nameof(GetIrqStatus)}"); if (irqStatus.Length != 4) { throw new ArgumentException(nameof(irqStatus), "Value must be 4 bytes."); @@ -1470,14 +1418,11 @@ namespace Iot.Device.Pn5180 try { SpiReadRegister(Register.IRQ_STATUS, irqStatus); - if (LogLevel >= LogLevel.Debug) - { - LogInfo.Log($"{nameof(GetIrqStatus)}: {nameof(irqStatus)}: {BitConverter.ToString(irqStatus.ToArray())}", LogLevel.Debug); - } + _logger.LogDebug($"{nameof(GetIrqStatus)}: {nameof(irqStatus)}: {BitConverter.ToString(irqStatus.ToArray())}"); } - catch (TimeoutException) + catch (TimeoutException tx) { - LogInfo.Log($"{nameof(GetIrqStatus)}: {nameof(TimeoutException)} in {nameof(SpiReadRegister)}", LogLevel.Debug); + _logger.LogError(tx, $"{nameof(GetIrqStatus)}: {nameof(TimeoutException)} in {nameof(SpiReadRegister)}"); return false; } diff --git a/src/devices/Pn532/Pn532.cs b/src/devices/Pn532/Pn532.cs index 8383a803..83310ce2 100644 --- a/src/devices/Pn532/Pn532.cs +++ b/src/devices/Pn532/Pn532.cs @@ -11,11 +11,13 @@ using System.IO; using System.IO.Ports; using System.Threading; using Iot.Device.Card; +using Iot.Device.Common; using Iot.Device.Pn532.AsTarget; using Iot.Device.Pn532.ListPassive; using Iot.Device.Pn532.RfConfiguration; using Iot.Device.Rfid; using IoT.Device.Pn532; +using Microsoft.Extensions.Logging; namespace Iot.Device.Pn532 { @@ -58,6 +60,7 @@ namespace Iot.Device.Pn532 private bool _shouldDispose; private SecurityAccessModuleMode _securityAccessModuleMode = SecurityAccessModuleMode.Normal; private uint _virtualCardTimeout = 0x17; + private ILogger _logger; /// /// Set or get the read timeout for I2C and SPI @@ -67,24 +70,6 @@ namespace Iot.Device.Pn532 /// public int ReadTimeOut { get; set; } = 500; - /// - /// The Log level - /// - public LogLevel LogLevel - { - get => LogInfo.LogLevel; - set => LogInfo.LogLevel = value; - } - - /// - /// The location to log the info - /// - public LogTo LogTo - { - get => LogInfo.LogTo; - set => LogInfo.LogTo = value; - } - /// /// Firmware version information /// @@ -113,16 +98,15 @@ namespace Iot.Device.Pn532 /// Create a PN532 using Serial Port /// /// The port name - /// /// The log level - public Pn532(string portName, LogLevel logLevel = LogLevel.None) + public Pn532(string portName) { - LogLevel = logLevel; + _logger = this.GetCurrentClassLogger(); // Data bit : 8 bits, // Parity bit : none, // Stop bit : 1 bit, // Baud rate : 115 200 bauds, - LogInfo.Log("Opening serial port 115200, Parity.None, 8 bits, StopBits.One", LogLevel.Debug); + _logger.LogDebug("Opening serial port 115200, Parity.None, 8 bits, StopBits.One"); _serialPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One); // Documentation page 39, serial timeout is 89 ms for 115 200 _serialPort.ReadTimeout = 89; @@ -137,7 +121,7 @@ namespace Iot.Device.Pn532 WakeUp(); // Set the SAM bool ret = SetSecurityAccessModule(); - LogInfo.Log($"Setting SAM changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting SAM changed: {ret}"); // Check the version if (!IsPn532()) { @@ -146,7 +130,7 @@ namespace Iot.Device.Pn532 // Apply default parameters ret = SetParameters(ParametersFlags.AutomaticATR_RES | ParametersFlags.AutomaticRATS); - LogInfo.Log($"Setting Parameters Flags changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting Parameters Flags changed: {ret}"); } /// @@ -155,11 +139,10 @@ namespace Iot.Device.Pn532 /// The SPI Device /// The GPIO pin number for the chip select /// A GPIO controller - /// The log level /// Dispose the GPIO Controller at the end - public Pn532(SpiDevice spiDevice, int pinChipSelect, GpioController? controller = null, LogLevel logLevel = LogLevel.None, bool shouldDispose = false) + public Pn532(SpiDevice spiDevice, int pinChipSelect, GpioController? controller = null, bool shouldDispose = false) { - LogLevel = logLevel; + _logger = this.GetCurrentClassLogger(); _spiDevice = spiDevice ?? throw new ArgumentNullException(nameof(spiDevice)); _shouldDispose = shouldDispose || controller == null; _controller = controller ?? new GpioController(); @@ -171,7 +154,7 @@ namespace Iot.Device.Pn532 // The first time we apply SAM after waking up the device, it always // returns false, some timeout appear. So we will need to apply a second time bool ret = SetSecurityAccessModule(); - LogInfo.Log($"Setting SAM changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting SAM changed: {ret}"); // Check the version if (!IsPn532()) { @@ -180,23 +163,22 @@ namespace Iot.Device.Pn532 // Apply default parameters ret = SetParameters(ParametersFlags.AutomaticATR_RES | ParametersFlags.AutomaticRATS); - LogInfo.Log($"Setting Parameters Flags changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting Parameters Flags changed: {ret}"); ret = SetSecurityAccessModule(); - LogInfo.Log($"Setting SAM changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting SAM changed: {ret}"); } /// /// Create a PN532 using I2C /// /// The I2C device - /// /// The log level - public Pn532(I2cDevice i2cDevice, LogLevel logLevel = LogLevel.None) + public Pn532(I2cDevice i2cDevice) { - LogLevel = logLevel; + _logger = this.GetCurrentClassLogger(); _i2cDevice = i2cDevice ?? throw new ArgumentNullException(nameof(i2cDevice)); WakeUp(); bool ret = SetSecurityAccessModule(); - LogInfo.Log($"Setting SAM changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting SAM changed: {ret}"); // Check the version if (!IsPn532()) { @@ -205,9 +187,9 @@ namespace Iot.Device.Pn532 // Apply default parameters ret = SetParameters(ParametersFlags.AutomaticATR_RES | ParametersFlags.AutomaticRATS); - LogInfo.Log($"Setting Parameters Flags changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting Parameters Flags changed: {ret}"); ret = SetSecurityAccessModule(); - LogInfo.Log($"Setting SAM changed: {ret}", LogLevel.Info); + _logger.LogInformation($"Setting SAM changed: {ret}"); } /// @@ -254,8 +236,7 @@ namespace Iot.Device.Pn532 Span resultTest = stackalloc byte[9]; ret = ReadResponse(CommandSet.Diagnose, resultTest); - LogInfo.Log($"{diagnoseMode} received: {BitConverter.ToString(resultTest.ToArray())}, ret: {ret}", - LogLevel.Debug); + _logger.LogDebug($"{diagnoseMode} received: {BitConverter.ToString(resultTest.ToArray())}, ret: {ret}"); return resultTest.SequenceEqual(toTest) && (ret >= 0); case DiagnoseMode.ROMTest: // NumTst = 0x01: ROM Test @@ -274,8 +255,7 @@ namespace Iot.Device.Pn532 Thread.Sleep(1500); Span romTest = stackalloc byte[1]; ret = ReadResponse(CommandSet.Diagnose, romTest); - LogInfo.Log($"{diagnoseMode} received: {BitConverter.ToString(romTest.ToArray())}, ret: {ret}", - LogLevel.Debug); + _logger.LogDebug($"{diagnoseMode} received: {BitConverter.ToString(romTest.ToArray())}, ret: {ret}"); // Wait for the test to run // TODO: find the right timing, this is empirical Thread.Sleep(100); @@ -300,8 +280,7 @@ namespace Iot.Device.Pn532 Thread.Sleep(1500); Span ramTest = stackalloc byte[1]; ret = ReadResponse(CommandSet.Diagnose, ramTest); - LogInfo.Log($"{diagnoseMode} received: {BitConverter.ToString(ramTest.ToArray())}, ret: {ret}", - LogLevel.Debug); + _logger.LogDebug($"{diagnoseMode} received: {BitConverter.ToString(ramTest.ToArray())}, ret: {ret}"); Thread.Sleep(100); return (ramTest[0] == 0) && (ret >= 0); case DiagnoseMode.PollingTestToTarget: @@ -410,7 +389,7 @@ namespace Iot.Device.Pn532 _virtualCardTimeout = value / 50; bool ret = SetSecurityAccessModule(); - LogInfo.Log($"{nameof(VirtualCardTimeout)} changed: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(VirtualCardTimeout)} changed: {ret}"); } } @@ -423,7 +402,7 @@ namespace Iot.Device.Pn532 set { bool ret = SetSecurityAccessModule(); - LogInfo.Log($"{nameof(SecurityAccessModuleMode)} changed: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(SecurityAccessModuleMode)} changed: {ret}"); } } @@ -437,7 +416,7 @@ namespace Iot.Device.Pn532 0x00 }; var ret = WriteCommand(CommandSet.SAMConfiguration, toSend); - LogInfo.Log($"{nameof(SetSecurityAccessModule)} Write: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(SetSecurityAccessModule)} Write: {ret}"); if (ret < 0) { return false; @@ -445,14 +424,14 @@ namespace Iot.Device.Pn532 // We don't expect any result, just that the command went well ret = ReadResponse(CommandSet.SAMConfiguration, Span.Empty); - LogInfo.Log($"{nameof(SetSecurityAccessModule)} read: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(SetSecurityAccessModule)} read: {ret}"); return ret >= 0; } private bool IsPn532() { var ret = WriteCommand(CommandSet.GetFirmwareVersion); - LogInfo.Log($"GetFirmwareVersion write command returned: {ret}", LogLevel.Info); + _logger.LogInformation($"GetFirmwareVersion write command returned: {ret}"); if (ret < 0) { return false; @@ -469,8 +448,7 @@ namespace Iot.Device.Pn532 (VersionSupported)(firmware[3] & 0b0000_0111)); // VersionSupported } - LogInfo.Log($"GetFirmwareVersion read command returned: {ret} - Bytes {BitConverter.ToString(ver)}", - LogLevel.Info); + _logger.LogInformation($"GetFirmwareVersion read command returned: {ret} - Bytes {BitConverter.ToString(ver)}"); return ret >= 0; } @@ -502,7 +480,7 @@ namespace Iot.Device.Pn532 } ret = ReadResponse(CommandSet.SetParameters, Span.Empty); - LogInfo.Log($"{nameof(SetParameters)}: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(SetParameters)}: {ret}"); return ret >= 0; } @@ -552,7 +530,7 @@ namespace Iot.Device.Pn532 // TODO: check what is the real maximum size Span listData = stackalloc byte[1024]; ret = ReadResponse(CommandSet.InListPassiveTarget, listData); - LogInfo.Log($"{nameof(ListPassiveTarget)}: {ret}, number tags: {listData[0]}", LogLevel.Debug); + _logger.LogDebug($"{nameof(ListPassiveTarget)}: {ret}, number tags: {listData[0]}"); if ((ret >= 0) && (listData[0] > 0)) { return listData.Slice(0, ret).ToArray(); @@ -855,7 +833,7 @@ namespace Iot.Device.Pn532 Span receivedData = stackalloc byte[1024]; ret = ReadResponse(CommandSet.InAutoPoll, receivedData); - LogInfo.Log($"{nameof(AutoPoll)}, success: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(AutoPoll)}, success: {ret}"); if (ret >= 0) { return receivedData.Slice(0, ret).ToArray(); @@ -875,14 +853,14 @@ namespace Iot.Device.Pn532 // First make sure we have the right mode in the parameters for the PICC only case if (mode == TargetModeInitialization.PiccOnly) { - LogInfo.Log($"{nameof(InitAsTarget)} - changing mode for Picc only", LogLevel.Debug); + _logger.LogDebug($"{nameof(InitAsTarget)} - changing mode for Picc only"); ParametersFlags |= ParametersFlags.ISO14443_4_PICC; } else { if (ParametersFlags.HasFlag(ParametersFlags.ISO14443_4_PICC)) { - LogInfo.Log($"{nameof(InitAsTarget)} - removing mode for Picc only", LogLevel.Debug); + _logger.LogDebug($"{nameof(InitAsTarget)} - removing mode for Picc only"); ParametersFlags = ParametersFlags & ~ParametersFlags.ISO14443_4_PICC; } } @@ -901,7 +879,7 @@ namespace Iot.Device.Pn532 Span receivedData = stackalloc byte[1024]; ret = ReadResponse(CommandSet.TgInitAsTarget, receivedData); - LogInfo.Log($"{nameof(InitAsTarget)}, success: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(InitAsTarget)}, success: {ret}"); if (ret >= 0) { TargetModeInitialized modeInitialized = new TargetModeInitialized(); @@ -929,12 +907,10 @@ namespace Iot.Device.Pn532 } ret = ReadResponse(CommandSet.TgGetData, receivedData); - LogInfo.Log($"{nameof(InitAsTarget)}, success: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(InitAsTarget)}, success: {ret}"); if (ret > 0) { - LogInfo.Log( - $"{nameof(WriteDataAsTarget)} - error: {(ErrorCode)receivedData[0]}, received array: {BitConverter.ToString(receivedData.Slice(1, ret - 1).ToArray())}", - LogLevel.Debug); + _logger.LogDebug($"{nameof(WriteDataAsTarget)} - error: {(ErrorCode)receivedData[0]}, received array: {BitConverter.ToString(receivedData.Slice(1, ret - 1).ToArray())}"); } return ret; @@ -955,10 +931,10 @@ namespace Iot.Device.Pn532 Span receivedData = stackalloc byte[1]; ret = ReadResponse(CommandSet.TgSetData, receivedData); - LogInfo.Log($"{nameof(InitAsTarget)}, success: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(InitAsTarget)}, success: {ret}"); if (ret > 0) { - LogInfo.Log($"{nameof(WriteDataAsTarget)} - error: {(ErrorCode)receivedData[0]}", LogLevel.Debug); + _logger.LogDebug($"{nameof(WriteDataAsTarget)} - error: {(ErrorCode)receivedData[0]}"); return receivedData[0] == (byte)ErrorCode.None; } @@ -1046,7 +1022,7 @@ namespace Iot.Device.Pn532 } ret = ReadResponse(CommandSet.RFConfiguration, Span.Empty); - LogInfo.Log($"{nameof(SetParameters)}: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(SetParameters)}: {ret}"); return ret >= 0; } @@ -1113,7 +1089,7 @@ namespace Iot.Device.Pn532 } ret = ReadResponse(CommandSet.ReadRegister, registerValues); - LogInfo.Log($"{nameof(ReadRegister)}: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(ReadRegister)}: {ret}"); return ret >= 0; } @@ -1180,7 +1156,7 @@ namespace Iot.Device.Pn532 // Generate a larger amount Span returnVal = stackalloc byte[1024]; ret = ReadResponse(CommandSet.ReadRegister, returnVal); - LogInfo.Log($"{nameof(WriteRegister)}: {ret}", LogLevel.Debug); + _logger.LogDebug($"{nameof(WriteRegister)}: {ret}"); return ret >= 0; } @@ -1305,7 +1281,7 @@ namespace Iot.Device.Pn532 Span status = stackalloc byte[1]; ret = ReadResponse(CommandSet.PowerDown, status); - LogInfo.Log($"{nameof(PowerDown)}: {ret}, Status {status[0]}", LogLevel.Debug); + _logger.LogDebug($"{nameof(PowerDown)}: {ret}, Status {status[0]}"); // Time needed to sleep Thread.Sleep(1); return (status[0] == (byte)ErrorCode.None) && (ret >= 0); @@ -1319,7 +1295,7 @@ namespace Iot.Device.Pn532 if (_serialPort is object) { // Wakeup the device send the magic 0x55 with a long preamble and SAM Command - LogInfo.Log("Waking up device", LogLevel.Debug); + _logger.LogDebug("Waking up device"); // Create a SAM message and add the wake up message before byte[] samMessage = CreateWriteMessage(CommandSet.SAMConfiguration, new byte[3] { (byte)_securityAccessModuleMode, (byte)(_virtualCardTimeout), 0x00 }); @@ -1327,7 +1303,7 @@ namespace Iot.Device.Pn532 _serialWakeUp.CopyTo(wakeUp, 0); samMessage.CopyTo(wakeUp, _serialWakeUp.Length); _serialPort.Write(wakeUp, 0, wakeUp.Length); - LogInfo.Log($"Send: {BitConverter.ToString(wakeUp)}", LogLevel.Debug); + _logger.LogDebug($"Send: {BitConverter.ToString(wakeUp)}"); // Wait to make sure it's awake and processed the order Thread.Sleep(5); // Dump the results @@ -1336,7 +1312,7 @@ namespace Iot.Device.Pn532 else if (_spiDevice is object && _controller is object) { // Wakeup the device by pulling down the pin select of SPI - LogInfo.Log("Waking up device", LogLevel.Debug); + _logger.LogDebug("Waking up device"); _controller.Write(_pin, PinValue.Low); Thread.Sleep(4); _controller.Write(_pin, PinValue.High); @@ -1350,7 +1326,7 @@ namespace Iot.Device.Pn532 } else if (_i2cDevice is object) { - LogInfo.Log("Waking up PN522 on I2C mode", LogLevel.Debug); + _logger.LogDebug("Waking up PN522 on I2C mode"); byte[] samMessage = CreateWriteMessage(CommandSet.SAMConfiguration, new byte[3] { (byte)_securityAccessModuleMode, (byte)(_virtualCardTimeout), 0x00 }); byte[] wakeUp = new byte[_i2CWakeUp.Length + samMessage.Length]; @@ -1362,7 +1338,7 @@ namespace Iot.Device.Pn532 try { _i2cDevice.Write(wakeUp); - LogInfo.Log($"Send: {BitConverter.ToString(wakeUp)}", LogLevel.Debug); + _logger.LogDebug($"Send: {BitConverter.ToString(wakeUp)}"); break; } catch (IOException) @@ -1471,7 +1447,7 @@ namespace Iot.Device.Pn532 { if (_serialPort is object) { - LogInfo.Log($"Serial Available bytes and dumped: {_serialPort.BytesToRead}", LogLevel.Debug); + _logger.LogDebug($"Serial Available bytes and dumped: {_serialPort.BytesToRead}"); while (_serialPort.BytesToRead > 0) { _serialPort.ReadByte(); @@ -1486,9 +1462,7 @@ namespace Iot.Device.Pn532 private int WriteCommand(CommandSet commandSet, ReadOnlySpan writeData) { - LogInfo.Log( - $"{nameof(WriteCommand)}: {nameof(CommandSet)} {commandSet} Bytes to send: {BitConverter.ToString(writeData.ToArray())}", - LogLevel.Debug); + _logger.LogDebug($"{nameof(WriteCommand)}: {nameof(CommandSet)} {commandSet} Bytes to send: {BitConverter.ToString(writeData.ToArray())}"); if (_spiDevice is object) { return WriteCommandSPI(commandSet, writeData); @@ -1601,7 +1575,7 @@ namespace Iot.Device.Pn532 buff[8 + writeData.Length + correctionLArgeSizeBuffer] = Postamble; } - LogInfo.Log($"Message to send: {BitConverter.ToString(buff.ToArray())}", LogLevel.Debug); + _logger.LogDebug($"Message to send: {BitConverter.ToString(buff.ToArray())}"); return buff.ToArray(); } @@ -2111,11 +2085,11 @@ namespace Iot.Device.Pn532 } catch (Exception ex) { - LogInfo.Log($"Exception: {ex.Message}", LogLevel.Info); + _logger.LogError($"Exception: {ex.Message}"); } } - LogInfo.Log($"ACK: {BitConverter.ToString(ackReceived.ToArray())}", LogLevel.Debug); + _logger.LogDebug($"ACK: {BitConverter.ToString(ackReceived.ToArray())}"); return ackReceived.SequenceEqual(_ackBuffer); } diff --git a/src/devices/Pn532/Pn532.csproj b/src/devices/Pn532/Pn532.csproj index 3ca1df8e..a50a152f 100644 --- a/src/devices/Pn532/Pn532.csproj +++ b/src/devices/Pn532/Pn532.csproj @@ -17,6 +17,7 @@ + diff --git a/src/devices/Pn532/samples/Pn532sample.csproj b/src/devices/Pn532/samples/Pn532sample.csproj index fb409817..fdcd44ed 100644 --- a/src/devices/Pn532/samples/Pn532sample.csproj +++ b/src/devices/Pn532/samples/Pn532sample.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/devices/Pn532/samples/Program.cs b/src/devices/Pn532/samples/Program.cs index 12476ebe..2c4ca4d2 100644 --- a/src/devices/Pn532/samples/Program.cs +++ b/src/devices/Pn532/samples/Program.cs @@ -12,8 +12,11 @@ using System.Threading.Tasks; using Iot.Device.Card; using Iot.Device.Card.CreditCardProcessing; using Iot.Device.Card.Mifare; +using Iot.Device.Common; using Iot.Device.Pn532; using Iot.Device.Pn532.ListPassive; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Console; Pn532 pn532; @@ -33,7 +36,16 @@ if (choiceInterface is not { KeyChar: '1' or '2' or '3' }) Console.WriteLine("Do you want log level to Debug? Y/N"); var debugLevelConsole = Console.ReadKey(); Console.WriteLine(); -LogLevel debugLevel = debugLevelConsole is { KeyChar: 'Y' or 'y' } ? LogLevel.Debug : LogLevel.None; +LogLevel debugLevel = debugLevelConsole is { KeyChar: 'Y' or 'y' } ? LogLevel.Debug : LogLevel.Information; + +var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddFilter(x => x >= debugLevel); + builder.AddConsole(); +}); + +// Statically register our factory. Note that this must be done before instantiation of any class that wants to use logging. +LogDispatcher.LoggerFactory = loggerFactory; if (choiceInterface is { KeyChar: '3' }) { @@ -50,18 +62,18 @@ if (choiceInterface is { KeyChar: '3' }) return; } - pn532 = new Pn532(SpiDevice.Create(new SpiConnectionSettings(0) { DataFlow = DataFlow.LsbFirst, Mode = SpiMode.Mode0 }), pinSelect, logLevel: debugLevel); + pn532 = new Pn532(SpiDevice.Create(new SpiConnectionSettings(0) { DataFlow = DataFlow.LsbFirst, Mode = SpiMode.Mode0 }), pinSelect); } else if (choiceInterface is { KeyChar: '2' }) { - pn532 = new Pn532(I2cDevice.Create(new I2cConnectionSettings(1, Pn532.I2cDefaultAddress)), debugLevel); + pn532 = new Pn532(I2cDevice.Create(new I2cConnectionSettings(1, Pn532.I2cDefaultAddress))); } else { Console.WriteLine("Please enter the serial port to use. ex: COM3 on Windows or /dev/ttyS0 on Linux"); var device = Console.ReadLine(); - pn532 = new Pn532(device!, debugLevel); + pn532 = new Pn532(device!); } if (pn532.FirmwareVersion is FirmwareVersion version) -- GitLab