@@ -274,10 +274,11 @@ pub fn respond_get_eid<'a>(
274274/// A Set Endpoint ID request.
275275#[ allow( missing_docs) ]
276276#[ derive( Debug ) ]
277- pub struct SetEndpointId {
278- pub eid : Eid ,
279- pub force : bool ,
280- pub reset : bool ,
277+ pub enum SetEndpointId {
278+ Set ( Eid ) ,
279+ Force ( Eid ) ,
280+ Reset ,
281+ SetDiscovered ,
281282}
282283
283284/// Parse a Set Endpoint ID request.
@@ -289,30 +290,26 @@ pub fn parse_set_eid(req: &MctpControlMsg) -> ControlResult<SetEndpointId> {
289290 return Err ( CompletionCode :: ERROR_INVALID_LENGTH ) ;
290291 }
291292
292- let eid = Eid :: new_normal ( req. body [ 1 ] ) . map_err ( |_| {
293- warn ! ( "Invalid Set EID {}" , req. body[ 1 ] ) ;
294- CompletionCode :: ERROR_INVALID_DATA
295- } ) ?;
296-
297- let mut ret = SetEndpointId {
298- eid,
299- force : false ,
300- reset : false ,
301- } ;
302-
303- match req. body [ 0 ] & 0x03 {
304- // Set
305- 0b00 => ( ) ,
306- // Force
307- 0b01 => ret. force = true ,
293+ let op = req. body [ 0 ] & 0x03 ;
294+ Ok ( match op {
295+ // Set or Force
296+ 0b00 | 0b01 => {
297+ let eid = Eid :: new_normal ( req. body [ 1 ] ) . map_err ( |_| {
298+ warn ! ( "Invalid Set EID {}" , req. body[ 1 ] ) ;
299+ CompletionCode :: ERROR_INVALID_DATA
300+ } ) ?;
301+ if op == 0b00 {
302+ SetEndpointId :: Set ( eid)
303+ } else {
304+ SetEndpointId :: Force ( eid)
305+ }
306+ }
308307 // Reset
309- 0b10 => ret . reset = true ,
308+ 0b10 => SetEndpointId :: Reset ,
310309 // Set Discovered
311- 0b11 => return Err ( CompletionCode :: ERROR_INVALID_DATA ) ,
310+ 0b11 => SetEndpointId :: SetDiscovered ,
312311 _ => unreachable ! ( ) ,
313- }
314-
315- Ok ( ret)
312+ } )
316313}
317314
318315/// Create a Set Endpoint ID response.
@@ -326,7 +323,13 @@ pub fn respond_set_eid<'a>(
326323 return Err ( CompletionCode :: ERROR ) ;
327324 }
328325 let status = if accepted { 0b00000000 } else { 0b00010000 } ;
329- let body = [ CompletionCode :: SUCCESS . into ( ) , status, current_eid. 0 , 0x00 ] ;
326+ let pool_size = 0 ;
327+ let body = [
328+ CompletionCode :: SUCCESS . into ( ) ,
329+ status,
330+ current_eid. 0 ,
331+ pool_size,
332+ ] ;
330333 let rsp_buf = & mut rsp_buf[ 0 ..body. len ( ) ] ;
331334 rsp_buf. clone_from_slice ( & body) ;
332335 req. new_resp ( rsp_buf)
@@ -448,22 +451,26 @@ impl<'a> MctpControl<'a> {
448451 & mut self ,
449452 msg : & [ u8 ] ,
450453 mut resp_chan : impl AsyncRespChannel ,
451- ) -> mctp:: Result < ( ) > {
454+ ) -> mctp:: Result < Option < ControlEvent > > {
452455 let req = MctpControlMsg :: from_buf ( msg) . map_err ( |e| {
453456 // Can't send a response since request couldn't be parsed
454457 debug ! ( "Bad control input {e:?}" ) ;
455458 mctp:: Error :: InvalidInput
456459 } ) ?;
457460
458- let mut resp = match self . handle_req ( & req) . await {
459- Err ( e) => {
460- debug ! ( "Control error response {:?}" , e) ;
461- respond_error ( & req, e, & mut self . rsp_buf )
462- }
463- Ok ( r) => Ok ( r) ,
464- } ?;
461+ let ( mut resp, ev) =
462+ match self . handle_req ( & req, resp_chan. remote_eid ( ) ) . await {
463+ Err ( e) => {
464+ debug ! ( "Control error response {:?}" , e) ;
465+ respond_error ( & req, e, & mut self . rsp_buf ) . map ( |r| ( r, None ) )
466+ }
467+ Ok ( r) => Ok ( r) ,
468+ } ?;
465469
466- resp_chan. send_vectored ( MsgIC ( false ) , & resp. slices ( ) ) . await
470+ resp_chan
471+ . send_vectored ( MsgIC ( false ) , & resp. slices ( ) )
472+ . await ?;
473+ Ok ( ev)
467474 }
468475
469476 /// Set MCTP message types to be reported by the handler.
@@ -485,9 +492,11 @@ impl<'a> MctpControl<'a> {
485492 async fn handle_req (
486493 & mut self ,
487494 req : & ' _ MctpControlMsg < ' _ > ,
488- ) -> ControlResult < MctpControlMsg < ' _ > > {
495+ source_eid : Eid ,
496+ ) -> ControlResult < ( MctpControlMsg < ' _ > , Option < ControlEvent > ) > {
489497 let cc = req. command_code ( ) ;
490498
499+ let mut event = None ;
491500 #[ cfg( feature = "log" ) ]
492501 debug ! ( "Control request {:?}" , cc) ;
493502 match cc {
@@ -496,11 +505,30 @@ impl<'a> MctpControl<'a> {
496505 respond_get_eid ( req, eid, 0 , & mut self . rsp_buf )
497506 }
498507 CommandCode :: SetEndpointID => {
499- let set = parse_set_eid ( req) ?;
500- let res = self . router . set_eid ( set. eid ) . await ;
501- let eid = self . router . get_eid ( ) . await ;
508+ let ( SetEndpointId :: Set ( eid) | SetEndpointId :: Force ( eid) ) =
509+ parse_set_eid ( req) ?
510+ else {
511+ // Don't support Reset or SetDiscovered
512+ return Err ( CompletionCode :: ERROR_INVALID_DATA ) ;
513+ } ;
514+ let old = self . router . get_eid ( ) . await ;
515+ let res = self . router . set_eid ( eid) . await ;
516+ let present_eid = self . router . get_eid ( ) . await ;
517+
518+ if res. is_ok ( ) && old != present_eid {
519+ event = Some ( ControlEvent :: SetEndpointId {
520+ old,
521+ new : present_eid,
522+ bus_owner : source_eid,
523+ } ) ;
524+ }
502525
503- respond_set_eid ( req, res. is_ok ( ) , eid, & mut self . rsp_buf )
526+ respond_set_eid (
527+ req,
528+ res. is_ok ( ) ,
529+ present_eid,
530+ & mut self . rsp_buf ,
531+ )
504532 }
505533 CommandCode :: GetEndpointUUID => {
506534 if let Some ( uuid) = self . uuid {
@@ -516,9 +544,23 @@ impl<'a> MctpControl<'a> {
516544 ) ,
517545 _ => Err ( CompletionCode :: ERROR_UNSUPPORTED_CMD ) ,
518546 }
547+ . map ( |r| ( r, event) )
519548 }
520549}
521550
551+ /// An MCTP control handler event
552+ pub enum ControlEvent {
553+ /// Set Endpoint ID changed EID
554+ SetEndpointId {
555+ /// Previous EID
556+ old : Eid ,
557+ /// New EID
558+ new : Eid ,
559+ /// Bus Owner that set the EID
560+ bus_owner : Eid ,
561+ } ,
562+ }
563+
522564#[ cfg( test) ]
523565mod tests {
524566 use super :: * ;
0 commit comments