# Copyright (C) 2017-2023 by Jacob Alexander # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. @0xd525cce96cb24671; ## Imports ## using Common = import "common.capnp"; ## Interfaces ## interface HidIoServer { # Authentication interface for HidIo struct Version { version @0 :Text; # Version number of running server buildtime @1 :Text; # Date server was build serverarch @2 :Text; # Architecture of running server compilerversion @3 :Text; # Version of the compiler used to build server } struct KeyInfo { basicKeyPath @0 :Text; # File path to basic key # Has permissions of basic user authKeyPath @1 :Text; # File path to authenticated key # Must have root/admin priviledges to read this key } ## Functions ## basic @0 (info :Common.Source, key :Text) -> (port :HidIo); # Allocates a basic interface, with no special priviledges # Must include a key retrieved using locations specified by HidIoInit auth @1 (info :Common.Source, key :Text) -> (port :HidIo); # Priviledged interface # Must include a key retrieved using locations specified by HidIoInit version @2 () -> (version :Version); # Returns the version number of the running server key @3 () -> (key :KeyInfo); # Returns information needed to authenticate with HidIoServer alive @4 () -> (alive: Bool); # Always returns true, used to determine if socket connection/API is working id @5 () -> (id :UInt64); # Unique id # Assigned per socket connection # This must be used when attempting basic/auth authentication name @6 () -> (name :Text); # Name of HID-IO Server logFiles @7 () -> (paths :List(Text)); # Path to the local hid-io core log file(s) # rCURRENT is the current active log file } interface HidIo { # Main HidIo Interface # Requires authentication through HidIoServer first struct Packet { # This struct represents a modified HidIo packet # as used internally by hid-io-core. # This is not the same as the "on-the-wire" HidIo packets # (Continued packets are joined together) enum Type { data @0; # Data packet ack @1; # Ack for a data packet nak @2; # Nak for a data packet (Error) naData @3; # Non-acknowledged data packet (no corresponding ack/nak packet) unknown @4; # Unknown packet type (i.e. there's a bug somewhere) } src @0 :UInt64; # Source uid of the packet (set to 0 if N/A) dst @1 :UInt64; # Destination uid of the packet (set to 0 if N/A) type @2 :Type; # Type of HidIo packet id @3 :UInt32; # Id of the HidIo packet data @4 :List(UInt8); # Payload data of packet (in bytes) } nodes @0 () -> (nodes :List(Common.Destination)); # List of supported nodes # This may not contain all nodes due to authentication levels # The HidIo daemon may revoke priviledges for certain modules during runtime interface NodesSubscription {} # Node subscription interface # Handles subscription ownership and when to drop subscription interface NodesSubscriber { # Client node subscriber # Handles any push methods that hid-io-core can send nodesUpdate @0 (nodes :List(Common.Destination)); # Called whenever the list of nodes changes hidioWatcher @1 (packet :Packet); # Called on every internal HidIo message # This watcher will show most of the "on-the-wire" packets as well as some hid-io-core internal packets. # Sync, Continued and NAContinued will not be triggered by the watcher. # NOTE: This callback is only used when hid-io-core is in debug mode with a priviledged interface } subscribeNodes @1 (subscriber :NodesSubscriber) -> (subscription :NodesSubscription); # Subscribes a NodesSubscriber interface # Registers push notifications for node list changes } interface Node extends(Common.Node) { # Common interface for all HidIo nodes struct FlashModeStatus { # Result of a flash mode command struct Success { scanCode @0 :UInt16; # In order to enter flash mode a specific (randomly) generated physical key must be pressed # This scan code refers to that physical key. # Use the key layout to determine the HID key label. } struct Error { # Entering flash mode failed reason @0 :ErrorReason; # Reason for flash mode failure enum ErrorReason { notSupported @0; # Flash mode is not supported on this device disabled @1; # Flash mode is disabled on this device (usually for security reasons) } } union { success @0 :Success; error @1 :Error; } } struct SleepModeStatus { # Result of a sleep mode command struct Success {} struct Error { # Entering sleep mode failed reason @0 :ErrorReason; # Reason for sleep mode failure enum ErrorReason { notSupported @0; # Sleep mode is not supported on this device disabled @1; # Sleep mode is disabled on this device notReady @2; # Not ready to enter sleep mode # This is usually due to some physical or USB state that is preventing the transition to sleep mode } } union { success @0 :Success; error @1 :Error; } } struct Manufacturing { enum Command { ledTestSequence @0; ledCycleKeypressTest @1; hallEffectSensorTest @2; } enum LedTestSequenceArg { disable @0; enable @1; activateLedShortTest @2; activateLedOpenCircuitTest @3; } enum LedCycleKeypressTestArg { disable @0; enable @1; } enum HallEffectSensorTestArg { disableAll @0; passFailTestToggle @1; levelCheckToggle @2; levelCheckColumn1Toggle @3; levelCheckColumn2Toggle @4; levelCheckColumn3Toggle @5; levelCheckColumn4Toggle @6; levelCheckColumn5Toggle @7; levelCheckColumn6Toggle @8; levelCheckColumn7Toggle @9; levelCheckColumn8Toggle @10; levelCheckColumn9Toggle @11; levelCheckColumn10Toggle @12; levelCheckColumn11Toggle @13; levelCheckColumn12Toggle @14; levelCheckColumn13Toggle @15; levelCheckColumn14Toggle @16; levelCheckColumn15Toggle @17; levelCheckColumn16Toggle @18; levelCheckColumn17Toggle @19; levelCheckColumn18Toggle @20; levelCheckColumn19Toggle @21; levelCheckColumn20Toggle @22; levelCheckColumn21Toggle @23; levelCheckColumn22Toggle @24; modeSetNormal @25; modeSetLowLatency @26; modeSetTest @27; } command @0 :Command; union { ledTestSequence @1 :LedTestSequenceArg; ledCycleKeypressTest @2 :LedCycleKeypressTestArg; hallEffectSensorTest @3 :HallEffectSensorTestArg; } } struct ManufacturingStatus { struct Success {} struct Error {} # Result of manufacturing test command union { success @0 :Success; error @1 :Error; } } struct PixelSet { enum Type { directSet @0; } type @0 :Type; startAddress @1 :UInt16; directSetData @2 :Data; } struct PixelSetStatus { struct Success {} struct Error {} union { success @0 :Success; error @1 :Error; } } struct PixelSetting { enum Command { control @0; # General LED control commands reset @1; # LED controller reset modes clear @2; # Frame clearing commands frame @3; # Frame control commands } enum ControlArg { disable @0; # Disable HID-IO LED controller # This will usually give LED control back to the device and may disable the LEDs for some # devices enableStart @1; # Enables LED frame display in free running mode enablePause @2; # Enable LED frame display, frame: nextFrame must be called to iterate to the next frame. } enum ResetArg { softReset @0; # Clear current pixel frame and any settings hardReset @1; # Initiate a hard reset of the LED controller and initialize # default settings } enum ClearArg { clear @0; # Clear current pixel frame # Will need to iterate to the next frame if using EnablePause } enum FrameArg { nextFrame @0; # Iterate to next pixel buffer frame if using EnablePause } command @0 :Command; union { control @1 :ControlArg; reset @2 :ResetArg; clear @3 :ClearArg; frame @4 :FrameArg; } } struct PixelSettingStatus { struct Success {} struct Error {} union { success @0 :Success; error @1 :Error; } } struct Info { # Result of an info command hidioMajorVersion @0 :UInt16; hidioMinorVersion @1 :UInt16; hidioPatchVersion @2 :UInt16; # HID-IO Version information (supported version) deviceName @3 :Text; # Name of the device deviceVendor @9 :Text; # Name of the vendor of the device deviceSerial @4 :Text; # Serial number of the device deviceVersion @5 :Text; # Version of the device # (this is sometimes used if different firmware is necessary for different generations of the same device) deviceMcu @6 :Text; # MCU of the device (there maybe be multiple) firmwareName @7 :Text; # Name of the firmware (e.g. kiibohd, QMK, etc.) firmwareVersion @8 :Text; # Firmware version } struct Id { # HID-IO Command Id info uid @0 :UInt32; # Unique id of the HID-IO Command Id name @1 :Text; # Name of the HID-IO Command Id } cliCommand @0 (command :Text) -> (); # CLI command sleepMode @1 () -> (status :SleepModeStatus); # Attempt to have device go into a sleep state flashMode @2 () -> (status :FlashModeStatus); # Attempt to have the device enter flash mode manufacturingTest @3 (command :Manufacturing) -> (status :ManufacturingStatus); # Send a device specific manufacturing test command # Must have full auth-level to use info @4 () -> (info :Info); # Retrieves HID-IO information from the device supportedIds @5 () -> (ids :List(Id)); # Lists the supported HID-IO command Ids by the device # Must have full auth-level to use test @6 (data :Data) -> (data :Data); # Send an arbitrary piece of data to device as a test command # Will Ack piece of data back if successful # Must have full auth-level to use pixelSetting @7 (command :PixelSetting) -> (status :PixelSettingStatus); # Configures LED settings # See pixelSet for updating specific LED channels pixelSet @8 (command :PixelSet) -> (status :PixelSetStatus); # Sets specific LED channels }