nanoapp_load_manager.cc revision 9856abf6175382475614819c1f4be93b9340e8c5
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
19namespace chre {
20
21bool NanoappLoadManager::prepareForLoad(
22    uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
23    uint32_t appVersion, size_t totalBinaryLen) {
24  if (hasPendingLoadTransaction()) {
25    LOGW("Pending load transaction already exists. Overriding previous"
26         " transaction.");
27  }
28  mCurrentLoadInfo.hostClientId = hostClientId;
29  mCurrentLoadInfo.transactionId = transactionId;
30  mCurrentLoadInfo.nextFragmentId = 1;
31  mNanoapp = MakeUnique<Nanoapp>();
32
33  bool success = false;
34  if (mNanoapp.isNull()) {
35    LOG_OOM();
36  } else if (!mNanoapp->reserveBuffer(appId, appVersion, totalBinaryLen)) {
37    LOGE("Failed to reserve %zu bytes for nanoapp 0x%016" PRIx64,
38         totalBinaryLen, appId);
39  } else {
40    success = true;
41  }
42
43  if (!success) {
44    markFailure();
45  }
46
47  return success;
48}
49
50bool NanoappLoadManager::copyNanoappFragment(
51    uint16_t hostClientId, uint32_t transactionId, uint32_t fragmentId,
52    const void *buffer, size_t bufferLen) {
53  bool success = false;
54  if (validateFragment(hostClientId, transactionId, fragmentId)) {
55    success = mNanoapp->copyNanoappFragment(buffer, bufferLen);
56    if (success) {
57      mCurrentLoadInfo.nextFragmentId++;
58    } else {
59      markFailure();
60    }
61  }
62
63  return success;
64}
65
66bool NanoappLoadManager::validateFragment(
67    uint16_t hostClientId, uint32_t transactionId, uint32_t fragmentId) const {
68  bool valid = false;
69  if (!hasPendingLoadTransaction()) {
70    LOGE("No pending load transaction exists");
71  } else {
72    const FragmentedLoadInfo& info = mCurrentLoadInfo;
73    valid = (info.hostClientId == hostClientId
74        && info.transactionId == transactionId
75        && info.nextFragmentId == fragmentId);
76    if (!valid) {
77      LOGE("Unexpected load fragment: expected host %" PRIu16
78          "transaction %" PRIu32 " fragment %" PRIu32 ", received host %"
79           PRIu16 " transaction %" PRIu32 " fragment %" PRIu32,
80           info.hostClientId, info.transactionId, info.nextFragmentId,
81           hostClientId, transactionId, fragmentId);
82    }
83  }
84
85  return valid;
86}
87
88}  // namespace chre
89