@@ -173,6 +173,198 @@ static int img_mgmt_find_tlvs(int slot, size_t *start_off, size_t *end_off, uint
173173 return IMG_MGMT_ERR_OK ;
174174}
175175
176+ int img_mgmt_active_slot (int image )
177+ {
178+ return 0 ;
179+ }
180+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO )
181+ /**
182+ * Command handler: image slot info
183+ */
184+ static int img_mgmt_slot_info (struct smp_streamer * ctxt )
185+ {
186+ LOG_ERR ("slot info" );
187+ int rc ;
188+ zcbor_state_t * zse = ctxt -> writer -> zs ;
189+ bool ok ;
190+ uint8_t i = 0 ;
191+ size_t area_sizes [SLOTS_PER_IMAGE ];
192+
193+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO_HOOKS )
194+ int32_t err_rc ;
195+ uint16_t err_group ;
196+ enum mgmt_cb_return status ;
197+ #endif
198+
199+ img_mgmt_take_lock ();
200+
201+ ok = zcbor_tstr_put_lit (zse , "images" ) &&
202+ zcbor_list_start_encode (zse , 10 );
203+
204+ while (i < CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER * SLOTS_PER_IMAGE ) {
205+ const struct flash_area * fa ;
206+ int area_id = img_mgmt_flash_area_id (i );
207+
208+ if ((i % SLOTS_PER_IMAGE ) == 0 ) {
209+ memset (area_sizes , 0 , sizeof (area_sizes ));
210+
211+ ok = zcbor_map_start_encode (zse , 4 ) &&
212+ zcbor_tstr_put_lit (zse , "image" ) &&
213+ zcbor_uint32_put (zse , (uint32_t )(i / SLOTS_PER_IMAGE )) &&
214+ zcbor_tstr_put_lit (zse , "slots" ) &&
215+ zcbor_list_start_encode (zse , 4 );
216+
217+ if (!ok ) {
218+ goto finish ;
219+ }
220+ }
221+
222+ ok = zcbor_map_start_encode (zse , 4 ) &&
223+ zcbor_tstr_put_lit (zse , "slot" ) &&
224+ zcbor_uint32_put (zse , (uint32_t )(i % SLOTS_PER_IMAGE ));
225+
226+ if (!ok ) {
227+ goto finish ;
228+ }
229+
230+ rc = flash_area_open (area_id , & fa );
231+
232+ if (rc ) {
233+ /* Failed opening slot, mark as error */
234+ ok = zcbor_tstr_put_lit (zse , "rc" ) &&
235+ zcbor_int32_put (zse , rc );
236+
237+ LOG_ERR ("Failed to open slot %d for information fetching: %d" , area_id , rc );
238+ } else {
239+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO_HOOKS )
240+ struct img_mgmt_slot_info_slot slot_info_data = {
241+ .image = (i / SLOTS_PER_IMAGE ),
242+ .slot = (i % SLOTS_PER_IMAGE ),
243+ .fa = fa ,
244+ .zse = zse ,
245+ };
246+ #endif
247+
248+ if (sizeof (fa -> fa_size ) == sizeof (uint64_t )) {
249+ ok = zcbor_tstr_put_lit (zse , "size" ) &&
250+ zcbor_uint64_put (zse , fa -> fa_size );
251+ } else {
252+ ok = zcbor_tstr_put_lit (zse , "size" ) &&
253+ zcbor_uint32_put (zse , fa -> fa_size );
254+ }
255+
256+ area_sizes [(i % SLOTS_PER_IMAGE )] = fa -> fa_size ;
257+
258+ if (!ok ) {
259+ goto finish ;
260+ }
261+
262+ /*
263+ * Check if we support uploading to this slot and if so, return the
264+ * image ID
265+ */
266+ #if defined(CONFIG_MCUMGR_GRP_IMG_DIRECT_UPLOAD )
267+ ok = zcbor_tstr_put_lit (zse , "upload_image_id" ) &&
268+ zcbor_uint32_put (zse , (i + 1 ));
269+ #else
270+ if (img_mgmt_active_slot ((i / SLOTS_PER_IMAGE )) != i ) {
271+ ok = zcbor_tstr_put_lit (zse , "upload_image_id" ) &&
272+ zcbor_uint32_put (zse , (i / SLOTS_PER_IMAGE ));
273+ }
274+ #endif
275+
276+ if (!ok ) {
277+ goto finish ;
278+ }
279+
280+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO_HOOKS )
281+ status = mgmt_callback_notify (MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_SLOT ,
282+ & slot_info_data , sizeof (slot_info_data ),
283+ & err_rc , & err_group );
284+ #endif
285+
286+ flash_area_close (fa );
287+
288+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO_HOOKS )
289+ if (status != MGMT_CB_OK ) {
290+ if (status == MGMT_CB_ERROR_RC ) {
291+ img_mgmt_release_lock ();
292+ return err_rc ;
293+ }
294+
295+ ok = smp_mgmt_reset_zse (ctxt ) &&
296+ smp_add_cmd_err (zse , err_group , (uint16_t )err_rc );
297+
298+ goto finish ;
299+ }
300+ #endif
301+ }
302+
303+ ok &= zcbor_map_end_encode (zse , 4 );
304+
305+ if (!ok ) {
306+ goto finish ;
307+ }
308+
309+ if ((i % SLOTS_PER_IMAGE ) == (SLOTS_PER_IMAGE - 1 )) {
310+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO_HOOKS )
311+ struct img_mgmt_slot_info_image image_info_data = {
312+ .image = (i / SLOTS_PER_IMAGE ),
313+ .zse = zse ,
314+ };
315+ #endif
316+
317+ ok = zcbor_list_end_encode (zse , 4 );
318+
319+ if (!ok ) {
320+ goto finish ;
321+ }
322+
323+ #if defined(CONFIG_MCUMGR_GRP_IMG_TOO_LARGE_SYSBUILD ) || \
324+ defined(CONFIG_MCUMGR_GRP_IMG_TOO_LARGE_BOOTLOADER_INFO )
325+ ok = img_mgmt_slot_max_size (area_sizes , zse );
326+
327+ if (!ok ) {
328+ goto finish ;
329+ }
330+ #endif
331+
332+ #if defined(CONFIG_MCUMGR_GRP_IMG_SLOT_INFO_HOOKS )
333+ status = mgmt_callback_notify (MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_IMAGE ,
334+ & image_info_data , sizeof (image_info_data ),
335+ & err_rc , & err_group );
336+
337+ if (status != MGMT_CB_OK ) {
338+ if (status == MGMT_CB_ERROR_RC ) {
339+ img_mgmt_release_lock ();
340+ return err_rc ;
341+ }
342+
343+ ok = smp_mgmt_reset_zse (ctxt ) &&
344+ smp_add_cmd_err (zse , err_group , (uint16_t )err_rc );
345+
346+ goto finish ;
347+ }
348+ #endif
349+
350+ ok = zcbor_map_end_encode (zse , 4 );
351+
352+ if (!ok ) {
353+ goto finish ;
354+ }
355+ }
356+
357+ ++ i ;
358+ }
359+
360+ ok = zcbor_list_end_encode (zse , 10 );
361+
362+ finish :
363+ img_mgmt_release_lock ();
364+
365+ return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE ;
366+ }
367+ #endif
176368
177369
178370/*
@@ -692,10 +884,18 @@ static int img_mgmt_translate_error_code(uint16_t err)
692884#endif
693885
694886static const struct mgmt_handler img_mgmt_handlers [] = {
887+ [IMG_MGMT_ID_STATE ] = {
888+ .mh_read = img_mgmt_state_read ,
889+ .mh_write = NULL
890+ },
695891 [IMG_MGMT_ID_UPLOAD ] = {
696892 .mh_read = NULL ,
697893 .mh_write = img_mgmt_upload
698894 },
895+ [IMG_MGMT_ID_SLOT_INFO ] = {
896+ .mh_read = img_mgmt_slot_info ,
897+ .mh_write = NULL
898+ },
699899};
700900
701901static const struct mgmt_handler img_mgmt_handlers [];
0 commit comments