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 
prepareForLoad(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,uint32_t appVersion,size_t totalBinaryLen)21 bool 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 {
37     success = mNanoapp->reserveBuffer(appId, appVersion, totalBinaryLen);
38   }
39 
40   if (!success) {
41     markFailure();
42   }
43 
44   return success;
45 }
46 
copyNanoappFragment(uint16_t hostClientId,uint32_t transactionId,uint32_t fragmentId,const void * buffer,size_t bufferLen)47 bool NanoappLoadManager::copyNanoappFragment(
48     uint16_t hostClientId, uint32_t transactionId, uint32_t fragmentId,
49     const void *buffer, size_t bufferLen) {
50   bool success = false;
51   if (validateFragment(hostClientId, transactionId, fragmentId)) {
52     success = mNanoapp->copyNanoappFragment(buffer, bufferLen);
53     if (success) {
54       mCurrentLoadInfo.nextFragmentId++;
55     } else {
56       markFailure();
57     }
58   }
59 
60   return success;
61 }
62 
validateFragment(uint16_t hostClientId,uint32_t transactionId,uint32_t fragmentId) const63 bool NanoappLoadManager::validateFragment(
64     uint16_t hostClientId, uint32_t transactionId, uint32_t fragmentId) const {
65   bool valid = false;
66   if (!hasPendingLoadTransaction()) {
67     LOGE("No pending load transaction exists");
68   } else {
69     const FragmentedLoadInfo& info = mCurrentLoadInfo;
70     valid = (info.hostClientId == hostClientId
71         && info.transactionId == transactionId
72         && info.nextFragmentId == fragmentId);
73     if (!valid) {
74       LOGE("Unexpected load fragment: expected host %" PRIu16
75           "transaction %" PRIu32 " fragment %" PRIu32 ", received host %"
76            PRIu16 " transaction %" PRIu32 " fragment %" PRIu32,
77            info.hostClientId, info.transactionId, info.nextFragmentId,
78            hostClientId, transactionId, fragmentId);
79     }
80   }
81 
82   return valid;
83 }
84 
85 }  // namespace chre
86