@@ -11,113 +11,153 @@ use crate::CommandUninstall;
1111
1212#[ async_trait]
1313impl CommandUninstall for ProbeRSConnection {
14- async fn uninstall_app ( & mut self , settings : & BoardSettings ) -> Result < ( ) , TockloaderError > {
14+ async fn uninstall_app (
15+ & mut self ,
16+ settings : & BoardSettings ,
17+ app_name : Option < & str > ,
18+ ) -> Result < ( ) , TockloaderError > {
1519 if !self . is_open ( ) {
1620 return Err ( InternalError :: ConnectionNotOpen . into ( ) ) ;
1721 }
1822 let session = self . session . as_mut ( ) . expect ( "Board must be open" ) ;
19-
20- let mut installed_apps: Vec < AppData > = Vec :: new ( ) ;
21- let mut index: u8 = 1 ;
22- let mut appaddr: u64 = settings. start_address ;
23-
24- // make "Delete all" a part of this vector
25- installed_apps. push ( AppData {
26- name : "Delete all" . to_string ( ) ,
27- address : settings. start_address ,
28- index : 0 ,
29- size : 0 ,
30- } ) ;
31-
3223 loop {
33- let mut board_core = session. core ( self . target_info . core ) ?;
34- // Read the first 8 bytes, which is the length of a TLV header.
35- let mut appdata = vec ! [ 0u8 ; 8 ] ;
36-
37- board_core. read ( appaddr, & mut appdata) ?;
38- let tbf_version: u16 ;
39- let header_size: u16 ;
40- let app_size: u32 ;
41-
42- // The first 8 bytes of the application data contain the TBF header
43- // lengths and version.
44- //
45- // Note on expect: `read` always fills up the entire buffer, which
46- // was previously declared as 8 bytes.
47- match parse_tbf_header_lengths (
48- & appdata[ 0 ..8 ]
49- . try_into ( )
50- . expect ( "Buffer length must be at least 8 bytes long." ) ,
51- ) {
52- Ok ( data) => {
53- tbf_version = data. 0 ;
54- header_size = data. 1 ;
55- app_size = data. 2 ;
56- }
57- _ => break ,
58- } ;
59-
60- // Read the rest of the header
61- let mut header_data = vec ! [ 0u8 ; header_size. into( ) ] ;
62- board_core. read ( appaddr, & mut header_data) ?;
24+ let mut installed_apps: Vec < AppData > = Vec :: new ( ) ;
25+ let mut index: u8 = 1 ;
26+ let mut appaddr: u64 = settings. start_address ;
6327
64- let header = parse_tbf_header ( & header_data, tbf_version)
65- . map_err ( TockError :: InvalidAppTbfHeader ) ?;
66- let pname = header. get_package_name ( ) . unwrap_or ( "" ) . to_owned ( ) ;
28+ // make "Delete all" a part of this vector
6729 installed_apps. push ( AppData {
68- address : appaddr ,
69- name : pname ,
70- size : app_size ,
71- index ,
30+ name : "Delete all" . to_string ( ) ,
31+ address : settings . start_address ,
32+ index : 0 ,
33+ size : 0 ,
7234 } ) ;
73- index += 1 ;
74- appaddr += app_size as u64 ;
75- }
76- if installed_apps. len ( ) == 1 {
77- return Err ( TockloaderError :: Tock ( TockError :: MissingAttribute (
78- "No apps installed" . to_string ( ) ,
79- ) ) ) ;
80- }
81- let app = inquire:: Select :: new (
82- "Which app do you want to uninstall?" ,
83- installed_apps. iter ( ) . clone ( ) . collect ( ) ,
84- )
85- . prompt ( )
86- . context ( "No apps installed" )
87- . unwrap ( ) ;
88- let address: u64 ; // here we'll write the remaining apps
89- let buf_size: usize = if app. index > 0 {
90- // buf_size is the size of all apps that are to the right of our target app
91- address = app. address ; // put remaining apps where target app starts
92- installed_apps. iter ( ) . fold ( 0 , |total_size, aux_app| {
93- if aux_app. index > app. index {
94- total_size + aux_app. size as usize // increase if app is to the right
35+
36+ loop {
37+ let mut board_core = session. core ( self . target_info . core ) ?;
38+ // Read the first 8 bytes, which is the length of a TLV header.
39+ let mut appdata = vec ! [ 0u8 ; 8 ] ;
40+
41+ board_core. read ( appaddr, & mut appdata) ?;
42+ let tbf_version: u16 ;
43+ let header_size: u16 ;
44+ let app_size: u32 ;
45+
46+ // The first 8 bytes of the application data contain the TBF header
47+ // lengths and version.
48+ //
49+ // Note on expect: `read` always fills up the entire buffer, which
50+ // was previously declared as 8 bytes.
51+ match parse_tbf_header_lengths (
52+ & appdata[ 0 ..8 ]
53+ . try_into ( )
54+ . expect ( "Buffer length must be at least 8 bytes long." ) ,
55+ ) {
56+ Ok ( data) => {
57+ tbf_version = data. 0 ;
58+ header_size = data. 1 ;
59+ app_size = data. 2 ;
60+ }
61+ _ => break ,
62+ } ;
63+
64+ // Read the rest of the header
65+ let mut header_data = vec ! [ 0u8 ; header_size. into( ) ] ;
66+ board_core. read ( appaddr, & mut header_data) ?;
67+
68+ let header = parse_tbf_header ( & header_data, tbf_version)
69+ . map_err ( TockError :: InvalidAppTbfHeader ) ?;
70+ let pname = header. get_package_name ( ) . unwrap_or ( "" ) . to_owned ( ) ;
71+ installed_apps. push ( AppData {
72+ address : appaddr,
73+ name : pname,
74+ size : app_size,
75+ index,
76+ } ) ;
77+ index += 1 ;
78+ appaddr += app_size as u64 ;
79+ }
80+ if installed_apps. len ( ) == 1 {
81+ if app_name == None {
82+ return Err ( TockloaderError :: Tock ( TockError :: MissingAttribute (
83+ "No apps installed" . to_string ( ) ,
84+ ) ) ) ;
9585 } else {
96- total_size
86+ return Err ( TockloaderError :: Tock ( TockError :: MissingAttribute (
87+ "Requested app is not instaleld" . to_string ( ) ,
88+ ) ) ) ;
9789 }
98- } )
99- } else {
100- // Delete all case
101- address = settings. start_address ; // put a 0x0 byte here, all apps will become invalid
102- 0
103- } ;
104- let mut buffer = vec ! [ 0u8 ; buf_size] ;
105- if buf_size > 0 {
106- // we have apps to the right
107- let mut board_core = session. core ( self . target_info . core ) ?;
108- board_core. read ( installed_apps[ app. index as usize + 1 ] . address , & mut buffer) ?;
109- }
90+ }
91+ let mut app: & AppData ;
92+ match app_name {
93+ Some ( app_name) => {
94+ app = match installed_apps. iter ( ) . find ( |iter| iter. name == app_name) {
95+ Some ( app) => app,
96+ None => break ,
97+ }
98+ }
99+ None => loop {
100+ app = inquire:: Select :: new (
101+ "Which app do you want to uninstall?" ,
102+ installed_apps. iter ( ) . clone ( ) . collect ( ) ,
103+ )
104+ . prompt ( )
105+ . context ( "No apps installed" )
106+ . unwrap ( ) ;
107+
108+ if inquire:: Select :: new (
109+ format ! ( "You chose {app}" , ) . as_str ( ) ,
110+ [ "Cancel" , "Confirm" ] . to_vec ( ) ,
111+ )
112+ . prompt ( )
113+ . unwrap ( )
114+ == "Confirm"
115+ {
116+ break ;
117+ }
118+ } ,
119+ }
120+ let address: u64 ; // here we'll write the remaining apps
121+ let buf_size: usize = if app. index > 0 {
122+ // buf_size is the size of all apps that are to the right of our target app
123+ address = app. address ; // put remaining apps where target app starts
124+ installed_apps. iter ( ) . fold ( 0 , |total_size, aux_app| {
125+ if aux_app. index > app. index {
126+ total_size + aux_app. size as usize // increase if app is to the right
127+ } else {
128+ total_size
129+ }
130+ } )
131+ } else {
132+ // Delete all case
133+ address = settings. start_address ; // put a 0x0 byte here, all apps will become invalid
134+ installed_apps. iter ( ) . fold ( 0 , |total_size, aux_app| {
135+ total_size + aux_app. size as usize // increase if app is to the right
136+ } )
137+ } ;
138+ let mut buffer = vec ! [ 0u8 ; buf_size] ;
139+ if buf_size > 0 && app. index > 0 {
140+ // copy apps only if we didn't choose "Delete all"
141+ // we have apps to the right
142+ let mut board_core = session. core ( self . target_info . core ) ?;
143+ board_core. read ( installed_apps[ app. index as usize + 1 ] . address , & mut buffer) ?;
144+ }
110145
111- buffer. push ( 0x0 ) ;
112- let mut loader = session. target ( ) . flash_loader ( ) ;
146+ buffer. extend ( [ 0x0 ; 512 ] ) ; // add an extra page of 0x0
147+ let mut loader = session. target ( ) . flash_loader ( ) ;
113148
114- loader. add_data ( address, & buffer) ?;
149+ loader. add_data ( address, & buffer) ?;
115150
116- let mut options = DownloadOptions :: default ( ) ;
117- options. keep_unwritten_bytes = true ;
151+ let mut options = DownloadOptions :: default ( ) ;
152+ options. keep_unwritten_bytes = true ;
118153
119- loader. commit ( session, options) ?;
154+ loader. commit ( session, options) ?;
120155
156+ if app_name == None {
157+ // exit if we don't have a name set, else continue removing
158+ break ;
159+ }
160+ }
121161 Ok ( ( ) )
122162 }
123163}
0 commit comments