Skip to content

Implement HID-I2C target service - #926

Open
williampMSFT wants to merge 18 commits into
OpenDevicePartnership:mainfrom
williampMSFT:user/williamp/hid-i2c-rework
Open

Implement HID-I2C target service#926
williampMSFT wants to merge 18 commits into
OpenDevicePartnership:mainfrom
williampMSFT:user/williamp/hid-i2c-rework

Conversation

@williampMSFT

Copy link
Copy Markdown
Collaborator

A new service that implements the HID-I2C spec, written against the I2C HAL trait and a new HidDevice trait that is transport-agnostic.

This obsoletes the current hid-service, which is really a HID-I2C service that leverages the comms system / message passing and doesn't handle interrupt line management.

A future change will introduce an analogue to the impl_odp_mctp_relay_handler macro to aggregate multiple logical HID devices into a single HID device.

This should allow clients to write transport-agnostic HID device code that can be reused without modification on other, future physical transports (e.g. I3C), and removes our dependance on the comms system, which imposes lifetime requirements that make testing difficult.

Resolves #839

A new service that implements the HID-I2C spec, written against the I2C HAL trait and a new HidDevice trait that is transport-agnostic.

This obsoletes the current hid-service, which is really a HID-I2C service that leverages the comms system / message passing and doesn't handle interrupt line management.

A future change will introduce an analogue to the impl_odp_mctp_relay_handler macro to aggregate multiple logical HID devices into a single HID device.

This should allow clients to write transport-agnostic HID device code that can be reused without modification on other, future physical transports (e.g. I3C), and removes our dependance on the comms system, which imposes lifetime requirements that make testing difficult.
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Cargo Vet Audit Passed

cargo vet has passed in this PR. No new unvetted dependencies were found.

@github-actions github-actions Bot added the cargo vet PRs pending auditor review label Jul 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new hidi2c-target-service crate that implements the HID-over-I2C target/slave side against an async I2C target HAL and a transport-agnostic HidDevice trait. In support of that goal, it refactors embedded-service/src/relay by splitting MCTP relay helpers into relay::mctp and adding a new relay::hid module for shared HID abstractions. It also adds RT685s-EVK mock keyboard/mouse examples and updates supply-chain metadata and workspace dependencies to include generic-array/typenum (used for compile-time report sizing).

Changes:

  • Add a new HID-I2C target service crate (runner + control handle, descriptor generation, timeouts, interrupt pin handling).
  • Refactor relay helpers into embedded_services::relay::mctp and introduce embedded_services::relay::hid for transport-agnostic HID types.
  • Add RT685s-EVK mock HID keyboard/mouse examples and update workspace + supply-chain metadata for new dependencies.

Step-by-step review guide (for human reviewers)

  1. Relay module refactor (MCTP vs HID)

    • embedded-service/src/relay/mod.rs now just re-exports hid and mctp; existing MCTP serialization traits moved to relay::mctp.
    • Multiple relay/message crates update imports accordingly (e.g., battery-service-relay, thermal-service-relay, time-alarm-service-relay, debug-service-messages).
  2. New HID relay primitives

    • embedded-service/src/relay/hid.rs adds HidDevice, report/descriptor helpers, and descriptor scanning (implicit vs explicit report IDs).
    • This module is intended to be transport-agnostic so both HID-I2C and future transports can share device logic.
  3. HID-I2C target service implementation

    • hidi2c-target-service implements register handling, command processing, device reset handling, and interrupt (“ATTN”) pin management, with per-operation timeouts and bus recovery logic.
    • Uses typenum-based sizing via ConstrainedHidDevice to allocate fixed buffers sized to max report lengths.
  4. Examples / mocks

    • Adds RT685s-EVK mock mouse/keyboard devices and example binaries wiring up I2cSlave + GPIO ATTN pin + hidi2c-target-service.

Potential issues

# Severity File Description Code
1 High hidi2c-target-service/src/constrained_hid_device.rs:24-43 ConstrainedHidDevice sealing is circular (ConstrainedHidDevice: Sealed but Sealed is only implemented for T: ConstrainedHidDevice), preventing the blanket impl from applying. pub trait ConstrainedHidDevice: ... + sealed::Sealed
2 High embedded-service/src/relay/hid.rs:221-265 item_size() can panic on long items and the descriptor scan doesn’t skip long items, making descriptor parsing unsafe and potentially incorrect. panic!("Long items are not yet supported");
3 Medium hidi2c-target-service/src/attn_pin_handler.rs:24-39 asserted state is updated before driving the GPIO; on pin I/O error, internal state can diverge from physical state and break the “don’t wait while asserted” logic. self.asserted = true; self.attn_pin.set_low()...
4 Medium hidi2c-target-service/src/service.rs:341-344 Several I2C reads ignore how many bytes were actually received; early-aborted writes can be misinterpreted as valid register/command data. self.bus.read(&mut reg).await?;
5 Medium hidi2c-target-service/src/service.rs:479-483, 562-567 Length fields are used with unchecked subtraction, risking underflow/wrap and incorrect buffer slicing/reads for malformed host packets. ... as usize - header_len
6 Medium hidi2c-target-service/src/service.rs:451-452, 550-552 write_unterminated()’s “NeedMore” signal is ignored; if the host terminates after the header, the follow-on payload write can time out and trigger recover unnecessarily. self.bus.write_unterminated(...); self.bus.write(...);
7 Low supply-chain/imports.lock:199-202 Duplicate aggregated-from entries add lockfile noise/churn; should be de-duplicated. aggregated-from = [ "...", "..." ]

