Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The Windows USB Communications interface will provide a set of interfaces and abstract classes that enable developers to communicate with usb devices, facilitating communication with VictoR devices in the VictoR Core library over USB. The abstract device class in the VictorCommunications library will be used to provide a means to read, write, connect to, and disconnect from usb devices, while refraining from direct references to core VictoR concepts.

...

Detailed Design

A VictorUsbDevice will derive from implement the IVictorDevice interface to define how users can read from and write to specific characteristics. These calls will be handled asynchronously to allow for the continued execution of code while the device performs the requested action and reports back the success of the read or write operation. Subscription functionality is also defined in the VictorUsbDevice class to raise events when a characteristic’s value has changed, as long as the characteristic in question supports notifications. The SerialDevice within the VictorUsbDevice class is what allows for the communication with a VictoR device connected through usb. The SerialDevice will be hidden from the user, only allowing modifications to be made to the device through the available functions within the VictorUsbDevice class. A device manager will contain a dictionary of devices to allow for the management of these devices, and ensuring the user does not need to retain their own collection of devices within their application.

In order to read from the device, a read request must first be sent to the device. A response will then be sent to the input stream by the device that contains the result of that request (either an error message or the data requested). When writing to the device, a result is also sent out to the input stream by the device. Additionally, subscriptions use the same input stream to send notifications on updates to any characteristics that have been subscribed to. Because of the potential for a steady stream of subscription notifications, reads and writes cannot reliably read the next available message after performing an initial write. Instead, a background thread that continuously reads from the input stream will be started on successful SerialDevice creation, parsing the header of the next available message to determine the message type, and feed the payload to the appropriate queue: a queue for notification messages of subscriptions and a queue for non-notification messages. As read/write operations will be limited to one at a time, this second queue can be expected to only contain a single byte array. Reads/writes will be limited through the use of a slim semaphore to prevent simultaneous reads.

In the case of subscriptions, delegate cannot be sent through the usb interface. To enable notifications within the system established by the SDK, a hash map of events tied to attributes will be managed by the VictorUsbDevice, with calls to subscribe being handled through services, passed to the VictorUsbDevice via the VictorUsbDeviceManager.

...

...

VictorUsbDeviceManager/VictorUsbDevice

...

  • Retrieve desired device from DeviceManager’s hashed collection of connected devices

  • Attempt to write a subscribe request to the deviceIf

    • As the device

    responds with a success, add callback to device manager’s internal dictionary of callbacks
    NOTE: It
    • does not

    seem possible to determine if an attribute can be subscribed to over usb until you attempt to do so, expecting that doing so will give you an error response (though error received is also unknown). Need to talk with Jabil about this.
    • respond to subscription requests, a return of true will simply indicate that the write to the buffer of the device did not fail

Unsubscribe

...

  • Wait on the semaphore slim object before attempting to write

  • Create a DataWriter object and attach it to the SerialDevice’s output stream

  • Write the desired bytes with the DataWriter

  • Use the DataWriter’s StoreAsync method to write to the device’s output stream

  • Await a response from the device to confirm successful write (see Read above)

    • Will return false if a WASP_EWRITEFAIL is sent by the device in response

  • Release the semaphore slim

ConnectionStatusChanged

  • May Will need to periodically poll the device to determine if a change in connection has occurred

  • If a disconnect occurs without having been requested, attempt to reconnect to the device

InputStreamThread

  • On a periodic basis:

    • Create a DataReader object and attach it to the SerialDevice’s input stream

    • Set ByteOrder of DataReader to LittleEndian

    • Use the DataReader’s LoadAsync method to load bytes from the device’s input stream matching the length of the message header for Victor messages

      • Will return the number of bytes successfully read from the device

      • If no value is retrieved after a set amount of time, cancel the read attempt and delay a set amount of time before performing a new write

      • If the device is no longer valid, then a disconnect has most likely occurred. Trigger connection state change callback

    • If there are bytes read by the DataReader, use the DataReader’s ReadBytes method to read the bytes loaded from the device’s input stream

      • If the header reports the message type as a subscription

        • Read the bytes from the DataReader

        • Pass the payload to the notifications queue to trigger the appropriate callback

      • If the header reports a read response as the message type

        • Read the bytes from the DataReader

        • Pass the payload to the response data queue

...