| /******************************************************************************* | |
| * Copyright (c) 2017 fortiss GmbH | |
| * This program and the accompanying materials are made available under the | |
| * terms of the Eclipse Public License 2.0 which is available at | |
| * http://www.eclipse.org/legal/epl-2.0. | |
| * | |
| * SPDX-License-Identifier: EPL-2.0 | |
| * | |
| * Contributors: | |
| * Monika Wenger | |
| * - initial API and implementation and/or initial documentation | |
| *******************************************************************************/ | |
| #include "ForteBootFileLoader.h" | |
| #include "../../arch/devlog.h" | |
| #include "../../../src/core/datatypes/forte_string.h" | |
| #include "IBootFileCallback.h" | |
| #include <mgmcmd.h> | |
| #include <mgmcmdstruct.h> | |
| #include "../../core/device.h" | |
| char* gCommandLineBootFile = 0; | |
| ForteBootFileLoader::ForteBootFileLoader(IBootFileCallback &paCallback) : mBootfile(0), mCallback(paCallback){ | |
| openBootFile(); | |
| } | |
| ForteBootFileLoader::~ForteBootFileLoader() { | |
| if(0 != mBootfile){ | |
| DEVLOG_INFO("Closing bootfile\n"); | |
| fclose(mBootfile); | |
| } | |
| } | |
| bool ForteBootFileLoader::openBootFile() { | |
| bool retVal = false; | |
| CIEC_STRING bootFileName; | |
| if(gCommandLineBootFile) { | |
| DEVLOG_INFO("Using provided bootfile location set in the command line: %s\n", gCommandLineBootFile); | |
| bootFileName = gCommandLineBootFile; | |
| } else { | |
| // select provided or default boot file name | |
| char * envBootFileName = getenv("FORTE_BOOT_FILE"); | |
| if(0 != envBootFileName) { | |
| DEVLOG_INFO("Using provided bootfile location from environment variable: %s\n", envBootFileName); | |
| bootFileName = envBootFileName; | |
| } else { | |
| DEVLOG_INFO("Using provided bootfile location set in CMake: %s\n", FORTE_BOOT_FILE_LOCATION); | |
| bootFileName = FORTE_BOOT_FILE_LOCATION; | |
| } | |
| } | |
| // check if we finally have a boot file name | |
| if("" == bootFileName){ | |
| DEVLOG_INFO("No bootfile specified and no default bootfile configured during build\n"); | |
| }else{ | |
| mBootfile = fopen(bootFileName.getValue(), "r"); | |
| if(0 != mBootfile){ | |
| DEVLOG_INFO("Boot file %s opened\n", bootFileName.getValue()); | |
| retVal = true; | |
| } | |
| else{ | |
| if(0 != getenv("FORTE_BOOT_FILE_FAIL_MISSING")){ | |
| DEVLOG_ERROR("Boot file %s could not be opened and FORTE_BOOT_FILE_FAIL_MISSING is set. Failing...\n", bootFileName.getValue()); | |
| exit(2); | |
| } | |
| else{ | |
| DEVLOG_INFO("Boot file %s could not be opened. Skipping...\n", bootFileName.getValue()); | |
| } | |
| } | |
| } | |
| return retVal; | |
| } | |
| LoadBootResult ForteBootFileLoader::loadBootFile(){ | |
| LoadBootResult eResp = FILE_NOT_OPENED; | |
| if(0 != mBootfile){ | |
| //we could open the file try to load it | |
| int nLineCount = 1; | |
| eResp = LOAD_RESULT_OK; | |
| CIEC_STRING line; | |
| while(readLine(line) && LOAD_RESULT_OK == eResp) { | |
| char *cmdStart = strchr(line.getValue(), ';'); | |
| if(0 == cmdStart){ | |
| eResp = MISSING_COLON; | |
| DEVLOG_ERROR("Boot file line does not contain separating ';'. Line: %d\n", nLineCount); | |
| } else { | |
| *cmdStart = '\0'; | |
| cmdStart++; | |
| if(!mCallback.executeCommand(line.getValue(), cmdStart)) { | |
| //command was not successful | |
| DEVLOG_ERROR("Boot file command could not be executed. Line: %d: %s\n", nLineCount, cmdStart); | |
| eResp = EXTERNAL_ERROR; | |
| } else { | |
| nLineCount++; | |
| } | |
| } | |
| } | |
| }else{ | |
| DEVLOG_ERROR("Loading cannot proceed because the boot file is no opened\n"); | |
| } | |
| return eResp; | |
| } | |
| bool ForteBootFileLoader::readLine(CIEC_STRING &line){ | |
| const unsigned int size = 100; | |
| line.clear(); | |
| char acLineBuf[size]; | |
| do{ | |
| if(0 != fgets(acLineBuf, size, mBootfile)){ | |
| line.append(acLineBuf); | |
| }else{ | |
| return 0 != line.length(); | |
| } | |
| }while(!hasCommandEnded(line)); | |
| return true; | |
| } | |
| bool ForteBootFileLoader::hasCommandEnded(const CIEC_STRING &line) const{ | |
| return (0 == strcmp(line.getValue() + line.length() - 11, "</Request>\n") || 0 == strcmp(line.getValue() + line.length() - 3, "/>\n")); | |
| } |