1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "chre/platform/slpi/nanoapp_load_manager.h" 18 19 namespace chre { 20 21 bool NanoappLoadManager::prepareForLoad(uint16_t hostClientId, 22 uint32_t transactionId, uint64_t appId, 23 uint32_t appVersion, 24 size_t totalBinaryLen) { 25 if (hasPendingLoadTransaction()) { 26 LOGW( 27 "Pending load transaction already exists. Overriding previous" 28 " transaction."); 29 } 30 mCurrentLoadInfo.hostClientId = hostClientId; 31 mCurrentLoadInfo.transactionId = transactionId; 32 mCurrentLoadInfo.nextFragmentId = 1; 33 mNanoapp = MakeUnique<Nanoapp>(); 34 35 bool success = false; 36 if (mNanoapp.isNull()) { 37 LOG_OOM(); 38 } else { 39 success = mNanoapp->reserveBuffer(appId, appVersion, totalBinaryLen); 40 } 41 42 if (!success) { 43 markFailure(); 44 } 45 46 return success; 47 } 48 49 bool NanoappLoadManager::copyNanoappFragment(uint16_t hostClientId, 50 uint32_t transactionId, 51 uint32_t fragmentId, 52 const void *buffer, 53 size_t bufferLen) { 54 bool success = false; 55 if (validateFragment(hostClientId, transactionId, fragmentId)) { 56 success = mNanoapp->copyNanoappFragment(buffer, bufferLen); 57 if (success) { 58 mCurrentLoadInfo.nextFragmentId++; 59 } else { 60 markFailure(); 61 } 62 } 63 64 return success; 65 } 66 67 bool NanoappLoadManager::validateFragment(uint16_t hostClientId, 68 uint32_t transactionId, 69 uint32_t fragmentId) const { 70 bool valid = false; 71 if (!hasPendingLoadTransaction()) { 72 LOGE("No pending load transaction exists"); 73 } else { 74 const FragmentedLoadInfo &info = mCurrentLoadInfo; 75 valid = (info.hostClientId == hostClientId && 76 info.transactionId == transactionId && 77 info.nextFragmentId == fragmentId); 78 if (!valid) { 79 LOGE("Unexpected load fragment: expected host %" PRIu16 80 "transaction %" PRIu32 " fragment %" PRIu32 81 ", received host %" PRIu16 " transaction %" PRIu32 82 " fragment %" PRIu32, 83 info.hostClientId, info.transactionId, info.nextFragmentId, 84 hostClientId, transactionId, fragmentId); 85 } 86 } 87 88 return valid; 89 } 90 91 } // namespace chre 92