1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #ifndef H_IMG_MGMT_
21 #define H_IMG_MGMT_
22 
23 #include <inttypes.h>
24 #include "img_mgmt_config.h"
25 #include "mgmt/mgmt.h"
26 
27 struct image_version;
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #define IMG_MGMT_HASH_STR         48
34 #define IMG_MGMT_HASH_LEN         32
35 #define IMG_MGMT_DATA_SHA_LEN     32 /* SHA256 */
36 
37 /*
38  * Image state flags
39  */
40 #define IMG_MGMT_STATE_F_PENDING    0x01
41 #define IMG_MGMT_STATE_F_CONFIRMED  0x02
42 #define IMG_MGMT_STATE_F_ACTIVE     0x04
43 #define IMG_MGMT_STATE_F_PERMANENT  0x08
44 
45 #define IMG_MGMT_VER_MAX_STR_LEN    25  /* 255.255.65535.4294967295\0 */
46 
47 /*
48  * Swap Types for image management state machine
49  */
50 #define IMG_MGMT_SWAP_TYPE_NONE     0
51 #define IMG_MGMT_SWAP_TYPE_TEST     1
52 #define IMG_MGMT_SWAP_TYPE_PERM     2
53 #define IMG_MGMT_SWAP_TYPE_REVERT   3
54 
55 /**
56  * Command IDs for image management group.
57  */
58 #define IMG_MGMT_ID_STATE           0
59 #define IMG_MGMT_ID_UPLOAD          1
60 #define IMG_MGMT_ID_FILE            2
61 #define IMG_MGMT_ID_CORELIST        3
62 #define IMG_MGMT_ID_CORELOAD        4
63 #define IMG_MGMT_ID_ERASE           5
64 
65 /*
66  * IMG_MGMT_ID_UPLOAD statuses.
67  */
68 #define IMG_MGMT_ID_UPLOAD_STATUS_START         0
69 #define IMG_MGMT_ID_UPLOAD_STATUS_ONGOING       1
70 #define IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE      2
71 
72 extern int boot_current_slot;
73 extern struct img_mgmt_state g_img_mgmt_state;
74 
75 /** Represents an individual upload request. */
76 struct img_mgmt_upload_req {
77     unsigned long long int image;   /* 0 by default */
78     unsigned long long int off;     /* -1 if unspecified */
79     unsigned long long int size;    /* -1 if unspecified */
80     size_t data_len;
81     size_t data_sha_len;
82     uint8_t img_data[IMG_MGMT_UL_CHUNK_SIZE];
83     uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN];
84     bool upgrade;                   /* Only allow greater version numbers. */
85 };
86 
87 /** Global state for upload in progress. */
88 struct img_mgmt_state {
89     /** Flash area being written; -1 if no upload in progress. */
90     int area_id;
91     /** Flash offset of next chunk. */
92     uint32_t off;
93     /** Total size of image data. */
94     uint32_t size;
95     /** Hash of image data; used for resumption of a partial upload. */
96     uint8_t data_sha_len;
97     uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN];
98 #if IMG_MGMT_LAZY_ERASE
99     int sector_id;
100     uint32_t sector_end;
101 #endif
102 };
103 
104 /** Describes what to do during processing of an upload request. */
105 struct img_mgmt_upload_action {
106     /** The total size of the image. */
107     unsigned long long size;
108     /** The number of image bytes to write to flash. */
109     int write_bytes;
110     /** The flash area to write to. */
111     int area_id;
112     /** Whether to process the request; false if offset is wrong. */
113     bool proceed;
114     /** Whether to erase the destination flash area. */
115     bool erase;
116 };
117 
118 /**
119  * @brief Registers the image management command handler group.
120  */
121 void img_mgmt_register_group(void);
122 
123 /**
124  * @brief Unregisters the image management command handler group.
125  */
126 void img_mgmt_unregister_group(void);
127 
128 /*
129  * @brief Read info of an image give the slot number
130  *
131  * @param image_slot     Image slot to read info from
132  * @param image_version  Image version to be filled up
133  * @param hash           Ptr to the read image hash
134  * @param flags          Ptr to flags filled up from the image
135  */
136 int img_mgmt_read_info(int image_slot, struct image_version *ver,
137                        uint8_t *hash, uint32_t *flags);
138 
139 /**
140  * @brief Get the current running image version
141  *
142  * @param image_version Given image version
143  *
144  * @return 0 on success, non-zero on failure
145  */
146 int img_mgmt_my_version(struct image_version *ver);
147 
148 /**
149  * @brief Get image version in string from image_version
150  *
151  * @param image_version Structure filled with image version
152  *                      information
153  * @param dst           Destination string created from the given
154  *                      in image version
155  *
156  * @return 0 on success, non-zero on failure
157  */
158 int img_mgmt_ver_str(const struct image_version *ver, char *dst);
159 
160 /**
161  * @brief Check if the image slot is in use
162  *
163  * @param slot Slot to check if its in use
164  *
165  * @return 0 on success, non-zero on failure
166  */
167 int img_mgmt_slot_in_use(int slot);
168 
169 /**
170  * @brief Check if the DFU status is pending
171  *
172  * @return 1 if there's pending DFU otherwise 0.
173  */
174 int img_mgmt_state_any_pending(void);
175 
176 /**
177  * @brief Collects information about the specified image slot
178  *
179  * @param query_slot Slot to read state flags from
180  *
181  * @return return the state flags
182  */
183 uint8_t img_mgmt_state_flags(int query_slot);
184 
185 /**
186  * @brief Sets the pending flag for the specified image slot.  That is, the system
187  * will swap to the specified image on the next reboot.  If the permanent
188  * argument is specified, the system doesn't require a confirm after the swap
189  * occurs.
190  *
191  * @param slot       Image slot to set pending
192  * @param permanent  If set no confirm is required after image swap
193  *
194  * @return 0 on success, non-zero on failure
195  */
196 int img_mgmt_state_set_pending(int slot, int permanent);
197 
198 /**
199  * Confirms the current image state.  Prevents a fallback from occurring on the
200  * next reboot if the active image is currently being tested.
201  *
202  * @return 0 on success, non -zero on failure
203  */
204 int img_mgmt_state_confirm(void);
205 
206 /** @brief Generic callback function for events */
207 typedef void (*img_mgmt_dfu_cb)(void);
208 
209 /** Callback function pointers */
210 typedef struct {
211     img_mgmt_dfu_cb dfu_started_cb;
212     img_mgmt_dfu_cb dfu_stopped_cb;
213     img_mgmt_dfu_cb dfu_pending_cb;
214     img_mgmt_dfu_cb dfu_confirmed_cb;
215 } img_mgmt_dfu_callbacks_t;
216 
217 /** @typedef img_mgmt_upload_fn
218  * @brief Application callback that is executed when an image upload request is
219  * received.
220  *
221  * The callback's return code determines whether the upload request is accepted
222  * or rejected.  If the callback returns 0, processing of the upload request
223  * proceeds.  If the callback returns nonzero, the request is rejected with a
224  * response containing an `rc` value equal to the return code.
225  *
226  * @param offset                The offset specified by the incoming request.
227  * @param size                  The total size of the image being uploaded.
228  * @param arg                   Optional argument specified when the callback
229  *                                  was configured.
230  *
231  * @return                      0 if the upload request should be accepted;
232  *                              nonzero to reject the request with the
233  *                                  specified status.
234  */
235 typedef int img_mgmt_upload_fn(uint32_t offset, uint32_t size, void *arg);
236 
237 /**
238  * @brief Configures a callback that gets called whenever a valid image upload
239  * request is received.
240  *
241  * The callback's return code determines whether the upload request is accepted
242  * or rejected.  If the callback returns 0, processing of the upload request
243  * proceeds.  If the callback returns nonzero, the request is rejected with a
244  * response containing an `rc` value equal to the return code.
245  *
246  * @param cb                    The callback to execute on rx of an upload
247  *                                  request.
248  * @param arg                   Optional argument that gets passed to the
249  *                                  callback.
250  */
251 void img_mgmt_set_upload_cb(img_mgmt_upload_fn *cb, void *arg);
252 void img_mgmt_register_callbacks(const img_mgmt_dfu_callbacks_t *cb_struct);
253 void img_mgmt_dfu_stopped(void);
254 void img_mgmt_dfu_started(void);
255 void img_mgmt_dfu_pending(void);
256 void img_mgmt_dfu_confirmed(void);
257 
258 #if IMG_MGMT_VERBOSE_ERR
259 int img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn);
260 extern const char *img_mgmt_err_str_app_reject;
261 extern const char *img_mgmt_err_str_hdr_malformed;
262 extern const char *img_mgmt_err_str_magic_mismatch;
263 extern const char *img_mgmt_err_str_no_slot;
264 extern const char *img_mgmt_err_str_flash_open_failed;
265 extern const char *img_mgmt_err_str_flash_erase_failed;
266 extern const char *img_mgmt_err_str_flash_write_failed;
267 extern const char *img_mgmt_err_str_downgrade;
268 extern const char *img_mgmt_err_str_image_bad_flash_addr;
269 #else
270 #define img_mgmt_error_rsp(ctxt, rc, rsn)             (rc)
271 #define img_mgmt_err_str_app_reject                   NULL
272 #define img_mgmt_err_str_hdr_malformed                NULL
273 #define img_mgmt_err_str_magic_mismatch               NULL
274 #define img_mgmt_err_str_no_slot                      NULL
275 #define img_mgmt_err_str_flash_open_failed            NULL
276 #define img_mgmt_err_str_flash_erase_failed           NULL
277 #define img_mgmt_err_str_flash_write_failed           NULL
278 #define img_mgmt_err_str_downgrade                    NULL
279 #define img_mgmt_err_str_image_bad_flash_addr         NULL
280 #endif
281 
282 #ifdef __cplusplus
283 }
284 #endif
285 
286 #endif /* H_IMG_MGMT_ */
287