Git Product home page Git Product logo

osdp.net's People

Contributors

arbi2 avatar bytedreamer avatar dependabot[bot] avatar dxm007 avatar fattymatty195 avatar hallsbyra avatar ldholmgren avatar mikaelj avatar silverdark avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

osdp.net's Issues

serial number display

suggestion: display serial number as hex. My serial number 0xcafedead came out odd.

retry for CHLNG not resetting sequence?

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

At Filetransfer, FtDelay seems not working as intended

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.

Powershell 7 Errors

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.

Best way of retrieving Issuing Command in event handler?

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.

Secure channel not working since 2.0.6

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.

Commands receiving NAK should throw

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:

  1. Commands that return a reply (e.g. IdReport) don't handle NAK and instead will throw an exception when trying to parse the NAK as a valid response.
  2. Commands that don't expect a reply (e.g. ReaderLedControl) will check for NAK reply and return true/false to indicate success.

The problems with this is:

  1. Inconsistent behavior between different commands. Sometimes an exception is thrown, sometimes false is returned.
  2. The exception thrown in case 1 is misleading, since it is just a byproduct of not handling NAK. E.g. instead of something informative like "NAK (0x06) Encrypted communication is required to process this command.", one receives something like "Invalid size for the data".
  3. In case 2, the NAK error code is not propagated to the client, which only receives a true/false.

I propose that:

  1. all commands check the received response and throw an informative exception in case of NAK.
  2. commands that today return a 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. Please provide a sample for encryptionkeyset method and Adddevice method with a securechannelkey

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

Introduce a device discovery capability

Given a presence of a physical PD, add an ability to discover...

  1. Baud rate the PD is configured for
  2. Address the PD is listening on
  3. PDs ID and capabilities
  4. Whether or not it is configured to communicate securely
  5. If secure, whether or not it is using a default setup encryption key

Additional requirements:

  1. Make corresponding changes to the Console project so that we can exercise and demo the discovery capability of the library
  2. As the discovery method will have to sequentially cycle through 0-127 address space (and several possible baud rates) and for each one issue a poll and then wait for a response which may or may not arrive, the caller needs to be able to...
    1. specify response timeout to use for the discovery process
    2. pass in a cancellation handle to interrupt the discovery process
  3. Provide an option for the caller to subscribe for progress notifications so that they can be notified as to what the discovery method is doing

Not part of this work, but what we are thinking down the road...

  1. In console when device is discovered, but we determine that it is using non-default encryption key...
    1. ask the user if they have a security key to use
    2. If they do not have a key, give them the option to reset the device back to factory defaults

OutOfMemoryException when polling

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)

Multi-drop device communication using OSDP

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?

Need help on multi-drop communication using OSDP

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);
}

suggest document .net 3.0 core installation

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 readers secure cycling 1 cycles the other

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

Fails to fail if RMAC_I indicates error

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.

poll in the middle of scs sequence

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

Process OSDP Cap files

This will help with creating the structure needed to read and write all types of OSDP messages

Powershell - can't subscribe/read events with Register-ObjectEvent cmdlet

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?

Need help to set the SCBK

We are using below code snippet to connect to the PD.

  1. 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);

  2. 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.

d__2.MoveNext()

Function to get the connection status of one of the device among set of devices sharing same connection ID

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

Multiple serial connection is not allowed, at least I guess so

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.

Publish compiled binaries to releases

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.

Keypad events

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;
}

Why was XWR and XRD removed in v3.0.0?

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.

Support for smart card commands removed?

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?

Query on Multi-drop

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

suggest add "poll" command

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?

Green LED command fails on some readers

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.