power-policy-interface: Port disconnect reasons from v0.1 - #948
power-policy-interface: Port disconnect reasons from v0.1#948RobertZ2011 wants to merge 5 commits into
Conversation
95095a0 to
72ce097
Compare
9a747e5 to
c7534ba
Compare
c7534ba to
60f8051
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the power-policy interface and its consumers to replace legacy bitfield-style flags with normal Rust structs, and to model consumer disconnects using a structured DisconnectReason (wrapped in DisconnectFlags) rather than separate boolean flags. It also extends Type-C service behavior to propagate a hard-reset disconnect reason through the power-policy event path.
Changes:
- Replace
ConsumerDisconnectboolean flags withDisconnectFlags { reason: Option<DisconnectReason> }and update all notification/event plumbing accordingly. - Refactor
ConsumerFlags/ProviderFlagsfrom bitfield-backed types to plain Rust structs (and update tests/mocks/examples). - Add Type-C hard reset handling that tears down the current contract and emits a disconnect event with a reset reason (plus a new test covering it).
Reviewed changes
Copilot reviewed 22 out of 26 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| type-c-service/tests/power.rs | Updates tests to use struct-based flags and validates disconnect reasons (including new hard reset coverage). |
| type-c-service/tests/debug_accessory.rs | Updates provider capability construction to the new ProviderFlags struct. |
| type-c-service/src/controller/power.rs | Migrates capability flags to struct fields; emits structured disconnect reasons; adds hard reset teardown path. |
| type-c-service/src/controller/mod.rs | Routes pd_hard_reset status events into the new hard reset teardown handler. |
| type-c-service/src/controller/max_sink_voltage.rs | Switches renegotiation disconnect signaling to DisconnectReason::ManualRenegotiation. |
| type-c-interface-mocks/tests/connect_disconnect.rs | Updates expected capabilities to use struct-based flags. |
| type-c-interface-mocks/src/port/mod.rs | Updates mock port state updates to use struct-based flags. |
| power-policy-service/tests/unconstrained.rs | Updates consumer flag usage to struct defaults/fields. |
| power-policy-service/tests/provider.rs | Updates provider flag usage to struct defaults. |
| power-policy-service/tests/consumer.rs | Updates disconnect assertions to reason-based disconnects and refactors related test naming. |
| power-policy-service/tests/common/mod.rs | Renames helper to assert disconnect “reason” via DisconnectFlags instead of legacy flags. |
| power-policy-service/src/service/mod.rs | Updates notifier plumbing and disconnect processing to carry DisconnectFlags/DisconnectReason. |
| power-policy-service/src/service/consumer.rs | Updates consumer selection/switch logic to produce a single disconnect reason and carry it through events. |
| power-policy-interface/src/service/notification.rs | Updates service notifier trait to accept DisconnectFlags. |
| power-policy-interface/src/service/event.rs | Updates service event payloads to use DisconnectFlags. |
| power-policy-interface/src/psu/notification.rs | Updates PSU notifier/handler traits to accept DisconnectFlags. |
| power-policy-interface/src/psu/event.rs | Updates PSU event payloads and notifier adapters to use DisconnectFlags. |
| power-policy-interface/src/charger/tests.rs | Updates helper capability construction to use ConsumerFlags::default(). |
| power-policy-interface/src/capability.rs | Replaces bitfield-based flag types with plain structs and introduces DisconnectReason + DisconnectFlags. |
| power-policy-interface/Cargo.toml | Drops bitfield/num_enum dependencies that were only needed for bitfield-based flags. |
| power-policy-interface-test-mocks/src/psu.rs | Updates mock PSU to construct provider flags via Default and notify disconnects via DisconnectFlags. |
| examples/std/src/bin/power_policy.rs | Updates example capability construction to struct-based consumer flags. |
| examples/std/Cargo.lock | Removes bitfield/num_enum from the example’s resolved dependency set. |
| examples/rt685s-evk/Cargo.lock | Removes bitfield/num_enum from the example’s resolved dependency set. |
| examples/pico-de-gallo/Cargo.lock | Removes bitfield/num_enum from the example’s resolved dependency set. |
| Cargo.lock | Removes bitfield/num_enum from the workspace resolved dependency set for power-policy-interface. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
60f8051 to
bbee585
Compare
Implement these flag structs as plain Rust structs. This reduces complexity and the number of dependencies.
Port disconnect reasons from v0.1 branch.
bbee585 to
5587b7f
Compare
jerrysxie
left a comment
There was a problem hiding this comment.
Mixing the removal of bitfields and the porting make the PR tough to review: it was hard to separate the mechanical bitfield removal change versus the logic changes. Thankfully they were 2 different commits.
| // The PD controller will issue its own sink ready interrupt after the hard reset, so we clear the deadline here. | ||
| self.shared_state.lock().await.sink_ready_deadline = None; | ||
| self.status.available_sink_contract = None; | ||
| self.status.available_source_contract = None; |
There was a problem hiding this comment.
This clears out the contacts in self.status.
However, following through the logic in process_port_status_changed():
See <-- marker below
async fn process_port_status_changed(
&mut self,
status_event: PortStatusEventBitfield,
) -> Result<ServicePortEventData, PdError> {
let new_status = self.controller.lock().await.get_port_status(self.port).await?; // <-- we cached the status here
debug!("({}) status: {:#?}", self.name, new_status);
debug!("({}) status events: {:#?}", self.name, status_event);
if status_event.plug_inserted_or_removed() {
self.process_plug_event(&new_status).await?;
}
if status_event.pd_hard_reset() {
self.process_hard_reset().await?; // <-- self.status gets cleared in this call, but what about `new_status`? Can it have the stale contracts and will proceed to be processed after this event? Or does a status with hard-reset flag set will be ensure that `new_status` will not have any contract set.
}
// Tear down the previous contract on a power role swap before establishing the new one
if status_event.power_swap_completed() {
self.process_power_role_swap(&new_status).await?;
}
// Only notify power policy of a contract after Sink Ready event (always after explicit or implicit contract)
if status_event.sink_ready() {
self.process_new_consumer_contract(&new_status).await?;
}
if new_status.is_connected() && new_status.available_source_contract != self.status.available_source_contract {
self.process_new_provider_contract(&new_status).await?;
}
self.check_sink_ready_timeout(
&new_status,
status_event.new_power_contract_as_consumer(),
status_event.sink_ready(),
)
.await?;
let status_changed = StatusChangedData {
status_event,
previous_status: self.status,
current_status: new_status,
};
self.status = new_status;
if let Err(e) = self
.port_notifier
.notify_status_changed(
status_changed.status_event,
status_changed.previous_status,
status_changed.current_status,
)
.await
{
error!("Failed to send port status type-C event: {:#?}", e);
}
Ok(ServicePortEventData::StatusChanged(status_changed))
}
Port changes from v0.1 that introduce an enum for disconnect reasons instead of separate flags. Also refactor existing power policy flag structs to use normal Rust structs instead of bitfield representations.