@@ -36,6 +36,11 @@ LOG_MODULE_REGISTER(mender_stm32l4a6_zephyr_example, LOG_LEVEL_INF);
36
36
#include <zephyr/net/net_mgmt.h>
37
37
#include <zephyr/sys/reboot.h>
38
38
39
+ #ifdef CONFIG_LLEXT
40
+ #include <zephyr/llext/llext.h>
41
+ #include <zephyr/llext/buf_loader.h>
42
+ #endif /* CONFIG_LLEXT */
43
+
39
44
/*
40
45
* Amazon Root CA 1 certificate, retrieved from https://www.amazontrust.com/repository in DER format.
41
46
* It is converted to include file in application CMakeLists.txt.
@@ -70,6 +75,16 @@ static K_EVENT_DEFINE(mender_client_events);
70
75
*/
71
76
static struct net_mgmt_event_callback mgmt_cb ;
72
77
78
+ #ifdef CONFIG_LLEXT
79
+
80
+ /**
81
+ * @brief Hello-world module data and size
82
+ */
83
+ static void * hello_world_module_data = NULL ;
84
+ static size_t hello_world_module_size = 0 ;
85
+
86
+ #endif /* CONFIG_LLEXT */
87
+
73
88
/**
74
89
* @brief print DHCPv4 address information
75
90
* @param iface Interface
@@ -211,10 +226,60 @@ authentication_failure_cb(void) {
211
226
static mender_err_t
212
227
deployment_status_cb (mender_deployment_status_t status , char * desc ) {
213
228
229
+ mender_err_t ret = MENDER_OK ;
230
+
214
231
/* We can do something else if required */
215
232
LOG_INF ("Deployment status is '%s'" , desc );
216
233
217
- return MENDER_OK ;
234
+ #ifdef CONFIG_LLEXT
235
+
236
+ /* Management of hello-world module */
237
+ if ((NULL != hello_world_module_data ) && (0 != hello_world_module_size )) {
238
+
239
+ /* Treatment depending ofthe status */
240
+ if (MENDER_DEPLOYMENT_STATUS_INSTALLING == status ) {
241
+
242
+ /* Load hello-world module */
243
+ struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER (hello_world_module_data , hello_world_module_size );
244
+ struct llext_loader * ldr = & buf_loader .loader ;
245
+ struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT ;
246
+ struct llext * ext ;
247
+ if (0 != llext_load (ldr , "hello-world" , & ext , & ldr_parm )) {
248
+ LOG_ERR ("Unable to load module" );
249
+ ret = MENDER_FAIL ;
250
+ } else {
251
+
252
+ /* Call hello_world function */
253
+ void (* hello_world_fn )() = llext_find_sym (& ext -> exp_tab , "hello_world" );
254
+ if (NULL != hello_world_fn ) {
255
+ hello_world_fn ();
256
+ }
257
+
258
+ /* Unload module */
259
+ llext_unload (& ext );
260
+ }
261
+
262
+ /* Release memory */
263
+ if (NULL != hello_world_module_data ) {
264
+ free (hello_world_module_data );
265
+ hello_world_module_data = NULL ;
266
+ }
267
+ hello_world_module_size = 0 ;
268
+
269
+ } else if (MENDER_DEPLOYMENT_STATUS_FAILURE == status ) {
270
+
271
+ /* Release memory */
272
+ if (NULL != hello_world_module_data ) {
273
+ free (hello_world_module_data );
274
+ hello_world_module_data = NULL ;
275
+ }
276
+ hello_world_module_size = 0 ;
277
+ }
278
+ }
279
+
280
+ #endif /* CONFIG_LLEXT */
281
+
282
+ return ret ;
218
283
}
219
284
220
285
/**
@@ -258,6 +323,41 @@ config_updated_cb(mender_keystore_t *configuration) {
258
323
#endif /* CONFIG_MENDER_CLIENT_CONFIGURE_STORAGE */
259
324
#endif /* CONFIG_MENDER_CLIENT_ADD_ON_CONFIGURE */
260
325
326
+ #ifdef CONFIG_LLEXT
327
+
328
+ static mender_err_t
329
+ hello_world_module_cb (char * id , char * artifact_name , char * type , cJSON * meta_data , char * filename , size_t size , void * data , size_t index , size_t length ) {
330
+
331
+ (void )id ;
332
+ (void )artifact_name ;
333
+ (void )type ;
334
+ (void )meta_data ;
335
+ (void )filename ;
336
+ (void )size ;
337
+ (void )index ;
338
+ void * tmp ;
339
+
340
+ /* Add data to the hello-world module data buffer */
341
+ if (NULL != data ) {
342
+ if (NULL == (tmp = realloc (hello_world_module_data , hello_world_module_size + length ))) {
343
+ LOG_ERR ("Unable to allocate memory" );
344
+ if (NULL != hello_world_module_data ) {
345
+ free (hello_world_module_data );
346
+ hello_world_module_data = NULL ;
347
+ }
348
+ hello_world_module_size = 0 ;
349
+ return MENDER_FAIL ;
350
+ }
351
+ hello_world_module_data = tmp ;
352
+ memcpy ((void * )(((uint8_t * )hello_world_module_data ) + hello_world_module_size ), data , length );
353
+ hello_world_module_size += length ;
354
+ }
355
+
356
+ return MENDER_OK ;
357
+ }
358
+
359
+ #endif /* CONFIG_LLEXT */
360
+
261
361
/**
262
362
* @brief Main function
263
363
* @return Always returns 0
@@ -324,6 +424,12 @@ main(void) {
324
424
assert (MENDER_OK == mender_client_init (& mender_client_config , & mender_client_callbacks ));
325
425
LOG_INF ("Mender client initialized" );
326
426
427
+ #ifdef CONFIG_LLEXT
428
+ /* Register LLEXT hello-world module, no reboot after installing the module, no verification of artifact name to check the version of the module */
429
+ assert (MENDER_OK == mender_client_register_artifact_type ("hello-world" , & hello_world_module_cb , false, NULL ));
430
+ LOG_INF ("Mender client registered hello-world module" );
431
+ #endif /* CONFIG_LLEXT */
432
+
327
433
/* Initialize mender add-ons */
328
434
#ifdef CONFIG_MENDER_CLIENT_ADD_ON_CONFIGURE
329
435
mender_configure_config_t mender_configure_config = { .refresh_interval = 0 };
0 commit comments