-
Notifications
You must be signed in to change notification settings - Fork 15
feat(api): add set_link_mode method for Thread link mode configuration #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
18e9ff6
5a57624
8e42bae
acec2a2
f5b7211
25eb787
09e36e4
87c5406
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,12 +72,13 @@ use sys::{ | |
| otError_OT_ERROR_NONE, otError_OT_ERROR_NOT_FOUND, otError_OT_ERROR_NO_ACK, | ||
| otError_OT_ERROR_NO_BUFS, otInstance, otInstanceFinalize, otInstanceInitSingle, otIp6Address, | ||
| otIp6GetUnicastAddresses, otIp6IsEnabled, otIp6NewMessageFromBuffer, otIp6Send, | ||
| otIp6SetEnabled, otIp6SetReceiveCallback, otMessage, otMessageFree, | ||
| otIp6SetEnabled, otIp6SetReceiveCallback, otLinkModeConfig, otMessage, otMessageFree, | ||
| otMessagePriority_OT_MESSAGE_PRIORITY_NORMAL, otMessageRead, otMessageSettings, | ||
| otOperationalDataset, otOperationalDatasetTlvs, otPlatAlarmMilliFired, otPlatRadioReceiveDone, | ||
| otPlatRadioTxDone, otPlatRadioTxStarted, otRadioCaps, otRadioFrame, otSetStateChangedCallback, | ||
| otTaskletsProcess, otThreadGetDeviceRole, otThreadGetExtendedPanId, otThreadSetEnabled, | ||
| OT_RADIO_CAPS_ACK_TIMEOUT, OT_RADIO_FRAME_MAX_SIZE, | ||
| otThreadSetLinkMode, OT_RADIO_CAPS_ACK_TIMEOUT, OT_RADIO_CAPS_CSMA_BACKOFF, | ||
| OT_RADIO_FRAME_MAX_SIZE, | ||
| }; | ||
|
|
||
| /// A newtype wrapper over the native OpenThread error type (`otError`). | ||
|
|
@@ -426,6 +427,54 @@ impl<'a> OpenThread<'a> { | |
| ot!(unsafe { otThreadSetEnabled(state.ot.instance, enable) }) | ||
| } | ||
|
|
||
| /// Set the Thread link mode configuration. | ||
| /// | ||
| /// Arguments: | ||
| /// - `rx_on_when_idle`: If true, the device keeps its receiver on when idle. | ||
| /// This is required for devices that need to receive unsolicited messages. | ||
| /// - `device_type`: If true, the device is a Full Thread Device (FTD). | ||
| /// - `network_data`: If true, the device requests full Network Data. | ||
| pub fn set_link_mode( | ||
| &self, | ||
| rx_on_when_idle: bool, | ||
| device_type: bool, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make this an
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also: what would happen if OpenThread is not compiled with FTD support (which is currently the case) and I pass |
||
| network_data: bool, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also here: perhaps |
||
| ) -> Result<(), OtError> { | ||
| let mut ot = self.activate(); | ||
| let state = ot.state(); | ||
|
|
||
| // Update radio config rx_when_idle to match link mode. | ||
| // OpenThread doesn't call otPlatRadioSetRxOnWhenIdle, so we must | ||
| // update the radio config directly here to ensure the ESP radio | ||
| // driver keeps the radio awake when needed. | ||
| // | ||
| // IMPORTANT: Only update radio_conf when device is already connected. | ||
| // set_link_mode() is called BEFORE attach in thread.rs, so we must | ||
| // not change rx_when_idle until the device is actually connected, | ||
| // otherwise the ESP radio driver behaves differently and attach fails. | ||
| let device_role: DeviceRole = | ||
| unsafe { otThreadGetDeviceRole(state.ot.instance) }.into(); | ||
|
|
||
| if device_role.is_connected() && state.ot.radio_conf.rx_when_idle != rx_on_when_idle { | ||
| info!( | ||
| "Updating radio config rx_when_idle: {} -> {}", | ||
| state.ot.radio_conf.rx_when_idle, rx_on_when_idle | ||
| ); | ||
| state.ot.radio_conf.rx_when_idle = rx_on_when_idle; | ||
| } | ||
|
|
||
| let mode = otLinkModeConfig { | ||
| _bitfield_align_1: [], | ||
| _bitfield_1: otLinkModeConfig::new_bitfield_1( | ||
| rx_on_when_idle, | ||
| device_type, | ||
| network_data, | ||
| ), | ||
| }; | ||
|
|
||
| ot!(unsafe { otThreadSetLinkMode(state.ot.instance, mode) }) | ||
| } | ||
|
|
||
| /// Gets the list of IPv6 addresses currently assigned to the Thread interface | ||
| /// | ||
| /// Arguments: | ||
|
|
@@ -1292,12 +1341,21 @@ impl<'a> OtContext<'a> { | |
|
|
||
| #[cfg(feature = "srp")] | ||
| unsafe extern "C" fn plat_c_srp_state_change_callback( | ||
| _error: otError, | ||
| error: otError, | ||
| host_info: *const crate::sys::otSrpClientHostInfo, | ||
| services: *const crate::sys::otSrpClientService, | ||
| removed_services: *const crate::sys::otSrpClientService, | ||
| context: *mut c_void, | ||
| ) { | ||
| // Log SRP errors for debugging (OT_ERROR_NONE = 0) | ||
| if error != 0 { | ||
| let host_state = unsafe { (*host_info).mState }; | ||
| warn!( | ||
| "SRP callback error: code={}, host_state={}", | ||
| error, host_state | ||
| ); | ||
| } | ||
|
|
||
| let instance = context as *mut otInstance; | ||
|
|
||
| Self::callback(instance).plat_srp_changed( | ||
|
|
@@ -1398,7 +1456,7 @@ impl<'a> OtContext<'a> { | |
| } | ||
|
|
||
| fn plat_radio_caps(&mut self) -> otRadioCaps { | ||
| let caps = OT_RADIO_CAPS_ACK_TIMEOUT as _; | ||
| let caps = (OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF) as _; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't OT_RADIO_CAPS_CSMA_BACKOFF (and all others, for that matter, including OT_RADIO_RX_ON_WHEN_IDLE) be obtained from the Radio driver actually? |
||
| trace!("Plat radio caps callback, caps: {}", caps); | ||
|
|
||
| caps | ||
|
|
@@ -1462,6 +1520,19 @@ impl<'a> OtContext<'a> { | |
| } | ||
| } | ||
|
|
||
| fn plat_radio_set_rx_on_when_idle(&mut self, enable: bool) { | ||
| info!( | ||
| "Plat radio set rx_on_when_idle callback, enable: {}", | ||
| enable | ||
| ); | ||
|
|
||
| let state = self.state(); | ||
|
|
||
| if state.ot.radio_conf.rx_when_idle != enable { | ||
| state.ot.radio_conf.rx_when_idle = enable; | ||
| } | ||
| } | ||
|
|
||
| fn plat_radio_set_extended_address(&mut self, address: u64) { | ||
| info!( | ||
| "Plat radio set extended address callback, addr: 0x{:08x}", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is autogenerated, so I wonder from where these changes came, given that I don't see anything related to the OpenThread build configuration that had changed.
Did you change it manually?