@@ -15,7 +15,7 @@ pub(crate) struct Tcp4 {
1515 protocol : NonNull < tcp4:: Protocol > ,
1616 flag : AtomicBool ,
1717 #[ expect( dead_code) ]
18- service_binding : helpers:: ServiceProtocol ,
18+ service_binding : Option < helpers:: ServiceProtocol > ,
1919}
2020
2121const DEFAULT_ADDR : efi:: Ipv4Address = efi:: Ipv4Address { addr : [ 0u8 ; 4 ] } ;
@@ -25,7 +25,7 @@ impl Tcp4 {
2525 let service_binding = helpers:: ServiceProtocol :: open ( tcp4:: SERVICE_BINDING_PROTOCOL_GUID ) ?;
2626 let protocol = helpers:: open_protocol ( service_binding. child_handle ( ) , tcp4:: PROTOCOL_GUID ) ?;
2727
28- Ok ( Self { service_binding, protocol, flag : AtomicBool :: new ( false ) } )
28+ Ok ( Self { service_binding : Some ( service_binding ) , protocol, flag : AtomicBool :: new ( false ) } )
2929 }
3030
3131 pub ( crate ) fn configure (
@@ -42,11 +42,14 @@ impl Tcp4 {
4242 ( DEFAULT_ADDR , 0 )
4343 } ;
4444
45- // FIXME: Remove when passive connections with proper subnet handling are added
46- assert ! ( station_address. is_none( ) ) ;
47- let use_default_address = efi:: Boolean :: TRUE ;
48- let ( station_address, station_port) = ( DEFAULT_ADDR , 0 ) ;
49- let subnet_mask = helpers:: ipv4_to_r_efi ( crate :: net:: Ipv4Addr :: new ( 0 , 0 , 0 , 0 ) ) ;
45+ let use_default_address: r_efi:: efi:: Boolean = station_address. is_none ( ) . into ( ) ;
46+ let ( station_address, station_port) = if let Some ( x) = station_address {
47+ ( helpers:: ipv4_to_r_efi ( * x. ip ( ) ) , x. port ( ) )
48+ } else {
49+ ( DEFAULT_ADDR , 0 )
50+ } ;
51+ let subnet_mask = crate :: net:: Ipv4Addr :: new ( 255 , 255 , 255 , 0 ) ;
52+ let subnet_mask = helpers:: ipv4_to_r_efi ( subnet_mask) ;
5053
5154 let mut config_data = tcp4:: ConfigData {
5255 type_of_service : TYPE_OF_SERVICE ,
@@ -85,6 +88,33 @@ impl Tcp4 {
8588 if r. is_error ( ) { Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) } else { Ok ( config_data) }
8689 }
8790
91+ pub ( crate ) fn accept ( & self ) -> io:: Result < Self > {
92+ let evt = unsafe { self . create_evt ( ) } ?;
93+ let completion_token =
94+ tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
95+ let mut listen_token =
96+ tcp4:: ListenToken { completion_token, new_child_handle : crate :: ptr:: null_mut ( ) } ;
97+
98+ let protocol = self . protocol . as_ptr ( ) ;
99+ let r = unsafe { ( ( * protocol) . accept ) ( protocol, & mut listen_token) } ;
100+ if r. is_error ( ) {
101+ return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
102+ }
103+
104+ unsafe { self . wait_or_cancel ( None , & mut listen_token. completion_token ) } ?;
105+
106+ if completion_token. status . is_error ( ) {
107+ Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
108+ } else {
109+ let handle = NonNull :: new ( listen_token. new_child_handle ) . unwrap ( ) ;
110+ let protocol = helpers:: open_protocol ( handle, tcp4:: PROTOCOL_GUID ) ?;
111+
112+ // The spec does not seem to state if we need to call ServiceBinding->DestroyChild for
113+ // this handle
114+ Ok ( Self { service_binding : None , protocol, flag : AtomicBool :: new ( false ) } )
115+ }
116+ }
117+
88118 pub ( crate ) fn connect ( & self , timeout : Option < Duration > ) -> io:: Result < ( ) > {
89119 let evt = unsafe { self . create_evt ( ) } ?;
90120 let completion_token =
0 commit comments