Reviewed changes

Copilot reviewed 24 out of 29 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
time-alarm-service-relay/src/serialization.rs Update relay serialization imports to embedded_services::relay::mctp.
thermal-service-relay/src/serialization.rs Update relay serialization imports to embedded_services::relay::mctp.
battery-service-relay/src/serialization.rs Update relay serialization imports to embedded_services::relay::mctp.
debug-service-messages/src/lib.rs Update relay serialization imports to embedded_services::relay::mctp.
embedded-service/src/relay/mod.rs Split relay surface into hid and mctp modules.
embedded-service/src/relay/mctp.rs New home for MCTP relay traits/macros previously in relay/mod.rs.
embedded-service/src/relay/hid.rs Add transport-agnostic HID types + descriptor helper/parser.
embedded-service/Cargo.toml Add deps needed by new relay HID module (generic-array, num_enum).
hidi2c-target-service/Cargo.toml New crate definition and dependencies/features for HID-I2C service.
hidi2c-target-service/src/lib.rs Crate root exports + HID-I2C register enum.
hidi2c-target-service/src/service.rs Core HID-I2C target service runner/control handle implementation.
hidi2c-target-service/src/error.rs New protocol/bus/device error types and conversions.
hidi2c-target-service/src/device_descriptor.rs Construct HID-I2C device descriptor based on HidDevice + HW IDs.
hidi2c-target-service/src/constrained_hid_device.rs Typenum-based sizing helper trait for max report buffer sizes.
hidi2c-target-service/src/attn_pin_handler.rs ATTN GPIO wrapper tracking asserted state.
Cargo.toml Add new crate to workspace; add workspace deps generic-array and typenum.
Cargo.lock Update lockfile for new crate and dependency graph changes.
supply-chain/audits.toml Add audit entry for generic-array.
supply-chain/imports.lock Update imports lock; currently includes duplicated aggregated-from.
examples/std/Cargo.lock Lockfile update for examples std workspace due to new deps.
examples/pico-de-gallo/Cargo.lock Lockfile update due to new deps.
examples/rt685s-evk/Cargo.toml Add hidi2c-target-service and related deps for mock HID examples.
examples/rt685s-evk/Cargo.lock Lockfile update for RT685s-EVK example workspace.
examples/rt685s-evk/src/lib.rs Re-export mocks module for example binaries.
examples/rt685s-evk/src/mocks/mod.rs New module for mock HID sub-devices.
examples/rt685s-evk/src/mocks/mouse.rs Mock HID mouse device + relay adapter.
examples/rt685s-evk/src/mocks/keyboard.rs Mock HID keyboard device + relay adapter.
examples/rt685s-evk/src/bin/mock_i2c_mouse.rs Example wiring I2C slave + ATTN pin + mock mouse HID device.
examples/rt685s-evk/src/bin/mock_i2c_keyboard.rs Example wiring I2C slave + ATTN pin + mock keyboard HID device.

Comment thread hidi2c-target-service/src/constrained_hid_device.rs Outdated
Comment thread embedded-service/src/relay/hid.rs
Comment thread embedded-service/src/relay/hid.rs
Comment thread hidi2c-target-service/src/attn_pin_handler.rs
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread hidi2c-target-service/src/service.rs
Comment thread hidi2c-target-service/src/service.rs
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread embedded-service/src/relay/hid.rs Outdated
Comment thread embedded-service/src/relay/hid.rs
Comment thread embedded-service/src/relay/hid.rs
}
}

impl MockKeyboardService {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This should be named something like MockKeyboardDevice or even just MockKeyboard.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that if you feel strongly about it, but it seems like a departure from the naming convention we have for other things of the same class so I'm not sure I understand why - can you expand on that? Is it because the old examples didn't fit your mental model for what constitutes a service, and if yes, do the new examples? If not, what am I missing?

Comment thread examples/rt685s-evk/src/mocks/keyboard.rs Outdated
Comment thread examples/rt685s-evk/src/mocks/keyboard.rs Outdated
Comment thread examples/rt685s-evk/src/mocks/keyboard.rs Outdated
Comment thread examples/rt685s-evk/src/mocks/mouse.rs Outdated
Comment thread hidi2c-target-service/src/service.rs

@jerrysxie jerrysxie left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not reviewed the examples yet. These are my initial thoughts.

Comment thread embedded-service/src/relay/hid.rs
Comment thread hidi2c-target-service/src/attn_pin_handler.rs Outdated
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread hidi2c-target-service/src/service.rs
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread hidi2c-target-service/src/service.rs
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread hidi2c-target-service/src/service.rs Outdated
Comment thread hidi2c-target-service/src/service.rs
Comment thread hidi2c-target-service/src/service.rs
Comment thread hidi2c-target-service/src/attn_pin_handler.rs Outdated
Comment thread hidi2c-target-service/src/attn_pin_handler.rs Outdated
Comment thread hidi2c-target-service/src/device_descriptor.rs Outdated
jerrysxie
jerrysxie previously approved these changes Jul 31, 2026
Comment thread hidi2c-target-service/src/service.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cargo vet PRs pending auditor review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement HidI2c service

6 participants