bytedreamer / osdp.net Goto Github PK
View Code? Open in Web Editor NEWA .NET Core control panel implementation of the Open Supervised Device Protocol(OSDP)
License: Apache License 2.0
A .NET Core control panel implementation of the Open Supervised Device Protocol(OSDP)
License: Apache License 2.0
suggestion: display serial number as hex. My serial number 0xcafedead came out odd.
With osdp.net configured for 3 PD's (at 0, 3, and 7) It appears that it does not reset the sequence number if it gets a NAK 0 and it was attempting to set up a secure channel. See attached log, packet 11 (a nak-0/s0/a=3) and packet 14 (a chlng/s1/a=3). IMO while this PD has issues the ACU code should be going back to sequence number 0 when it receives a NAK 0.
21.log
When using OSDP_FILETRANSFER, the PD is allowed to request a timeout from the ACU. This time is specified in the FTSTAT response in bits 3 and 4 (see OSDP specification 2.2 section 7.25 -- FtDelay).
In this particular case a timeout of 5000 milliseconds is requested. The ACU responds by waiting an unspecified time (perhaps seconds instead of milliseconds?) and sending no further messages to the PD until the user is manually aborting the file transfer.
When trying to Load OSDP.Net.dll in Powershell 7 I get this error:
PS C:\Users\Justin\Downloads> Add-Type C:\users\justin\downloads\sample\sample\OSDP.Net.dll
Add-Type: (1,50): error CS0116: A namespace cannot directly contain members such as fields or methods
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,2): error CS1022: Type or namespace definition, or end-of-file expected
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,3): error CS1009: Unrecognized escape sequence
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,9): error CS1056: Unexpected character ''
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,16): error CS1056: Unexpected character ''
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,26): error CS1056: Unexpected character ''
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,33): error CS1056: Unexpected character ''
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,40): error CS1056: Unexpected character ''
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: (1,1): error CS0116: A namespace cannot directly contain members such as fields or methods
C:\users\justin\downloads\sample\sample\OSDP.Net.dll
^
Add-Type: Cannot add type. Compilation errors occurred.
PS C:\Users\Justin\Downloads>
I can use the old school System.Reflection.Assembly::LoadFile method but when I try to use the library I get a different error about missing class System.IO.Ports
PS C:\Users\Justin\Downloads> [System.Reflection.Assembly]::LoadFile("C:\users\justin\downloads\sample\sample\OSDP.Net.dll")
GAC Version Location
False v4.0.30319 C:\users\justin\downloads\sample\sample\OSDP.Net.dll
PS C:\Users\Justin\Downloads> $conn = [OSDP.Net.Connections.SerialPortOsdpConnection]::new("COM2",9600)
MethodInvocationException: Exception calling ".ctor" with "2" argument(s): "Could not load file or assembly 'System.IO.Ports, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified."
PS C:\Users\Justin\Downloads>
Oddly enough when I put [System.IO.Ports] into the command line I can tab through it with Intelisense so I know its installed properly.
This update prevents any clear test communication before reestablishing secure channel session.
Since I have registered a manufacturer specific reply handler, I receive MfgReply both replied to from poll and from a specific MfgCommand.
I need to distinguish between the two, and I can do that if I know what the reply was from. I see there's an Issuing Command which I can expose and add to the handler, but before I fork - is there a better / already supported way? I couldn't find any.
Thanks!
I ended up exposing IssuingCommand in Reply and adding IssuingCommand as a parameter to ManufacturerSpecificReplyEventArgs.
Maybe it would be better to change the signature so it only receives the Reply, since the code already exctracts ConnectionId and Address. This would add a third (IssuingCommand) and by then it's simpler to just pass on the Reply.
Im in the process of updating our internal tools which have been using v1.0.4.
I'm running into some problems when trying to use secure channel on any release above 2.0.5.
2.0.6-2.0.8 throws a SystemTimeoutException from ControlPanel.SendCommand(...) when sending any command.
With the latest version however (2.0.9) this is the result:
Error while processing reply Connection ID: 4e600eda-773e-4aee-ba94-d73cbfd002e8 Address: 1 Type: CrypticData from address 1 System.Exception: Invalid client cryptogram at OSDP.Net.SecureChannel.Initialize(Byte[] clientRandomNumber, Byte[] clientCryptogram, Byte[] secureChannelKey) at OSDP.Net.Device.InitializeSecureChannel(Reply reply) at OSDP.Net.Bus.ProcessReply(Reply reply, Device device) at OSDP.Net.Bus.StartPollingAsync()
This happens immediately at AddDevice(...)
From looking at respective release pr's, 2.0.6 had changes done to the secure channel handling. Guessing its something related to that?
Dunno about 2.0.9
Unsecured is working as expected.
Each device needs to have unique address and security context
This would be a breaking change so I thought I throw it up here for discussion before starting to make any changes.
Today there is somewhat inconsistent behavior when receiving NAK responses:
IdReport
) don't handle NAK and instead will throw an exception when trying to parse the NAK as a valid response.ReaderLedControl
) will check for NAK reply and return true/false to indicate success.The problems with this is:
I propose that:
Task<bool>
is changed to return only Task
.Can you please provide a sample on how to use OSDP.Net with secure sessions. I am able to connect to the device when secure channel is disabled. But I want to set up a secure session with the device for communication.
I enabled secure mode on the device but not able to use EncryptionKeySet on the device.
Please provide a sample on how to use encryptionkeyset method and Adddevice method with a securechannelkey
Given a presence of a physical PD, add an ability to discover...
Additional requirements:
Not part of this work, but what we are thinking down the road...
Polling one device over virtual USB-serial. Not using a secure channel. What other information do you need?
OSDP.Net.ControlPanel: Error: Error while sending command OSDP.Net.Messages.PollCommand to address 1. Connection 559491fb-e2f7-4964-a7c4-c39869143562
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Collections.Generic.List`1.set_Capacity(Int32 value)
at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
at System.Collections.Generic.List`1.Insert(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at OSDP.Net.Bus.<WaitForRestOfMessage>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at OSDP.Net.Bus.<ReceiveReply>d__46.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at OSDP.Net.Bus.<SendCommandAndReceiveReply>d__45.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
Hi,
In the previous query I had shared the sample code and below are details in response to your query.
Sorry for being late in my response...
We are using multiple devices multi-dropped and connected over RS-485.
Serial to Ethernet converter that we are using is MOXA NPort 6650-16
With the latest 2.1.6, I am still facing the issue. If among the 3 multi-dropped devices, one of the device is switched off, we are not able to get response from any of the other devices
Can you please help on this?
While performing discovery, iterating through addresses are randomly skipped.
Hi,
We have 3 card readers multi-dropped(in the order 1,2,3) having different address. We are using the below code for OSDP communication. It works fine when all the 3 card readers are up and running. If one of the in-between card reader like Card reader with device address 2 is switched off, we are not able to get the response from any of the reader. The event triggered for device connection status change-online or offline is also not coming for rest of the card readers(1 and 3 in this case).
Please help on this...
string IPAddr = "10.77.47.99";
int port = 965;
int baudRate = 9600;
byte deviceAddress1 = byte.Parse("01");
byte deviceAddress2 = byte.Parse("02");
byte deviceAddress3 = byte.Parse("03");
var panel = new ControlPanel();
panel.ConnectionStatusChanged += (_, eventArgs) =>
{
Console.WriteLine("Device with address:" + eventArgs.Address + " is " + (eventArgs.IsConnected ? "Online" : "Offline"));
};
_connectionId = panel.StartConnection(new TcpClientOsdpConnection(IPAddr, port, baudRate));
panel.AddDevice(_connectionId, deviceAddress1, true, true);
panel.AddDevice(_connectionId, deviceAddress2, true, true);
panel.AddDevice(_connectionId, deviceAddress3, true, true);
while(true)
{
panel.IsOnline(_connectionId, deviceAddress1);
System.Threading.Thread.Sleep(100);
panel.IsOnline(_connectionId, deviceAddress2);
System.Threading.Thread.Sleep(100);
panel.IsOnline(_connectionId, deviceAddress3);
System.Threading.Thread.Sleep(100);
}
if one loads this on an "empty" windows system you may not have .net core 3.0. Suggestion: in the readme or elsewhere give some bit of hint as to what to retrieve from the Microsoft (or wherever) site to install this.
2 OSDP readers addresses 0x00 and 0x01. both in secure channel.
scenario:
both readers powered on, secure channel active
power off reader at address 0x01 do not disturb the other reader.
console shows reader a=0x01 offline
osdp,net starts sending CHLNG messages seeking the missing reader on address 0x01
power on reader
osdp.net reports reader 0x00 offline and reader 0x01 online
subsequently it shows reader 0x00 online again so both are online
what is happening:
when power is reapplied to the (second) reader it sends a chlng to the second reader and then for no reason sends a chlng to the first reader too. this causes the first reader to cycle the secure channel session thus showing the offline/online bounce.
this is with 2.0.11.0
those two capabilities do not fit the "compliance/number-of" paradigm. So e.g. libosdp-conformance returns 8192 for both. what's there is not "wrong", you returned the proper data.
Commit c003ad6 deletes the 5 second delay between connection retries (line 165/166). This results in CPU hogging and logger flooding in case e.g. trying to connect to an invalid serial port.
I liked the delay! 😃
If the RMAC_I response from a PD does not contain 0x01 in the third byte per D.1.3.4 of SIA OSDP 2.2 then the secure channel session failed to start. OSDP.NET ignores this and uses the session anyway.
during the secure channel setup sequence I've seen it send a Poll. This is after the osdp_CHLNG/osdp_CCRYPT pair but before the osdp_SCRYPT/osdp_RMAC_I pair. Things work out so clearly the two secure channel implementations are interoperating. See attached trace. osdp_2019_10_03_200540.log
In the current version the LED command uses all zero's as it's parameters which is not valid (PD returns NAK 9.)
This will help with creating the structure needed to read and write all types of OSDP messages
Ok, so I'm able to instantiate connection and panel objects, add my reader by its address and make it beep a few times. But I'm having trouble subscribing to events when data comes back from the reader:
Register-ObjectEvent -InputObject $panel.LocalStatusReportReplyReceived -EventName "lsrrr" -Action {"TEST"}
Register-ObjectEvent: Cannot bind argument to parameter 'InputObject' because it is null.
$panel.localstatusreportreplyrecieved is indeed null, although I do see the definition for it under the panel object:
PS C:\Users\Justin\Downloads\OSDP.Net-develop (1)\OSDP.Net-develop\src\Console\bin\Debug\netcoreapp3.1> $panel | gm
TypeName: OSDP.Net.ControlPanel
Name MemberType Definition
---- ---------- ----------
LocalStatusReportReplyReceived Event System.EventHandler`1[OSDP.Net.ControlPanel+LocalStatusReportReplyEventAr…
Any ideas?
This create an issue with performance, as multipart messages need to wait until the next poll time.
We are using below code snippet to connect to the PD.
Default Key is used initially to establish connection
byte[] bytes = new byte[] { 0x30, 0x31, 0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F };
panel.AddDevice(_connectionId, deviceAddress, true, true,bytes);
Next we are trying to set the new SCBK using the below EncryptionKeySet method.
byte[] bytes1 = new byte[]
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
};
bool successfulSet = await panel.EncryptionKeySet(_connectionId, deviceAddress, new EncryptionKeyConfiguration(KeyType.SecureChannelBaseKey, bytes1));
But after sometime we get an exception as "The operation has timed out". Below is the detailed stack trace. Can you please guide us on why this error can happen?
at OSDP.Net.ControlPanel.d__30.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at OSDP.Net.ControlPanel.d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at OSDPSample.Program.
Hi,
We are using 3 devices connected to the same IP address and Port. But they are having different address and using the same connection ID. If one of the intermediate device is down, will the ControlPanel.IsOnline() function provide us the connection status of that particular device which is down?
Is there any other way to know that one out of the 3 device is down/Communication is offline? They are all using the same connection ID and other 2 devices status is online.
Regards,
Deepa
Hi,
Is there some usbOsdpConnection implementation?
In the test console, an attempt to restart an existing connection would cause the program to hang
The library should prevent sending a request to change to an address that is already assigned to an existing reader.
The demo downloadable at https://www.z-bitco.com/downloads/OSDPTestConsole.zip works fine with our devices; however, downloading the source code and running it fails ("error while sending command" or "invalid size for the data" are common).
I'm at a loss why, unless the code is just so different. Thanks for your help in advance.
Normally when I use the default OSDP.Net software I start a serial connection then I add a device (OSDP card reader) and it works just fine but if I start a new serial connection, when I press the start button previous serial connection is cancelled and the gui says "........ device is disconnected" (the one I previously added with first serial connection). According to these experiences, I guess the default OSDP.Net software doesn't support multiple serial connections at the same time.
I need to solve this problem because I have five different OSDP card reader and I allocated them into two different serial connections. Three of them are serial to each other and belong to COM1, other two of them are serial to each other and belong to COM2. When I run the OSDP.Net software I start a serial connection via interface, for example I start a serial connection via COM1 and add all three devices one by one (I marked "UseSecureChannel" false, while I was adding the devices, if I mark true, error pop out due to multiple card readers that are serially connected) . No problem so far, Then I start a new serial connection which is COM2 and suddenly I get error, and all the devices added previously are disconnected. After some debugging, I found out that If I comment the code segment below it would be okey to start a second serial connection.
private static async Task StartConnection(IOsdpConnection osdpConnection)
{
LastNak.Clear();
// if (_connectionId != Guid.Empty) // I commented these four lines
// {
// await _controlPanel.Shutdown();
// }
_connectionId =
_controlPanel.StartConnection(osdpConnection, TimeSpan.FromMilliseconds(_settings.PollingInterval),
_settings.IsTracing);
foreach (var device in _settings.Devices)
{
_controlPanel.AddDevice(_connectionId, device.Address, device.UseCrc, device.UseSecureChannel,
device.SecureChannelKey);
}
}
As I expected, I managed to start a new serial connection and I didn't lose the connection of three devices belong to the first serial connection. Then I added the other two devices (card readers) belong to the COM2. At this point, I have 5 different properly working OSDP card readers, allocated into 2 different serial connections, their LED's turned green to blue and they all read the data of my dummy smart card. So far so good but then I realized I can send command through last added two device but I couldn't do the same with previous three card reader. Finally I figured it out, when a serial connection is created there is a two-way communication between card reader and OSDP.Net (card reader can send the data that is read to the OSDP.Net and OSDP.Net can send the command to the card reader) but after a second serial connection is started, the two-way communication of the first serial connection is downgraded to one-way communication which is card reader to OSDP.Net (card reader still sends the data that is read but OSDP.Net can't send command anymore). For the second serial connection, two-way communication is still valid but if I start I third serial connection second one will be downgraded to. So it is clear that with this version of the software I can have a proper setup with only one serial connection and this doesn't work for me. I need to have multiple serial connections, multiple card readers on each serial connection and two-way communication for all of them.
Do you have any suggestion or comment? like, is this software able to be upgraded in this way? or my observations are correct? I may missunderstood somethings. I appreciate for any help. Best regards.
The specs use two bytes for length, but the parser times out whenever a too long message arrives.
I'm not very familiar with Azure Pipelines but it shouldn't be too difficult to automatically publish the compiled binaries for both the library and the console application here in the releases section of this repo.
Have you any plans to add keypad functionality? I have added some code and I'm now getting the key presses as events using the following code.
The data in the event appears to be ASCII for each key press. The keypad I have also has enter and cancel, being 0x0D (CR) & 0x7F (DEL) respectively.
public class KeypadReplyData
{
private const int REPLY_KEYPPAD_DATA_LEN = 2;
public byte ReaderNumber { get; private set; }
public ushort BitCount { get; private set; }
public BitArray Data { get; private set; }
internal static KeypadReplyData ParseData(ReadOnlySpan<byte> data)
{
var dataArray = data.ToArray();
if (dataArray.Length < REPLY_KEYPPAD_DATA_LEN)
{
throw new Exception("Invalid size for the data");
}
var keypadData = new BitArray(dataArray.Skip(REPLY_KEYPPAD_DATA_LEN).Take(dataArray.Length - REPLY_KEYPPAD_DATA_LEN).Reverse().ToArray());
Reverse(keypadData);
var keypadReplyData = new KeypadReplyData
{
ReaderNumber = dataArray[0],
BitCount = dataArray[1],
Data = keypadData
};
return keypadReplyData;
}
public override string ToString()
{
var build = new StringBuilder();
build.AppendLine($"Reader Number: {ReaderNumber}");
build.AppendLine($" Bit Count: {BitCount}");
build.AppendLine($" Data: {FormatData(Data)}");
return build.ToString();
}
private static string FormatData(BitArray bitArray)
{
var builder = new StringBuilder();
foreach (bool bit in bitArray)
{
builder.Append(bit ? "1" : "0");
}
return builder.ToString();
}
private static void Reverse(BitArray array)
{
int length = array.Length;
int mid = length / 2;
for (int index = 0; index < mid; index++)
{
bool bit = array[index];
array[index] = array[length - index - 1];
array[length - index - 1] = bit;
}
}
}
Then adding to ControlPanel.cs
New event
public event EventHandler<KeypadReplyEventArgs> KeypadReplyReceived;
New eventargs
public class KeypadReplyEventArgs : EventArgs
{
public KeypadReplyEventArgs(Guid connectionId, byte address, KeypadReplyData keypadData)
{
ConnectionId = connectionId;
Address = address;
KeypadData = keypadData;
}
public Guid ConnectionId { get; }
public byte Address { get; }
public KeypadReplyData KeypadData { get; }
}
In the OnReplyReceived method add the following case.
case ReplyType.KeypadData:
{
var handler = KeypadReplyReceived;
handler?.Invoke(this,
new KeypadReplyEventArgs(reply.ConnectionId, reply.Address,
KeypadReplyData.ParseData(reply.ExtractReplyData)));
break;
}
Hi,
Since 2.0.17 if I add PD that is off line or if online device lost communication, all other communications stop.
Could you please check this?
Regards
The console crashes when connection is open, but no device is defined yet and a command is issued via the "Commands" menu.
I am trying to use this library for utilizing readers to read DESfire. I noticed that you removed XWR and XRD support in January when v3 got released. Is there a specific reason for this? I am specifically looking for support for the spec that is specified in v2.1.5 of the standed that works with HID readers, but adding support for v2.2 would be nice as well. Do you need help testing? I can provide readers and anything else if needed.
I bought a HID Signo 40k reader to test your library. It works great for basic functionality. However I was hoping to be able to send APDU commands to the card using the OSDP extended write command. It looks like you removed this functionality at some point, any reason why? Do you have plans to add it back?
Hi,
We have multi-dropped 3 devices and trying to use OSDP connection to read the data from PD.
DeviceAddress is set in each of those devices which can be used while adding device as below code .
panel.AddDevice(_connectionId, deviceAddress, true, true);
What should be given for the reader number? How can multi-drop devices be read using this OSDP.Net dll? Any samples for that?
Regards,
Deepa
if you add a PD after the program is started it doesn't seem to find it and start polling. if you start the program after the PD is running it seems fine. Perhaps add a "poll now" command so it can "kick" a newly arrived PD?
The "set green led" command doesn't work in at least one reader. It sends temp ctl=01 on=100 off=0 blink=0, perm ctl=01, on=100, off=0. The temp value should IMO be ctl=0 (no-op)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.