22use core:: future:: Future ;
33
44use embassy_sync:: blocking_mutex:: raw:: NoopRawMutex ;
5- use embassy_sync:: channel:: Channel ;
65use embassy_sync:: mutex:: Mutex ;
76use embedded_cfu_protocol:: components:: { CfuComponentInfo , CfuComponentStorage , CfuComponentTraits } ;
87use embedded_cfu_protocol:: protocol_definitions:: * ;
@@ -12,6 +11,7 @@ use heapless::Vec;
1211use super :: CfuError ;
1312use crate :: cfu:: route_request;
1413use crate :: intrusive_list;
14+ use crate :: ipc:: deferred;
1515
1616/// Component internal update state
1717#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
@@ -57,6 +57,16 @@ impl Default for InternalState {
5757 }
5858}
5959
60+ /// Request to the cfu service
61+ #[ derive( Debug , PartialEq ) ]
62+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
63+ pub struct Request {
64+ /// Component that sent this request
65+ pub id : ComponentId ,
66+ /// Request data
67+ pub data : RequestData ,
68+ }
69+
6070/// CFU Request types and necessary data
6171#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
6272#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
@@ -93,17 +103,16 @@ pub enum InternalResponseData {
93103 ComponentPrepared ,
94104}
95105
96- /// Channel size for device requests
97- pub const DEVICE_CHANNEL_SIZE : usize = 1 ;
106+ /// Wrapper type to make code cleaner
107+ pub type InternalResponse = Result < InternalResponseData , CfuError > ;
98108
99109/// CfuDevice struct
100110/// Can be inserted in an intrusive-list+
101111pub struct CfuDevice {
102112 node : intrusive_list:: Node ,
103113 component_id : ComponentId ,
104114 state : Mutex < NoopRawMutex , InternalState > ,
105- request : Channel < NoopRawMutex , RequestData , DEVICE_CHANNEL_SIZE > ,
106- response : Channel < NoopRawMutex , InternalResponseData , DEVICE_CHANNEL_SIZE > ,
115+ request : deferred:: Channel < NoopRawMutex , Request , InternalResponse > ,
107116}
108117
109118impl intrusive_list:: NodeContainer for CfuDevice {
@@ -124,15 +133,17 @@ impl CfuDeviceContainer for CfuDevice {
124133 }
125134}
126135
136+ /// Convenience type for CFU request
137+ pub type CfuRequest < ' a > = deferred:: Request < ' a , NoopRawMutex , Request , InternalResponse > ;
138+
127139impl CfuDevice {
128140 /// Constructor for CfuDevice
129141 pub fn new ( component_id : ComponentId ) -> Self {
130142 Self {
131143 node : intrusive_list:: Node :: uninit ( ) ,
132144 component_id,
133145 state : Mutex :: new ( InternalState :: default ( ) ) ,
134- request : Channel :: new ( ) ,
135- response : Channel :: new ( ) ,
146+ request : deferred:: Channel :: new ( ) ,
136147 }
137148 }
138149 /// Getter for component id
@@ -151,19 +162,13 @@ impl CfuDevice {
151162 }
152163
153164 /// Sends a request to this device and returns a response
154- pub async fn execute_device_request ( & self , request : RequestData ) -> Result < InternalResponseData , CfuProtocolError > {
155- self . send_request ( request) . await ;
156- Ok ( self . wait_response ( ) . await )
157- }
158-
159- /// Wait for a request
160- pub async fn wait_request ( & self ) -> RequestData {
161- self . request . receive ( ) . await
165+ pub async fn execute_device_request ( & self , request : Request ) -> InternalResponse {
166+ self . request . execute ( request) . await
162167 }
163168
164169 /// Send a response
165- pub async fn send_response ( & self , response : InternalResponseData ) {
166- self . response . send ( response ) . await ;
170+ pub async fn receive ( & self ) -> CfuRequest {
171+ self . request . receive ( ) . await
167172 }
168173
169174 /// Waits for a response
@@ -213,7 +218,8 @@ impl<W: CfuWriter> CfuComponentDefault<W> {
213218 }
214219 /// wait for a request and process it
215220 pub async fn process_request ( & self ) -> Result < ( ) , CfuError > {
216- match self . device . wait_request ( ) . await {
221+ let request = self . device . receive ( ) . await ;
222+ match request. command . data {
217223 RequestData :: FwVersionRequest => {
218224 let fwv = self . get_fw_version ( ) . await . map_err ( CfuError :: ProtocolError ) ?;
219225 let dev_inf = FwVerComponentInfo :: new ( fwv, self . get_component_id ( ) ) ;
@@ -250,9 +256,7 @@ impl<W: CfuWriter> CfuComponentDefault<W> {
250256 ) ,
251257 component_info : comp_info,
252258 } ;
253- self . device
254- . send_response ( InternalResponseData :: FwVersionResponse ( resp) )
255- . await ;
259+ request. respond ( Ok ( InternalResponseData :: FwVersionResponse ( resp) ) ) ;
256260 }
257261 RequestData :: PrepareComponentForUpdate => {
258262 self . storage_prepare ( )
@@ -263,9 +267,7 @@ impl<W: CfuWriter> CfuComponentDefault<W> {
263267 // accept any and all offers regardless of what version it is
264268 if buf. component_info . component_id == self . get_component_id ( ) {
265269 let resp = FwUpdateOfferResponse :: new_accept ( HostToken :: Driver ) ;
266- self . device
267- . send_response ( InternalResponseData :: OfferResponse ( resp) )
268- . await ;
270+ request. respond ( Ok ( InternalResponseData :: OfferResponse ( resp) ) ) ;
269271 }
270272 }
271273 RequestData :: GiveContent ( buf) => {
@@ -276,8 +278,14 @@ impl<W: CfuWriter> CfuComponentDefault<W> {
276278 . cfu_write ( Some ( offset) , & buf. data )
277279 . await
278280 . map_err ( |e| CfuError :: ProtocolError ( CfuProtocolError :: WriterError ( e) ) ) ?;
281+ request. respond ( Ok ( InternalResponseData :: ContentResponse ( FwUpdateContentResponse :: new (
282+ buf. header . sequence_num ,
283+ CfuUpdateContentResponseStatus :: Success ,
284+ ) ) ) ) ;
285+ }
286+ RequestData :: FinalizeUpdate => {
287+ request. respond ( Ok ( InternalResponseData :: ComponentPrepared ) ) ;
279288 }
280- RequestData :: FinalizeUpdate => { }
281289 }
282290 Ok ( ( ) )
283291 }
0 commit comments