Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
arm_uc_pal_linux_implementation_internal.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "arm_uc_config.h" 00020 #if defined(ARM_UC_FEATURE_PAL_LINUX) && (ARM_UC_FEATURE_PAL_LINUX == 1) 00021 #if defined(TARGET_IS_PC_LINUX) 00022 #define _FILE_OFFSET_BITS 64 00023 00024 #include "update-client-pal-linux/arm_uc_pal_linux_implementation_internal.h" 00025 00026 #include "update-client-metadata-header/arm_uc_metadata_header_v2.h" 00027 #include "update-client-common/arm_uc_scheduler.h" 00028 00029 #define __STDC_FORMAT_MACROS 00030 #include <inttypes.h> 00031 #include <stdio.h> 00032 #include <errno.h> 00033 #include <pthread.h> 00034 #include <stdlib.h> 00035 #include <sys/stat.h> 00036 #include <sys/wait.h> 00037 00038 /* pointer to external callback handler */ 00039 static ARM_UC_PAAL_UPDATE_SignalEvent_t arm_uc_pal_external_callback = NULL; 00040 00041 linux_worker_thread_info_t linux_worker_thread = { .attr_initialized = 0, .mutex = PTHREAD_MUTEX_INITIALIZER }; 00042 00043 // storage set aside for adding event_cb to the event queue 00044 static arm_uc_callback_t event_cb_storage = { 0 }; 00045 00046 void arm_uc_pal_linux_signal_callback(uint32_t event, bool from_thread) 00047 { 00048 if (arm_uc_pal_external_callback) { 00049 if (from_thread) { 00050 /* Run given callback in the update client's thread */ 00051 ARM_UC_PostCallback(&event_cb_storage, arm_uc_pal_external_callback, event); 00052 } else { 00053 arm_uc_pal_external_callback(event); 00054 } 00055 } 00056 if (from_thread) { 00057 /* The last thing that the thread does is call arm_uc_pal_linux_signal_callback(), 00058 * so unlock the thread mutex so that another thread can be created if needed */ 00059 pthread_mutex_unlock(&linux_worker_thread.mutex); 00060 } 00061 } 00062 00063 void arm_uc_pal_linux_internal_set_callback(ARM_UC_PAAL_UPDATE_SignalEvent_t callback) 00064 { 00065 arm_uc_pal_external_callback = callback; 00066 } 00067 00068 static uint32_t arm_uc_offset = 0; 00069 static arm_uc_buffer_t *arm_uc_buffer = NULL; 00070 static arm_uc_firmware_details_t *arm_uc_details = NULL; 00071 static arm_uc_installer_details_t *arm_uc_installer = NULL; 00072 static uint32_t *arm_uc_location = NULL; 00073 static uint32_t arm_uc_location_buffer = 0; 00074 00075 void arm_uc_pal_linux_internal_set_offset(uint32_t offset) 00076 { 00077 arm_uc_offset = offset; 00078 } 00079 00080 void arm_uc_pal_linux_internal_set_buffer(arm_uc_buffer_t *buffer) 00081 { 00082 arm_uc_buffer = buffer; 00083 } 00084 00085 void arm_uc_pal_linux_internal_set_details(arm_uc_firmware_details_t *details) 00086 { 00087 arm_uc_details = details; 00088 } 00089 00090 void arm_uc_pal_linux_internal_set_installer(arm_uc_installer_details_t *details) 00091 { 00092 arm_uc_installer = details; 00093 } 00094 00095 void arm_uc_pal_linux_internal_set_location(uint32_t *location) 00096 { 00097 if (location) { 00098 arm_uc_location_buffer = *location; 00099 arm_uc_location = &arm_uc_location_buffer; 00100 } else { 00101 arm_uc_location = NULL; 00102 } 00103 } 00104 00105 arm_uc_error_t arm_uc_pal_linux_internal_file_path(char *buffer, 00106 size_t buffer_length, 00107 const char *folder, 00108 const char *type, 00109 uint32_t *location) 00110 { 00111 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00112 00113 if (buffer && folder && type) { 00114 int actual_length = 0; 00115 00116 if (location) { 00117 /* construct file path using location */ 00118 actual_length = snprintf(buffer, buffer_length, 00119 "%s/%s_%" PRIu32 ".bin", folder, type, *location); 00120 } else { 00121 /* construct file path without location */ 00122 actual_length = snprintf(buffer, buffer_length, 00123 "%s/%s.bin", folder, type); 00124 } 00125 00126 /* check that the buffer is large enough */ 00127 if (actual_length < buffer_length) { 00128 result.code = ERR_NONE; 00129 } 00130 } 00131 00132 return result; 00133 } 00134 00135 static bool arm_uc_pal_linux_internal_command(arm_ucp_worker_t *parameters, 00136 char *command, 00137 size_t command_length) 00138 { 00139 /* default to failed */ 00140 bool valid = false; 00141 00142 if (parameters && command) { 00143 /* invert status */ 00144 valid = true; 00145 00146 int length = snprintf(command, 00147 command_length, 00148 "%s ", 00149 parameters->command); 00150 00151 /* initialize remaining */ 00152 int remaining = command_length - length; 00153 00154 /* add header parameter if requested */ 00155 if ((remaining > 0) && (parameters->header)) { 00156 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00157 00158 /* construct header file path */ 00159 arm_uc_error_t result = 00160 arm_uc_pal_linux_internal_file_path(file_path, 00161 sizeof(file_path), 00162 ARM_UC_HEADER_FOLDER_PATH, 00163 "header", 00164 arm_uc_location); 00165 00166 /* generated valid file path */ 00167 if (result.error == ERR_NONE) { 00168 /* add parameter to command line */ 00169 length += snprintf(&command[length], 00170 remaining, 00171 "-h %s ", 00172 file_path); 00173 } 00174 00175 /* update remaining */ 00176 remaining = ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH - length; 00177 00178 /* check validity */ 00179 valid = ((result.error == ERR_NONE) && (remaining > 0)); 00180 } 00181 00182 /* add firmware parameter if requested */ 00183 if ((valid) && (parameters->firmware)) { 00184 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00185 00186 /* construct firmware file path */ 00187 arm_uc_error_t result = 00188 arm_uc_pal_linux_internal_file_path(file_path, 00189 sizeof(file_path), 00190 ARM_UC_FIRMWARE_FOLDER_PATH, 00191 "firmware", 00192 arm_uc_location); 00193 00194 /* generated valid file path */ 00195 if (result.error == ERR_NONE) { 00196 /* add parameter to command line */ 00197 length += snprintf(&command[length], 00198 remaining, 00199 "-f %s ", 00200 file_path); 00201 } 00202 00203 /* update remaining */ 00204 remaining = ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH - length; 00205 00206 /* check validity */ 00207 valid = ((result.error == ERR_NONE) && (remaining > 0)); 00208 } 00209 00210 /* add location parameter if requested */ 00211 if ((valid) && (parameters->location)) { 00212 /* add parameter to command line */ 00213 length += snprintf(&command[length], 00214 remaining, 00215 "-l %" PRIu32 " ", 00216 *arm_uc_location); 00217 00218 /* update remaining */ 00219 remaining = ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH - length; 00220 00221 /* check validity */ 00222 valid = (remaining > 0); 00223 } 00224 00225 /* add offset parameter if requested */ 00226 if ((valid) && (parameters->offset)) { 00227 /* add parameter to command line */ 00228 length += snprintf(&command[length], 00229 remaining, 00230 "-o %" PRIu32 " ", 00231 arm_uc_offset); 00232 00233 /* update remaining */ 00234 remaining = ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH - length; 00235 00236 /* check validity */ 00237 valid = (remaining > 0); 00238 } 00239 00240 /* add size parameter if requested */ 00241 if ((valid) && (parameters->size)) { 00242 if (arm_uc_buffer) { 00243 /* add parameter to command line */ 00244 length += snprintf(&command[length], 00245 remaining, 00246 "-s %" PRIu32 " ", 00247 arm_uc_buffer->size_max); 00248 00249 /* update remaining */ 00250 remaining = ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH - length; 00251 00252 /* check validity */ 00253 valid = (remaining > 0); 00254 } else { 00255 valid = false; 00256 } 00257 } 00258 } 00259 00260 return valid; 00261 } 00262 00263 arm_uc_error_t arm_uc_pal_linux_internal_read(const char *file_path, 00264 uint32_t offset, 00265 arm_uc_buffer_t *buffer) 00266 { 00267 /* default to failure result */ 00268 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00269 00270 if (file_path && buffer) { 00271 /* open file */ 00272 errno = 0; 00273 FILE *descriptor = fopen(file_path, "rb"); 00274 00275 /* continue if file is open */ 00276 if (descriptor != NULL) { 00277 /* set read position */ 00278 int status = fseeko(descriptor, offset, SEEK_SET); 00279 00280 /* continue if position is set */ 00281 if (status == 0) { 00282 /* read buffer */ 00283 errno = 0; 00284 size_t xfer_size = fread(buffer->ptr, 00285 sizeof(uint8_t), 00286 buffer->size, 00287 descriptor); 00288 00289 /* set buffer size if read succeeded */ 00290 status = ferror(descriptor); 00291 00292 if (status == 0) { 00293 buffer->size = xfer_size; 00294 00295 /* set successful result */ 00296 result.code = ERR_NONE; 00297 } else { 00298 /* set error code if read failed */ 00299 UC_PAAL_ERR_MSG("failed to read %s: %s", file_path, strerror(errno)); 00300 buffer->size = 0; 00301 } 00302 00303 /* close file after read */ 00304 fclose(descriptor); 00305 } else { 00306 UC_PAAL_ERR_MSG("failed to seek in: %s", file_path); 00307 } 00308 } else { 00309 UC_PAAL_ERR_MSG("failed to open %s: %s", file_path, strerror(errno)); 00310 } 00311 } 00312 00313 return result; 00314 } 00315 00316 arm_uc_error_t arm_uc_pal_linux_internal_read_header(uint32_t *location, 00317 arm_uc_firmware_details_t *details) 00318 { 00319 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00320 00321 if (details) { 00322 /* construct header file path */ 00323 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00324 00325 result = arm_uc_pal_linux_internal_file_path(file_path, 00326 ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH, 00327 ARM_UC_HEADER_FOLDER_PATH, 00328 "header", 00329 location); 00330 00331 /* file path is valid */ 00332 if (result.error == ERR_NONE) { 00333 /* allocate external header sized read buffer since it will be 00334 large enough to hold either an internal or external header. 00335 */ 00336 uint8_t read_buffer[ARM_UC_EXTERNAL_HEADER_SIZE_V2] = { 0 }; 00337 00338 arm_uc_buffer_t buffer = { 00339 .size_max = sizeof(read_buffer), 00340 .size = sizeof(read_buffer), 00341 .ptr = read_buffer 00342 }; 00343 00344 /* read metadata header */ 00345 result = arm_uc_pal_linux_internal_read(file_path, 0, &buffer); 00346 00347 /* check return code */ 00348 if (result.error == ERR_NONE) { 00349 UC_PAAL_TRACE("header bytes: %u", buffer.size); 00350 00351 /* read out header magic */ 00352 uint32_t headerMagic = arm_uc_parse_uint32(&read_buffer[0]); 00353 00354 /* read out header magic */ 00355 uint32_t headerVersion = arm_uc_parse_uint32(&read_buffer[4]); 00356 00357 /* choose version to decode */ 00358 if ((headerMagic == ARM_UC_INTERNAL_HEADER_MAGIC_V2) && 00359 (headerVersion == ARM_UC_INTERNAL_HEADER_VERSION_V2) && 00360 (buffer.size == ARM_UC_INTERNAL_HEADER_SIZE_V2)) { 00361 result = arm_uc_parse_internal_header_v2(read_buffer, details); 00362 } else if ((headerMagic == ARM_UC_EXTERNAL_HEADER_MAGIC_V2) && 00363 (headerVersion == ARM_UC_EXTERNAL_HEADER_VERSION_V2) && 00364 (buffer.size == ARM_UC_EXTERNAL_HEADER_SIZE_V2)) { 00365 result = arm_uc_parse_external_header_v2(read_buffer, details); 00366 } else { 00367 if (location) { 00368 UC_PAAL_ERR_MSG("invalid header in slot %" PRIu32, *location); 00369 } else { 00370 UC_PAAL_ERR_MSG("invalid header location"); 00371 } 00372 00373 /* invalid header format */ 00374 result.code = ERR_INVALID_PARAMETER; 00375 } 00376 } else { 00377 /* unsuccessful read */ 00378 if (location) { 00379 UC_PAAL_ERR_MSG("unable to read header in slot %" PRIX32, *location); 00380 } else { 00381 UC_PAAL_ERR_MSG("unable to read from unspecified header location"); 00382 } 00383 } 00384 } else { 00385 UC_PAAL_ERR_MSG("header file name and path too long"); 00386 } 00387 } 00388 00389 return result; 00390 } 00391 00392 arm_uc_error_t arm_uc_pal_linux_internal_read_installer(arm_uc_installer_details_t *details) 00393 { 00394 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00395 00396 if (details) { 00397 /* construct file path */ 00398 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00399 00400 result = arm_uc_pal_linux_internal_file_path(file_path, 00401 ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH, 00402 ARM_UC_INSTALLER_FOLDER_PATH, 00403 "installer", 00404 NULL); 00405 00406 /* file path is valid */ 00407 if (result.error == ERR_NONE) { 00408 uint8_t read_buffer[2 * sizeof(arm_uc_hash_t) + sizeof(uint32_t)] = { 0 }; 00409 00410 arm_uc_buffer_t buffer = { 00411 .size_max = sizeof(read_buffer), 00412 .size = 0, 00413 .ptr = read_buffer 00414 }; 00415 00416 /* read installer details */ 00417 result = arm_uc_pal_linux_internal_read(file_path, 0, &buffer); 00418 00419 UC_PAAL_TRACE("installer bytes: %u", buffer.size); 00420 00421 /* check return code */ 00422 if ((result.error == ERR_NONE) && 00423 (buffer.size == sizeof(read_buffer))) { 00424 memcpy(details->arm_hash, 00425 buffer.ptr, 00426 sizeof(arm_uc_hash_t)); 00427 00428 memcpy(details->oem_hash, 00429 &buffer.ptr[sizeof(arm_uc_hash_t)], 00430 sizeof(arm_uc_hash_t)); 00431 00432 details->layout = arm_uc_parse_uint32(&buffer.ptr[2 * sizeof(arm_uc_hash_t)]); 00433 } else { 00434 /* unsuccessful read */ 00435 UC_PAAL_ERR_MSG("unable to read installer details"); 00436 } 00437 } else { 00438 UC_PAAL_ERR_MSG("installer file name and path too long"); 00439 } 00440 } 00441 00442 return result; 00443 } 00444 00445 arm_uc_error_t arm_uc_pal_linux_internal_write_header(uint32_t *location, 00446 const arm_uc_firmware_details_t *details) 00447 { 00448 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00449 00450 if (details) { 00451 /* allocate external header sized buffer since it will be 00452 large enough to hold either an internal or external header. 00453 */ 00454 uint8_t temp_buffer[ARM_UC_EXTERNAL_HEADER_SIZE_V2] = { 0 }; 00455 00456 arm_uc_buffer_t buffer = { 00457 .size_max = sizeof(temp_buffer), 00458 .size = 0, 00459 .ptr = temp_buffer 00460 }; 00461 00462 /* encode firmware details in buffer */ 00463 #if ARM_UC_USE_EXTERNAL_HEADER 00464 result = arm_uc_create_external_header_v2(details, &buffer); 00465 #else 00466 result = arm_uc_create_internal_header_v2(details, &buffer); 00467 #endif 00468 00469 /* write header file */ 00470 if (result.error == ERR_NONE) { 00471 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00472 00473 /* construct header file path */ 00474 result = arm_uc_pal_linux_internal_file_path(file_path, 00475 ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH, 00476 ARM_UC_HEADER_FOLDER_PATH, 00477 "header", 00478 location); 00479 00480 if (result.error == ERR_NONE) { 00481 /* inverse result */ 00482 result.code = ERR_INVALID_PARAMETER; 00483 00484 /* open file and get file handler */ 00485 errno = 0; 00486 FILE *file = fopen(file_path, "wb"); 00487 00488 if (file != NULL) { 00489 /* write buffer to file */ 00490 size_t xfer_size = fwrite(buffer.ptr, 00491 sizeof(uint8_t), 00492 buffer.size, 00493 file); 00494 00495 UC_PAAL_TRACE("written: %" PRIu64, xfer_size); 00496 00497 /* close file after write */ 00498 int status = fclose(file); 00499 00500 if ((xfer_size == buffer.size) && 00501 (status != EOF)) { 00502 /* set return code if write was successful */ 00503 result.code = ERR_NONE; 00504 } else { 00505 UC_PAAL_ERR_MSG("failed to write header"); 00506 } 00507 } else { 00508 UC_PAAL_ERR_MSG("file open failed: %s", strerror(errno)); 00509 } 00510 } else { 00511 UC_PAAL_ERR_MSG("header file name and path too long"); 00512 } 00513 } else { 00514 UC_PAAL_ERR_MSG("header too large for buffer"); 00515 } 00516 00517 } 00518 00519 return result; 00520 } 00521 00522 arm_uc_error_t arm_uc_pal_linux_internal_write_manifest(uint32_t *location, 00523 const arm_uc_buffer_t *manifest) 00524 { 00525 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00526 00527 if (manifest) { 00528 /* write header file */ 00529 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00530 00531 /* construct header file path */ 00532 result = arm_uc_pal_linux_internal_file_path(file_path, 00533 ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH, 00534 ARM_UC_HEADER_FOLDER_PATH, 00535 "manifest", 00536 location); 00537 00538 if (result.error == ERR_NONE) { 00539 /* inverse result */ 00540 result.code = ERR_INVALID_PARAMETER; 00541 00542 /* open file and get file handler */ 00543 errno = 0; 00544 FILE *file = fopen(file_path, "wb"); 00545 00546 if (file != NULL) { 00547 /* write manifest to file */ 00548 size_t xfer_size = fwrite(manifest->ptr, 00549 sizeof(uint8_t), 00550 manifest->size, 00551 file); 00552 00553 UC_PAAL_TRACE("written: %" PRIu64, xfer_size); 00554 00555 /* close file after write */ 00556 int status = fclose(file); 00557 00558 if ((xfer_size == manifest->size) && (status != EOF)) { 00559 /* set return code if write was successful */ 00560 result.code = ERR_NONE; 00561 } else { 00562 UC_PAAL_ERR_MSG("failed to write manifest"); 00563 } 00564 } else { 00565 UC_PAAL_ERR_MSG("file open failed: %s", strerror(errno)); 00566 } 00567 } else { 00568 UC_PAAL_ERR_MSG("manifest file name and path too long"); 00569 } 00570 } 00571 00572 return result; 00573 } 00574 00575 /** 00576 * @brief Function to run script in a worker thread before file operations. 00577 * 00578 * @param params Pointer to arm_ucp_worker_t struct. 00579 */ 00580 void *arm_uc_pal_linux_extended_pre_worker(void *params) 00581 { 00582 /* default to failure */ 00583 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00584 00585 /* get parameters */ 00586 arm_ucp_worker_t *parameters = (arm_ucp_worker_t *) params; 00587 00588 /* file path to script result */ 00589 char file_path[ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH] = { 0 }; 00590 00591 /* construct script command */ 00592 char command[ARM_UC_MAXIMUM_COMMAND_LENGTH] = { 0 }; 00593 00594 int valid = arm_uc_pal_linux_internal_command(parameters, 00595 command, 00596 ARM_UC_MAXIMUM_COMMAND_LENGTH); 00597 00598 /* command is valid */ 00599 if (valid) { 00600 UC_PAAL_TRACE("Extended pre-script command: %s", command); 00601 00602 /* execute script */ 00603 errno = 0; 00604 FILE *pipe = popen(command, "r"); 00605 00606 if (pipe) { 00607 /* read pipe */ 00608 size_t xfer_size = fread(file_path, 00609 sizeof(uint8_t), 00610 ARM_UC_MAXIMUM_FILE_AND_PATH_LENGTH, 00611 pipe); 00612 00613 /* trim non-printable characters */ 00614 for (size_t index = 0; index < xfer_size; index++) { 00615 /* space is the first printable character */ 00616 if (file_path[index] < ' ') { 00617 /* truncate string */ 00618 file_path[index] = '\0'; 00619 break; 00620 } 00621 } 00622 00623 int status = 0; 00624 00625 /* check fread error status */ 00626 status = ferror(pipe); 00627 if (status == 0) { 00628 /* Wait for child thread termination and check exit status */ 00629 status = pclose(pipe); 00630 00631 /* make sure child thread terminated correctly and scirpt exit status is 0 */ 00632 if (status != -1 && WIFEXITED(status)) { 00633 if (WEXITSTATUS(status) == 0) { 00634 /* switch from boolean result to arm_uc_error_t */ 00635 result.code = ERR_NONE; 00636 } else { 00637 UC_PAAL_ERR_MSG("Script exited with non-zero status %" PRId32, status); 00638 } 00639 } else { 00640 UC_PAAL_ERR_MSG("pipe terminated incorrectly %" PRId32, status); 00641 } 00642 } else { 00643 UC_PAAL_ERR_MSG("failed to read pipe: %" PRId32, status); 00644 } 00645 } else { 00646 UC_PAAL_ERR_MSG("failed to execute script: %" PRId32, errno); 00647 } 00648 } 00649 00650 /* file path is valid */ 00651 if (result.error == ERR_NONE) { 00652 /* invert status */ 00653 result.code = ERR_INVALID_PARAMETER; 00654 00655 extern arm_ucp_worker_config_t arm_uc_worker_parameters; 00656 00657 /* perform read operation */ 00658 if ((parameters == arm_uc_worker_parameters.read) && 00659 (arm_uc_buffer != NULL)) { 00660 result = arm_uc_pal_linux_internal_read(file_path, 0, arm_uc_buffer); 00661 00662 /* reset global buffer */ 00663 arm_uc_buffer = NULL; 00664 } 00665 00666 /* read details */ 00667 if ((parameters == arm_uc_worker_parameters.details) && 00668 (arm_uc_details != NULL)) { 00669 result = arm_uc_pal_linux_internal_read_header(arm_uc_location, 00670 arm_uc_details); 00671 00672 /* reset global details pointer */ 00673 arm_uc_details = NULL; 00674 } 00675 00676 /* read active details */ 00677 if ((parameters == arm_uc_worker_parameters.active_details) && 00678 (arm_uc_details != NULL)) { 00679 result = arm_uc_pal_linux_internal_read_header(NULL, 00680 arm_uc_details); 00681 00682 /* reset global details pointer */ 00683 arm_uc_details = NULL; 00684 } 00685 00686 /* read installer details */ 00687 if ((parameters == arm_uc_worker_parameters.installer) && 00688 (arm_uc_installer != NULL)) { 00689 result = arm_uc_pal_linux_internal_read_installer(arm_uc_installer); 00690 00691 /* reset global installer pointer */ 00692 arm_uc_installer = NULL; 00693 } 00694 } 00695 00696 if (result.error == ERR_NONE) { 00697 UC_PAAL_TRACE("pre-script complete"); 00698 00699 arm_uc_pal_linux_signal_callback(parameters->success_event, true); 00700 } else { 00701 UC_PAAL_ERR_MSG("pre-script failed"); 00702 00703 arm_uc_pal_linux_signal_callback(parameters->failure_event, true); 00704 } 00705 return NULL; 00706 } 00707 00708 /** 00709 * @brief Function to run script in a worker thread before file operations. 00710 * 00711 * @param params Pointer to arm_ucp_worker_t struct. 00712 */ 00713 void *arm_uc_pal_linux_extended_post_worker(void *params) 00714 { 00715 /* get parameters */ 00716 arm_ucp_worker_t *parameters = (arm_ucp_worker_t *) params; 00717 00718 /* construct script command */ 00719 char command[ARM_UC_MAXIMUM_COMMAND_LENGTH] = { 0 }; 00720 00721 int error = 0; 00722 int32_t event = 0; 00723 int valid = arm_uc_pal_linux_internal_command(parameters, 00724 command, 00725 ARM_UC_MAXIMUM_COMMAND_LENGTH); 00726 00727 if (valid) { 00728 UC_PAAL_TRACE("Extended post-script command: %s", command); 00729 00730 /* execute script command */ 00731 error = system(command); 00732 error = WEXITSTATUS(error); 00733 00734 /* update valid flag */ 00735 valid = (error == 0); 00736 } 00737 00738 if (valid) { 00739 UC_PAAL_TRACE("post-script completed"); 00740 00741 event = parameters->success_event; 00742 00743 /* execute the post runner if it exists and the script succeeded */ 00744 if (parameters->post_runner) { 00745 event = parameters->post_runner(); 00746 UC_PAAL_TRACE("post runner returned event %" PRId32, event); 00747 } 00748 } else { 00749 UC_PAAL_ERR_MSG("post-script failed: %" PRId32, error); 00750 00751 event = parameters->failure_event; 00752 } 00753 00754 arm_uc_pal_linux_signal_callback(event, true); 00755 00756 return NULL; 00757 } 00758 00759 #endif /* TARGET_IS_PC_LINUX */ 00760 #endif /* ARM_UC_FEATURE_PAL_LINUX */
Generated on Tue Jul 12 2022 20:20:57 by
