summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-04-22 07:24:54 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-04-22 07:24:54 +0000
commit8fc691d6601ab14a6d64caa42c7f216e088bd0eb (patch)
tree619891219e39f328dee845a136fcf9d20fa8caed
parentb46c2e2a233028891aa343e162b715c7b06ab501 (diff)
parent227914e6d74b7d2ae1738dfd372e54944c64f84f (diff)
downloadcontexthub-8fc691d6601ab14a6d64caa42c7f216e088bd0eb.tar.gz
Snap for 4736748 from 227914e6d74b7d2ae1738dfd372e54944c64f84f to pi-release
Change-Id: I92b4eb2db62d2b657c0ec4739870ef813bcc17ec
-rw-r--r--Android.bp4
-rw-r--r--contexthubhal/Android.bp73
-rw-r--r--contexthubhal/NanohubHidlAdapter.cpp61
-rw-r--r--contexthubhal/NanohubHidlAdapter.h3
-rw-r--r--contexthubhal/legacyhal.cpp2
-rw-r--r--contexthubhal/nanohubhal.cpp9
-rw-r--r--contexthubhal/nanohubhal.h44
-rw-r--r--contexthubhal/system_comms.cpp1395
-rw-r--r--contexthubhal/system_comms.h264
-rw-r--r--util/common/Android.bp37
-rw-r--r--util/common/Android.mk47
11 files changed, 1492 insertions, 447 deletions
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 6d5a864d..00000000
--- a/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-subdirs = [
- "contexthubhal",
- "lib",
-]
diff --git a/contexthubhal/Android.bp b/contexthubhal/Android.bp
index 93c8dcb2..130f7de0 100644
--- a/contexthubhal/Android.bp
+++ b/contexthubhal/Android.bp
@@ -12,80 +12,77 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_library {
- name: "context_hub.default",
+cc_defaults {
+ name: "contexthub_libs_default",
relative_install_path: "hw",
srcs: [
"nanohubhal.cpp",
- "system_comms.cpp",
"nanohubhal_default.cpp",
- "legacyhal.cpp",
+ "system_comms.cpp",
],
cflags: ["-Wall", "-Werror", "-Wextra"],
shared_libs: [
"liblog",
"libcutils",
+ "libutils",
+ "libstagefright_foundation",
+ ],
+ static_libs: [
+ "libjsoncpp",
+ "libhubutilcommon",
],
header_libs: [
"libnanohub_common_headers",
"libhardware_headers",
"libutils_headers",
],
- proprietary: true,
+ vendor: true,
}
-cc_library_shared {
- name: "android.hardware.contexthub@1.0-impl.nanohub",
- proprietary: true,
- relative_install_path: "hw",
+cc_defaults {
+ name: "contexthub_hidl_libs_default",
srcs: [
"NanohubHidlAdapter.cpp",
- "nanohubhal.cpp",
- "nanohubhal_default.cpp",
- "system_comms.cpp",
],
- cflags: ["-Wall", "-Werror", "-Wextra"],
shared_libs: [
- "liblog",
- "libbase",
- "libcutils",
- "libutils",
"libhidlbase",
"libhidltransport",
"android.hardware.contexthub@1.0",
],
- header_libs: [
- "libnanohub_common_headers",
- "libhardware_headers",
- "libutils_headers",
+}
+
+cc_library {
+ name: "context_hub.default",
+ srcs: [
+ "legacyhal.cpp",
+ ],
+ defaults: [
+ "contexthub_libs_default",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.contexthub@1.0-impl.nanohub",
+ shared_libs: [
+ "libbase",
+ ],
+ defaults: [
+ "contexthub_libs_default",
+ "contexthub_hidl_libs_default",
],
}
cc_binary {
name: "android.hardware.contexthub@1.0-service.nanohub",
- relative_install_path: "hw",
init_rc: ["android.hardware.contexthub@1.0-service.nanohub.rc"],
srcs: [
"service.cpp",
- "NanohubHidlAdapter.cpp",
- "nanohubhal.cpp",
- "nanohubhal_default.cpp",
- "system_comms.cpp",
],
- cflags: ["-Wall", "-Werror"],
shared_libs: [
- "libhidlbase",
- "libhidltransport",
"libhwbinder",
- "liblog",
- "libutils",
- "libcutils",
- "android.hardware.contexthub@1.0",
],
- header_libs: [
- "libnanohub_common_headers",
- "libhardware_headers",
- "libutils_headers",
+ defaults: [
+ "contexthub_libs_default",
+ "contexthub_hidl_libs_default",
],
- proprietary: true,
}
diff --git a/contexthubhal/NanohubHidlAdapter.cpp b/contexthubhal/NanohubHidlAdapter.cpp
index fcfb3711..9efca2ad 100644
--- a/contexthubhal/NanohubHidlAdapter.cpp
+++ b/contexthubhal/NanohubHidlAdapter.cpp
@@ -28,6 +28,7 @@
#include <log/log.h>
#include <utils/String8.h>
+#include <sys/stat.h>
#include <android/hardware/contexthub/1.0/IContexthub.h>
#include <hardware/context_hub.h>
@@ -151,7 +152,7 @@ Return<Result> Contexthub::sendMessageToHub(uint32_t hubId,
txMsg.message_len,
txMsg.app_name.id);
- if(NanoHub::sendToNanohub(hubId, &txMsg, msg.hostEndPoint) != 0) {
+ if(NanoHub::sendToNanohub(hubId, &txMsg, 0, msg.hostEndPoint) != 0) {
return Result::TRANSACTION_FAILED;
}
@@ -221,7 +222,8 @@ static bool isValidOsStatus(const uint8_t *msg,
int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
uint32_t msgType,
const uint8_t *msg,
- int msgLen) {
+ int msgLen,
+ uint32_t transactionId) {
int retVal = -1;
@@ -242,7 +244,7 @@ int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
mIsTransactionPending = false;
if (cb != nullptr) {
- cb->handleTxnResult(mTransactionId, result);
+ cb->handleTxnResult(transactionId, result);
}
retVal = 0;
break;
@@ -331,7 +333,8 @@ int Contexthub::contextHubCb(uint32_t hubId,
obj->handleOsMessage(cb,
rxMsg.message_type,
static_cast<const uint8_t *>(rxMsg.message),
- rxMsg.message_len);
+ rxMsg.message_len,
+ rxMsg.message_transaction_id);
} else {
ContextHubMsg msg;
@@ -370,10 +373,10 @@ Return<Result> Contexthub::unloadNanoApp(uint32_t hubId,
if(NanoHub::sendToNanohub(hubId,
&msg,
+ transactionId,
static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
return Result::TRANSACTION_FAILED;
} else {
- mTransactionId = transactionId;
mIsTransactionPending = true;
return Result::OK;
}
@@ -418,10 +421,10 @@ Return<Result> Contexthub::loadNanoApp(uint32_t hubId,
if(NanoHub::sendToNanohub(hubId,
&hubMsg,
+ transactionId,
static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
return Result::TRANSACTION_FAILED;
} else {
- mTransactionId = transactionId;
mIsTransactionPending = true;
return Result::OK;
}
@@ -449,10 +452,10 @@ Return<Result> Contexthub::enableNanoApp(uint32_t hubId,
if(NanoHub::sendToNanohub(hubId,
&msg,
+ transactionId,
static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
return Result::TRANSACTION_FAILED;
} else {
- mTransactionId = transactionId;
mIsTransactionPending = true;
return Result::OK;
}
@@ -480,10 +483,10 @@ Return<Result> Contexthub::disableNanoApp(uint32_t hubId,
if(NanoHub::sendToNanohub(hubId,
&msg,
+ transactionId,
static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
return Result::TRANSACTION_FAILED;
} else {
- mTransactionId = transactionId;
mIsTransactionPending = true;
return Result::OK;
}
@@ -505,6 +508,7 @@ Return<Result> Contexthub::queryApps(uint32_t hubId) {
if(NanoHub::sendToNanohub(hubId,
&msg,
+ 0,
static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
ALOGW("Query Apps sendMessage failed");
return Result::TRANSACTION_FAILED;
@@ -517,6 +521,32 @@ IContexthub *HIDL_FETCH_IContexthub(const char *) {
return new Contexthub();
}
+static bool readApp(const char *file, NanoAppBinary *appBinary)
+{
+ bool success = false;
+ int fd = open(file, O_RDONLY);
+
+ if (fd >= 0) {
+ struct stat sb;
+ if (fstat(fd, &sb) == 0) {
+ void *buf = malloc(sb.st_size);
+ if (buf != nullptr && read(fd, buf, sb.st_size) == sb.st_size) {
+ success = true;
+ const struct nano_app_binary_t *header = static_cast<const struct nano_app_binary_t *>(buf);
+ appBinary->appId = header->app_id.id;
+ appBinary->appVersion = header->app_version;
+ appBinary->flags = header->flags;
+ appBinary->targetChreApiMajorVersion = header->target_chre_api_major_version;
+ appBinary->targetChreApiMinorVersion = header->target_chre_api_minor_version;
+ appBinary->customBinary = std::vector<uint8_t>(static_cast<const uint8_t *>(buf) + sizeof(struct nano_app_binary_t), static_cast<const uint8_t *>(buf) + sb.st_size);
+ }
+ free(buf);
+ }
+ close(fd);
+ }
+ return success;
+}
+
Return<void> Contexthub::debug(const hidl_handle& hh_fd,
const hidl_vec<hidl_string>& hh_data) {
if (hh_fd == nullptr || hh_fd->numFds < 1) {
@@ -528,9 +558,24 @@ Return<void> Contexthub::debug(const hidl_handle& hh_fd,
if (hh_data.size() == 0) {
result.appendFormat("debug: %d\n", NanoHub::getDebugFlags());
+ std::string appInfo;
+ NanoHub::dumpAppInfo(appInfo);
+ result.append(appInfo.c_str());
} else if (hh_data.size() == 1) {
NanoHub::setDebugFlags(atoi(hh_data[0].c_str()));
result.appendFormat("debug: %d\n", NanoHub::getDebugFlags());
+ } else if (hh_data.size() == 2) {
+ if (strncmp(hh_data[0].c_str(), "load", 4) == 0) {
+ NanoAppBinary appBinary;
+ if (readApp(hh_data[1].c_str(), &appBinary))
+ loadNanoApp(0, appBinary, 0);
+ } else if (strncmp(hh_data[0].c_str(), "unload", 6) == 0) {
+ unloadNanoApp(0, strtoul(hh_data[1].c_str(), NULL, 16), 0);
+ } else if (strncmp(hh_data[0].c_str(), "enable", 6) == 0) {
+ enableNanoApp(0, strtoul(hh_data[1].c_str(), NULL, 16), 0);
+ } else if (strncmp(hh_data[0].c_str(), "disable", 7) == 0) {
+ disableNanoApp(0, strtoul(hh_data[1].c_str(), NULL, 16), 0);
+ }
} else {
result.appendFormat("unknown debug options");
}
diff --git a/contexthubhal/NanohubHidlAdapter.h b/contexthubhal/NanohubHidlAdapter.h
index b8928e8c..79d6242f 100644
--- a/contexthubhal/NanohubHidlAdapter.h
+++ b/contexthubhal/NanohubHidlAdapter.h
@@ -106,7 +106,8 @@ private:
int handleOsMessage(sp<IContexthubCallback> cb,
uint32_t msgType,
const uint8_t *msg,
- int msgLen);
+ int msgLen,
+ uint32_t transactionId);
// Handle the case where the callback registered for the given hub ID dies
void handleServiceDeath(uint32_t hubId);
diff --git a/contexthubhal/legacyhal.cpp b/contexthubhal/legacyhal.cpp
index ce2707ab..80ceedb8 100644
--- a/contexthubhal/legacyhal.cpp
+++ b/contexthubhal/legacyhal.cpp
@@ -37,7 +37,7 @@ static int legacy_subscribe_messages(uint32_t hub_id, context_hub_callback *cbk,
static int legacy_send_message(uint32_t hub_id, const hub_message_t *msg)
{
- return NanoHub::sendToNanohub(hub_id, msg, ENDPOINT_UNSPECIFIED);
+ return NanoHub::sendToNanohub(hub_id, msg, 0, ENDPOINT_UNSPECIFIED);
}
static int legacy_get_hubs(context_hub_module_t*, const context_hub_t ** list)
diff --git a/contexthubhal/nanohubhal.cpp b/contexthubhal/nanohubhal.cpp
index 46ce1e67..2f750a64 100644
--- a/contexthubhal/nanohubhal.cpp
+++ b/contexthubhal/nanohubhal.cpp
@@ -192,6 +192,11 @@ void NanoHub::doSendToApp(HubMessage &&msg)
mAppTxCond.notify_all();
}
+void NanoHub::doDumpAppInfo(std::string &result)
+{
+ SystemComm::dumpAppInfo(result);
+}
+
void* NanoHub::runAppTx()
{
std::unique_lock<std::mutex> lk(mAppTxLock);
@@ -400,7 +405,7 @@ int NanoHub::doSubscribeMessages(uint32_t hub_id, Contexthub_callback *cbk, void
return ret;
}
-int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint16_t endpoint)
+int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint32_t transaction_id, uint16_t endpoint)
{
if (hub_id) {
return -ENODEV;
@@ -421,7 +426,7 @@ int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint16_t
if (messageTracingEnabled()) {
dumpBuffer("APP -> HAL", msg->app_name, msg->message_type, 0, msg->message, msg->message_len);
}
- ret = SystemComm::handleTx(msg);
+ ret = SystemComm::handleTx(msg, transaction_id);
} else if (msg->message_len > MAX_RX_PACKET) {
ALOGW("not sending invalid message 2");
ret = -EINVAL;
diff --git a/contexthubhal/nanohubhal.h b/contexthubhal/nanohubhal.h
index 1acb266a..b9cc172c 100644
--- a/contexthubhal/nanohubhal.h
+++ b/contexthubhal/nanohubhal.h
@@ -27,6 +27,7 @@
//as per protocol
#define MAX_RX_PACKET 128
+#define MAX_TX_PACKET 128
#define APP_FROM_HOST_EVENT_ID 0x000000F8
#define APP_FROM_HOST_CHRE_EVENT_ID 0x000000F9
@@ -57,15 +58,18 @@ union nano_message {
class HubMessage : public hub_message_t {
std::unique_ptr<uint8_t> data_;
public:
+ uint32_t message_transaction_id;
uint16_t message_endpoint;
HubMessage(const HubMessage &other) = delete;
HubMessage &operator = (const HubMessage &other) = delete;
- HubMessage(const hub_app_name_t *name, uint32_t typ, uint16_t endpoint, const void *data, uint32_t len) {
+ HubMessage(const hub_app_name_t *name, uint32_t typ, uint32_t transaction_id,
+ uint16_t endpoint, const void *data, uint32_t len) {
app_name = *name;
message_type = typ;
message_len = len;
message = data;
+ message_transaction_id = transaction_id;
message_endpoint = endpoint;
if (len > 0 && data != nullptr) {
data_ = std::unique_ptr<uint8_t>(new uint8_t[len]);
@@ -74,12 +78,30 @@ public:
}
}
+ HubMessage(const hub_app_name_t *name, uint32_t typ, uint16_t endpoint, const void *data,
+ uint32_t len) : HubMessage(name, typ, 0, endpoint, data, len) { }
+
+ HubMessage(const hub_message_t *msg, uint32_t transaction_id, uint16_t endpoint) {
+ app_name = msg->app_name;
+ message_type = msg->message_type;
+ message_len = msg->message_len;
+ message = msg->message;
+ message_transaction_id = transaction_id;
+ message_endpoint = endpoint;
+ if (msg->message_len > 0 && msg->message != nullptr) {
+ data_ = std::unique_ptr<uint8_t>(new uint8_t[msg->message_len]);
+ memcpy(data_.get(), msg->message, msg->message_len);
+ message = data_.get();
+ }
+ }
+
HubMessage(HubMessage &&other) {
*this = (HubMessage &&)other;
}
HubMessage &operator = (HubMessage &&other) {
*static_cast<hub_message_t *>(this) = static_cast<hub_message_t>(other);
+ message_transaction_id = other.message_transaction_id;
message_endpoint = other.message_endpoint;
data_ = std::move(other.data_);
other.message = nullptr;
@@ -127,9 +149,12 @@ class NanoHub {
}
int doSubscribeMessages(uint32_t hub_id, Contexthub_callback *cbk, void *cookie);
- int doSendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint16_t endpoint);
- int doSendToDevice(const hub_app_name_t name, const void *data, uint32_t len, uint32_t messageType = 0, uint16_t endpoint = ENDPOINT_UNSPECIFIED);
+ int doSendToNanohub(uint32_t hub_id, const hub_message_t *msg,
+ uint32_t transaction_id, uint16_t endpoint);
+ int doSendToDevice(const hub_app_name_t name, const void *data, uint32_t len,
+ uint32_t messageType = 0, uint16_t endpoint = ENDPOINT_UNSPECIFIED);
void doSendToApp(HubMessage &&msg);
+ void doDumpAppInfo(std::string &result);
static constexpr unsigned int FL_MESSAGE_TRACING = 1;
@@ -148,6 +173,9 @@ public:
static void setDebugFlags(unsigned int flags) {
hubInstance()->mFlags = flags;
}
+ static void dumpAppInfo(std::string &result) {
+ hubInstance()->doDumpAppInfo(result);
+ }
// messaging interface
@@ -156,12 +184,14 @@ public:
return hubInstance()->doSubscribeMessages(hub_id, cbk, cookie);
}
// all messages from APP go here
- static int sendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint16_t endpoint) {
- return hubInstance()->doSendToNanohub(hub_id, msg, endpoint);
+ static int sendToNanohub(uint32_t hub_id, const hub_message_t *msg,
+ uint32_t transaction_id, uint16_t endpoint) {
+ return hubInstance()->doSendToNanohub(hub_id, msg, transaction_id, endpoint);
}
// passes message to kernel driver directly
- static int sendToDevice(const hub_app_name_t *name, const void *data, uint32_t len) {
- return hubInstance()->doSendToDevice(*name, data, len);
+ static int sendToDevice(const hub_app_name_t *name, const void *data, uint32_t len,
+ uint32_t transactionId) {
+ return hubInstance()->doSendToDevice(*name, data, len, transactionId, ENDPOINT_UNSPECIFIED);
}
// passes message to APP via callback
static void sendToApp(HubMessage &&msg) {
diff --git a/contexthubhal/system_comms.cpp b/contexthubhal/system_comms.cpp
index 2a7ca76d..6edd0cbc 100644
--- a/contexthubhal/system_comms.cpp
+++ b/contexthubhal/system_comms.cpp
@@ -16,9 +16,13 @@
#define LOG_TAG "NanohubHAL"
+#include "file.h"
+#include <json/json.h>
+
#include <cassert>
#include <cerrno>
#include <cinttypes>
+#include <string>
#include <endian.h>
@@ -27,12 +31,20 @@
#include <log/log.h>
#include <endian.h>
+#include <sys/stat.h>
+
+#include <media/stagefright/foundation/ADebug.h>
#include <hardware/context_hub.h>
#include "nanohub_perdevice.h"
#include "system_comms.h"
#include "nanohubhal.h"
+#define CHRE_APP_DIR "/data/vendor/sensor/chre"
+#define CHRE_APP_DIR_PERMS (S_IRUSR | S_IWUSR | S_IXUSR)
+#define CHRE_APP_FILE_PERMS (S_IRUSR | S_IWUSR)
+#define CHRE_APP_SETTINGS CHRE_APP_DIR "/apps.json"
+
namespace android {
namespace nanohub {
@@ -47,74 +59,134 @@ static void writeAppName(MessageBuf &buf, const hub_app_name_t &name)
buf.writeU64(name.id);
}
-static void readNanohubAppInfo(MessageBuf &buf, NanohubAppInfo &info)
+static void readNanohubMemInfo(MessageBuf &buf, NanohubMemInfo &mi)
{
- size_t pos = buf.getPos();
- readAppName(buf, info.name);
- info.version = buf.readU32();
- info.flashUse = buf.readU32();
- info.ramUse = buf.readU32();
- if ((buf.getPos() - pos) != sizeof(info)) {
- ALOGE("%s: failed to read object", __func__);
+ uint8_t type, len;
+ uint32_t ramFree = NANOHUB_MEM_SZ_UNKNOWN;
+ uint32_t eeFree = NANOHUB_MEM_SZ_UNKNOWN;
+ uint32_t sharedFree = NANOHUB_MEM_SZ_UNKNOWN;
+ uint32_t osFree = NANOHUB_MEM_SZ_UNKNOWN;
+
+ mi.flashSz = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.blSz = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.osSz = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.sharedSz = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.eeSz = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.ramSz = NANOHUB_MEM_SZ_UNKNOWN;
+
+ mi.blUse = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.osUse = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.sharedUse = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.eeUse = NANOHUB_MEM_SZ_UNKNOWN;
+ mi.ramUse = NANOHUB_MEM_SZ_UNKNOWN;
+
+ while (buf.getRoom() >= 2) {
+ type = buf.readU8();
+ len = buf.readU8();
+ if (buf.getRoom() >= len) {
+ switch(type) {
+ case NANOHUB_HAL_SYS_INFO_HEAP_FREE:
+ if (len == sizeof(ramFree))
+ ramFree = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_RAM_SIZE:
+ if (len == sizeof(mi.ramSz))
+ mi.ramSz = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_EEDATA_SIZE:
+ if (len == sizeof(mi.ramSz))
+ mi.eeSz = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_EEDATA_FREE:
+ if (len == sizeof(eeFree))
+ eeFree = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_CODE_SIZE:
+ if (len == sizeof(mi.osSz))
+ mi.osSz = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_CODE_FREE:
+ if (len == sizeof(osFree))
+ osFree = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_SHARED_SIZE:
+ if (len == sizeof(mi.sharedSz))
+ mi.sharedSz = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_SHARED_FREE:
+ if (len == sizeof(sharedFree))
+ sharedFree = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_SYS_INFO_END:
+ if (len != 0 || buf.getRoom() != 0) {
+ ALOGE("%s: failed to read object", __func__);
+ return;
+ }
+ break;
+ default:
+ ALOGI("%s: unsupported type: %d", __func__, type);
+ buf.readRaw(len);
+ break;
+ }
+ } else {
+ ALOGE("%s: failed to read object", __func__);
+ return;
+ }
}
-}
-static void readNanohubMemInfo(MessageBuf &buf, NanohubMemInfo &mi)
-{
- size_t pos = buf.getPos();
- mi.flashSz = buf.readU32();
- mi.blSz = buf.readU32();
- mi.osSz = buf.readU32();
- mi.sharedSz = buf.readU32();
- mi.eeSz = buf.readU32();
- mi.ramSz = buf.readU32();
-
- mi.blUse = buf.readU32();
- mi.osUse = buf.readU32();
- mi.sharedUse = buf.readU32();
- mi.eeUse = buf.readU32();
- mi.ramUse = buf.readU32();
- if ((buf.getPos() - pos) != sizeof(mi)) {
+ if (buf.getRoom() != 0) {
ALOGE("%s: failed to read object", __func__);
+ return;
}
+
+ if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN && ramFree != NANOHUB_MEM_SZ_UNKNOWN)
+ mi.ramUse = mi.ramSz - ramFree;
+ if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN && eeFree != NANOHUB_MEM_SZ_UNKNOWN)
+ mi.eeUse = mi.eeSz - eeFree;
+ if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN && osFree != NANOHUB_MEM_SZ_UNKNOWN)
+ mi.osUse = mi.osSz - osFree;
+ if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN && sharedFree != NANOHUB_MEM_SZ_UNKNOWN)
+ mi.sharedUse = mi.sharedSz - sharedFree;
}
-NanohubRsp::NanohubRsp(MessageBuf &buf, bool no_status)
+NanohubRsp::NanohubRsp(MessageBuf &buf, uint32_t transactionId, bool chre)
{
- // all responses start with command
- // most of them have 4-byte status (result code)
+ // all responses start with command and have a 4-byte status (result code)
buf.reset();
- cmd = buf.readU8();
- if (!buf.getSize()) {
- status = -EINVAL;
- } else if (no_status) {
- status = 0;
+ if (buf.getSize() < 5) {
+ mStatus = -EINVAL;
} else {
- if (cmd == NANOHUB_START_UPLOAD || cmd == NANOHUB_CONT_UPLOAD || cmd == NANOHUB_FINISH_UPLOAD)
- status = buf.readU8();
+ mCmd = buf.readU8();
+ mStatus = buf.readU32();
+ if (chre)
+ mTransactionId = transactionId;
else
- status = buf.readU32();
+ mTransactionId = 0;
}
}
-int SystemComm::sendToSystem(const void *data, size_t len)
+int SystemComm::sendToSystem(const void *data, size_t len, uint32_t transactionId)
{
if (NanoHub::messageTracingEnabled()) {
- dumpBuffer("HAL -> SYS", getSystem()->mHostIfAppName, 0, 0, data, len);
+ dumpBuffer("HAL -> SYS", getSystem()->mHostIfAppName, transactionId, 0, data, len);
}
- return NanoHub::sendToDevice(&getSystem()->mHostIfAppName, data, len);
-}
-
-int SystemComm::AppInfoSession::setup(const hub_message_t *)
-{
- std::lock_guard<std::mutex> _l(mLock);
- int suggestedSize = mAppInfo.size() ? mAppInfo.size() : 20;
-
- mAppInfo.clear();
- mAppInfo.reserve(suggestedSize);
- setState(SESSION_USER);
-
- return requestNext();
+ return NanoHub::sendToDevice(&getSystem()->mHostIfAppName, data, len, transactionId);
}
inline hub_app_name_t deviceAppNameToHost(const hub_app_name_t src)
@@ -129,143 +201,112 @@ inline hub_app_name_t hostAppNameToDevice(const hub_app_name_t src)
return res;
}
-int SystemComm::AppInfoSession::handleRx(MessageBuf &buf)
+const uint8_t app_info_tags[] =
{
- std::lock_guard<std::mutex> _l(mLock);
-
- NanohubRsp rsp(buf, true);
- if (rsp.cmd != NANOHUB_QUERY_APPS) {
- return 1;
- }
- size_t len = buf.getRoom();
- if (len != sizeof(NanohubAppInfo) && len) {
- ALOGE("%s: Invalid data size; have %zu, need %zu", __func__,
- len, sizeof(NanohubAppInfo));
- return -EINVAL;
- }
- if (getState() != SESSION_USER) {
- ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
- return -EINVAL;
- }
- if (len) {
- NanohubAppInfo info;
- readNanohubAppInfo(buf, info);
- hub_app_info appInfo;
- appInfo.num_mem_ranges = 0;
- if (info.flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
- mem_range_t &range = appInfo.mem_usage[appInfo.num_mem_ranges++];
- range.type = HUB_MEM_TYPE_MAIN;
- range.total_bytes = info.flashUse;
- }
- if (info.ramUse != NANOHUB_MEM_SZ_UNKNOWN) {
- mem_range_t &range = appInfo.mem_usage[appInfo.num_mem_ranges++];
- range.type = HUB_MEM_TYPE_RAM;
- range.total_bytes = info.ramUse;
- }
-
- appInfo.app_name = info.name;
- appInfo.version = info.version;
-
- mAppInfo.push_back(appInfo);
- return requestNext();
- } else {
- sendToApp(CONTEXT_HUB_QUERY_APPS,
- static_cast<const void *>(mAppInfo.data()),
- mAppInfo.size() * sizeof(mAppInfo[0]));
- complete();
- }
-
- return 0;
-}
-
-int SystemComm::AppInfoSession::requestNext()
+ NANOHUB_HAL_APP_INFO_APPID,
+ NANOHUB_HAL_APP_INFO_CRC,
+ NANOHUB_HAL_APP_INFO_TID,
+ NANOHUB_HAL_APP_INFO_VERSION,
+ NANOHUB_HAL_APP_INFO_ADDR,
+ NANOHUB_HAL_APP_INFO_SIZE,
+ NANOHUB_HAL_APP_INFO_HEAP,
+ NANOHUB_HAL_APP_INFO_DATA,
+ NANOHUB_HAL_APP_INFO_BSS,
+ NANOHUB_HAL_APP_INFO_CHRE_MAJOR,
+ NANOHUB_HAL_APP_INFO_CHRE_MINOR,
+ NANOHUB_HAL_APP_INFO_END,
+};
+
+const uint8_t sys_info_tags[] =
{
- char data[MAX_RX_PACKET];
- MessageBuf buf(data, sizeof(data));
- buf.writeU8(NANOHUB_QUERY_APPS);
- buf.writeU32(mAppInfo.size());
- return sendToSystem(buf.getData(), buf.getPos());
-}
-
-int SystemComm::MemInfoSession::setup(const hub_message_t *)
+ NANOHUB_HAL_SYS_INFO_HEAP_FREE,
+ NANOHUB_HAL_SYS_INFO_RAM_SIZE,
+ NANOHUB_HAL_SYS_INFO_EEDATA_SIZE,
+ NANOHUB_HAL_SYS_INFO_EEDATA_FREE,
+ NANOHUB_HAL_SYS_INFO_CODE_SIZE,
+ NANOHUB_HAL_SYS_INFO_CODE_FREE,
+ NANOHUB_HAL_SYS_INFO_SHARED_SIZE,
+ NANOHUB_HAL_SYS_INFO_SHARED_FREE,
+ NANOHUB_HAL_SYS_INFO_END,
+};
+
+int SystemComm::MemInfoSession::setup(const hub_message_t *, uint32_t transactionId, AppManager &)
{
std::lock_guard<std::mutex> _l(mLock);
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- buf.writeU8(NANOHUB_QUERY_MEMINFO);
+ buf.writeU8(NANOHUB_HAL_SYS_INFO);
+ buf.writeRaw(sys_info_tags, sizeof(sys_info_tags));
setState(SESSION_USER);
- return sendToSystem(buf.getData(), buf.getPos());
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
}
-int SystemComm::MemInfoSession::handleRx(MessageBuf &buf)
+int SystemComm::MemInfoSession::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &, bool chre)
{
std::lock_guard<std::mutex> _l(mLock);
- NanohubRsp rsp(buf, true);
+ NanohubRsp rsp(buf, transactionId, chre);
- if (rsp.cmd != NANOHUB_QUERY_MEMINFO)
+ if (rsp.mCmd != NANOHUB_HAL_SYS_INFO)
return 1;
size_t len = buf.getRoom();
- if (len != sizeof(NanohubMemInfo)) {
- ALOGE("%s: Invalid data size: %zu", __func__, len);
- return -EINVAL;
- }
if (getState() != SESSION_USER) {
ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
return -EINVAL;
}
- NanohubMemInfo mi;
- readNanohubMemInfo(buf, mi);
std::vector<mem_range_t> ranges;
ranges.reserve(4);
-
- //if each is valid, copy to output area
- if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN &&
- mi.sharedUse != NANOHUB_MEM_SZ_UNKNOWN)
- ranges.push_back({
- .type = HUB_MEM_TYPE_MAIN,
- .total_bytes = mi.sharedSz,
- .free_bytes = mi.sharedSz - mi.sharedUse,
- });
-
- if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN &&
- mi.osUse != NANOHUB_MEM_SZ_UNKNOWN)
- ranges.push_back({
- .type = HUB_MEM_TYPE_OS,
- .total_bytes = mi.osSz,
- .free_bytes = mi.osSz - mi.osUse,
- });
-
- if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN &&
- mi.eeUse != NANOHUB_MEM_SZ_UNKNOWN)
- ranges.push_back({
- .type = HUB_MEM_TYPE_EEDATA,
- .total_bytes = mi.eeSz,
- .free_bytes = mi.eeSz - mi.eeUse,
- });
-
- if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN &&
- mi.ramUse != NANOHUB_MEM_SZ_UNKNOWN)
- ranges.push_back({
- .type = HUB_MEM_TYPE_RAM,
- .total_bytes = mi.ramSz,
- .free_bytes = mi.ramSz - mi.ramUse,
- });
+ if (len) {
+ NanohubMemInfo mi;
+ readNanohubMemInfo(buf, mi);
+
+ //if each is valid, copy to output area
+ if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN &&
+ mi.sharedUse != NANOHUB_MEM_SZ_UNKNOWN)
+ ranges.push_back({
+ .type = HUB_MEM_TYPE_MAIN,
+ .total_bytes = mi.sharedSz,
+ .free_bytes = mi.sharedSz - mi.sharedUse,
+ });
+
+ if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN &&
+ mi.osUse != NANOHUB_MEM_SZ_UNKNOWN)
+ ranges.push_back({
+ .type = HUB_MEM_TYPE_OS,
+ .total_bytes = mi.osSz,
+ .free_bytes = mi.osSz - mi.osUse,
+ });
+
+ if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN &&
+ mi.eeUse != NANOHUB_MEM_SZ_UNKNOWN)
+ ranges.push_back({
+ .type = HUB_MEM_TYPE_EEDATA,
+ .total_bytes = mi.eeSz,
+ .free_bytes = mi.eeSz - mi.eeUse,
+ });
+
+ if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN &&
+ mi.ramUse != NANOHUB_MEM_SZ_UNKNOWN)
+ ranges.push_back({
+ .type = HUB_MEM_TYPE_RAM,
+ .total_bytes = mi.ramSz,
+ .free_bytes = mi.ramSz - mi.ramUse,
+ });
+ }
//send it out
- sendToApp(CONTEXT_HUB_QUERY_MEMORY,
+ sendToApp(CONTEXT_HUB_QUERY_MEMORY, transactionId,
static_cast<const void *>(ranges.data()),
ranges.size() * sizeof(ranges[0]));
complete();
-
return 0;
}
-int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg)
+int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg, uint32_t transactionId, AppManager &appManager)
{
std::lock_guard<std::mutex> _l(mLock);
@@ -281,203 +322,468 @@ int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg)
switch (mCmd) {
case CONTEXT_HUB_APPS_ENABLE:
- return setupMgmt(appMsg, NANOHUB_EXT_APPS_ON);
+ return setupMgmt(appMsg, transactionId, NANOHUB_HAL_APP_MGMT_START, appManager);
case CONTEXT_HUB_APPS_DISABLE:
- return setupMgmt(appMsg, NANOHUB_EXT_APPS_OFF);
+ return setupMgmt(appMsg, transactionId, NANOHUB_HAL_APP_MGMT_STOP, appManager);
case CONTEXT_HUB_UNLOAD_APP:
- return setupMgmt(appMsg, NANOHUB_EXT_APP_DELETE);
+ return setupMgmt(appMsg, transactionId, NANOHUB_HAL_APP_MGMT_UNLOAD, appManager);
case CONTEXT_HUB_LOAD_APP:
{
- mData.clear();
- mData = std::vector<uint8_t>(msgData, msgData + mLen);
const load_app_request_t *appReq = static_cast<const load_app_request_t*>(appMsg->message);
if (appReq == nullptr || mLen <= sizeof(*appReq)) {
ALOGE("%s: Invalid app header: too short\n", __func__);
return -EINVAL;
}
mAppName = appReq->app_binary.app_id;
- setState(TRANSFER);
-
- buf.writeU8(NANOHUB_START_UPLOAD);
- buf.writeU8(0);
- buf.writeU32(mLen);
- return sendToSystem(buf.getData(), buf.getPos());
+ if (!appManager.isAppLoaded(mAppName)) {
+ appManager.addNewApp(mAppName, appReq->app_binary.app_version);
+ appManager.writeApp(mAppName, msgData, mLen);
+ mData.clear();
+ mData = std::vector<uint8_t>(msgData, msgData + mLen);
+ setState(TRANSFER);
+
+ buf.writeU8(NANOHUB_HAL_START_UPLOAD);
+ buf.writeU8(0);
+ buf.writeU32(mLen);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+ } else {
+ if (appManager.cmpApp(mAppName, msgData, mLen)) {
+ mFlashAddr = appManager.getFlashAddr(mAppName);
+ if (appManager.isAppRunning(mAppName)) {
+ setState(STOP_RUN);
+
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
+ writeAppName(buf, mAppName);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_STOP);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+ } else {
+ setState(RUN);
+
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
+ writeAppName(buf, mAppName);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+ }
+ } else {
+ appManager.setCachedVersion(mAppName, appReq->app_binary.app_version);
+ appManager.writeApp(mAppName, msgData, mLen);
+ mData.clear();
+ mData = std::vector<uint8_t>(msgData, msgData + mLen);
+ if (appManager.isAppRunning(mAppName)) {
+ setState(STOP_TRANSFER);
+
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
+ writeAppName(buf, mAppName);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_STOP);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+ } else {
+ setState(TRANSFER);
+
+ buf.writeU8(NANOHUB_HAL_START_UPLOAD);
+ buf.writeU8(0);
+ buf.writeU32(mLen);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+ }
+ }
+ }
}
-
case CONTEXT_HUB_OS_REBOOT:
setState(REBOOT);
- buf.writeU8(NANOHUB_REBOOT);
- return sendToSystem(buf.getData(), buf.getPos());
+
+ buf.writeU8(NANOHUB_HAL_SYS_MGMT);
+ buf.writeU8(NANOHUB_HAL_SYS_MGMT_REBOOT);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+
+ case CONTEXT_HUB_START_APPS:
+ if (mLen == sizeof(mStatus))
+ memcpy(&mStatus, msgData, mLen);
+ appManager.eraseApps();
+ setState(QUERY_START);
+
+ buf.writeU8(NANOHUB_HAL_APP_INFO);
+ buf.writeU32(0);
+ buf.writeRaw(app_info_tags, sizeof(app_info_tags));
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
}
return -EINVAL;
}
-int SystemComm::AppMgmtSession::setupMgmt(const hub_message_t *appMsg, uint32_t cmd)
+int SystemComm::AppMgmtSession::setupMgmt(const hub_message_t *appMsg, uint32_t transactionId, uint32_t cmd, AppManager &appManager)
{
+ int32_t result = 0;
const hub_app_name_t &appName = *static_cast<const hub_app_name_t*>(appMsg->message);
if (appMsg->message_len != sizeof(appName)) {
return -EINVAL;
}
-
+ mAppName = appName;
+
+ switch (cmd) {
+ case NANOHUB_HAL_APP_MGMT_START:
+ if (appManager.isAppRunning(mAppName)) {
+ appManager.setCachedStart(mAppName, true);
+ sendToApp(mCmd, transactionId, &result, sizeof(result));
+ complete();
+ return 0;
+ }
+ break;
+ case NANOHUB_HAL_APP_MGMT_STOP:
+ case NANOHUB_HAL_APP_MGMT_UNLOAD:
+ appManager.setCachedStart(mAppName, false);
+ if (!appManager.isAppRunning(mAppName)) {
+ sendToApp(mCmd, transactionId, &result, sizeof(result));
+ complete();
+ return 0;
+ }
+ break;
+ }
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- buf.writeU8(cmd);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
writeAppName(buf, appName);
+ buf.writeU8(cmd);
setState(MGMT);
- return sendToSystem(buf.getData(), buf.getPos());
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
}
-int SystemComm::AppMgmtSession::handleRx(MessageBuf &buf)
+int SystemComm::AppMgmtSession::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre)
{
int ret = 0;
std::lock_guard<std::mutex> _l(mLock);
- NanohubRsp rsp(buf);
+ NanohubRsp rsp(buf, transactionId, chre);
switch (getState()) {
case TRANSFER:
- ret = handleTransfer(rsp);
+ ret = handleTransfer(rsp, buf, appManager);
+ break;
+ case STOP_TRANSFER:
+ ret = handleStopTransfer(rsp, buf, appManager);
+ break;
+ case QUERY_START:
+ ret = handleQueryStart(rsp, buf, appManager);
+ break;
+ case START:
+ ret = handleStart(rsp, buf, appManager);
break;
case FINISH:
- ret = handleFinish(rsp);
+ ret = handleFinish(rsp, buf, appManager);
break;
case RUN:
- ret = handleRun(rsp);
+ ret = handleRun(rsp, buf, appManager);
break;
- case RUN_FAILED:
- ret = handleRunFailed(rsp);
+ case STOP_RUN:
+ ret = handleStopRun(rsp, buf, appManager);
break;
case REBOOT:
- ret = handleReboot(rsp);
+ ret = handleReboot(rsp, buf, appManager);
+ break;
+ case ERASE_TRANSFER:
+ ret = handleEraseTransfer(rsp, buf, appManager);
break;
case MGMT:
- ret = handleMgmt(rsp);
+ ret = handleMgmt(rsp, buf, appManager);
+ break;
+ case INFO:
+ ret = handleInfo(rsp, buf, appManager);
break;
}
return ret;
}
-int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp, MessageBuf &, AppManager &appManager)
{
- if (rsp.cmd != NANOHUB_CONT_UPLOAD && rsp.cmd != NANOHUB_START_UPLOAD)
+ if (rsp.mCmd != NANOHUB_HAL_CONT_UPLOAD && rsp.mCmd != NANOHUB_HAL_START_UPLOAD)
return 1;
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- const bool success = rsp.status != 0;
+ int32_t result = 0;
static_assert(NANOHUB_UPLOAD_CHUNK_SZ_MAX <= (MAX_RX_PACKET-5),
"Invalid chunk size");
- if (success) {
+ if (rsp.mStatus == NANOHUB_HAL_UPLOAD_ACCEPTED) {
mPos = mNextPos;
mErrCnt = 0;
+ } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_RESEND) {
+ mErrCnt ++;
+ } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_RESTART) {
+ mPos = 0;
+ mErrCnt ++;
+ } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_CANCEL ||
+ rsp.mStatus == NANOHUB_HAL_UPLOAD_CANCEL_NO_RETRY) {
+ mPos = mLen;
+ result = NANOHUB_APP_NOT_LOADED;
+ } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_NO_SPACE) {
+ mPos = 0;
+ mErrCnt = 0;
+ setState(ERASE_TRANSFER);
+
+ buf.writeU8(NANOHUB_HAL_SYS_MGMT);
+ buf.writeU8(NANOHUB_HAL_SYS_MGMT_ERASE);
+
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
} else if (mErrCnt > 5) {
mPos = mLen;
+ result = NANOHUB_APP_NOT_LOADED;
} else {
mErrCnt ++;
}
- if (mPos < mLen) {
+ if (result != 0) {
+ appManager.clearCachedApp(mAppName);
+
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
+ complete();
+ return 0;
+ } else if (mPos < mLen) {
uint32_t chunkSize = mLen - mPos;
if (chunkSize > NANOHUB_UPLOAD_CHUNK_SZ_MAX) {
chunkSize = NANOHUB_UPLOAD_CHUNK_SZ_MAX;
}
- buf.writeU8(NANOHUB_CONT_UPLOAD);
+ buf.writeU8(NANOHUB_HAL_CONT_UPLOAD);
buf.writeU32(mPos);
buf.writeRaw(&mData[mPos], chunkSize);
mNextPos = mPos + chunkSize;
} else {
- buf.writeU8(NANOHUB_FINISH_UPLOAD);
+ buf.writeU8(NANOHUB_HAL_FINISH_UPLOAD);
setState(FINISH);
}
- return sendToSystem(buf.getData(), buf.getPos());
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
}
-int SystemComm::AppMgmtSession::handleFinish(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleStopTransfer(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
- if (rsp.cmd != NANOHUB_FINISH_UPLOAD)
+ if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
return 1;
- int ret = 0;
- const bool success = rsp.status != 0;
- mData.clear();
+ uint8_t cmd = buf.readU8();
- if (success) {
+ if (cmd != NANOHUB_HAL_APP_MGMT_STOP)
+ return 1;
+
+ MgmtStatus sts = { .value = buf.readU32() };
+
+ ALOGI("Nanohub NEW APP STOP: %08" PRIX32 "\n", sts.value);
+ if (rsp.mStatus == 0) {
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- buf.writeU8(NANOHUB_EXT_APPS_ON);
- writeAppName(buf, mAppName);
- setState(RUN);
- ret = sendToSystem(buf.getData(), buf.getPos());
+ setState(TRANSFER);
+
+ buf.writeU8(NANOHUB_HAL_START_UPLOAD);
+ buf.writeU8(0);
+ buf.writeU32(mLen);
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
} else {
int32_t result = NANOHUB_APP_NOT_LOADED;
- sendToApp(mCmd, &result, sizeof(result));
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
complete();
+ return 0;
}
+}
- return ret;
+int SystemComm::AppMgmtSession::handleQueryStart(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
+{
+
+ if (rsp.mCmd != NANOHUB_HAL_APP_INFO)
+ return 1;
+
+ size_t len = buf.getRoom();
+ if (len) {
+ uint32_t nextAddr = appManager.readNanohubAppInfo(buf);
+
+ if (nextAddr) {
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+
+ buf.writeU8(NANOHUB_HAL_APP_INFO);
+ buf.writeU32(nextAddr);
+ buf.writeRaw(app_info_tags, sizeof(app_info_tags));
+
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ }
+ }
+
+ appManager.getAppsToStart(mAppList);
+ if (mAppList.empty()) {
+ sendToApp(CONTEXT_HUB_OS_REBOOT, 0, &mStatus, sizeof(mStatus));
+ complete();
+ return 0;
+ } else {
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ mAppName = mAppList.back();
+ mAppList.pop_back();
+ setState(START);
+
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
+ writeAppName(buf, mAppName);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ }
}
-int SystemComm::AppMgmtSession::handleRun(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleStart(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
- if (rsp.cmd != NANOHUB_EXT_APPS_ON)
+ if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
return 1;
- MgmtStatus sts = { .value = (uint32_t)rsp.status };
+ uint8_t cmd = buf.readU8();
- // op counter returns number of nanoapps that were started as result of the command
- // for successful start command it must be > 0
- int32_t result = sts.value > 0 && sts.op > 0 && sts.op <= 0x7F ? 0 : -1;
+ if (cmd != NANOHUB_HAL_APP_MGMT_START)
+ return 1;
- ALOGI("Nanohub NEW APP START: %08" PRIX32 "\n", rsp.status);
- if (result != 0) {
- // if nanoapp failed to start we have to unload it
+ MgmtStatus sts = { .value = buf.readU32() };
+
+ ALOGI("Nanohub EXISTING APP START: %08" PRIX32 "\n", sts.value);
+ if (mAppList.empty()) {
+ sendToApp(CONTEXT_HUB_OS_REBOOT, 0, &mStatus, sizeof(mStatus));
+ complete();
+ return 0;
+ } else {
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- buf.writeU8(NANOHUB_EXT_APP_DELETE);
+ mAppName = mAppList.back();
+ mAppList.pop_back();
+
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
writeAppName(buf, mAppName);
- if (sendToSystem(buf.getData(), buf.getPos()) == 0) {
- setState(RUN_FAILED);
- return 0;
- }
- ALOGE("%s: failed to send DELETE for failed app\n", __func__);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ }
+}
+
+int SystemComm::AppMgmtSession::handleFinish(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
+{
+ if (rsp.mCmd != NANOHUB_HAL_FINISH_UPLOAD)
+ return 1;
+
+ mFlashAddr = buf.readU32();
+ uint32_t crc = buf.readU32();
+ mData.clear();
+
+ if (rsp.mStatus == 0) {
+ appManager.setCachedCrc(mAppName, crc);
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ setState(RUN);
+
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
+ writeAppName(buf, mAppName);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ } else {
+ int32_t result = NANOHUB_APP_NOT_LOADED;
+ appManager.clearCachedApp(mAppName);
+
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
+ complete();
+ return 0;
+ }
+}
+
+int SystemComm::AppMgmtSession::handleRun(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
+{
+ if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
+ return 1;
+
+ uint8_t cmd = buf.readU8();
+
+ if (cmd != NANOHUB_HAL_APP_MGMT_START)
+ return 1;
+
+ MgmtStatus sts = { .value = buf.readU32() };
+
+ ALOGI("Nanohub NEW APP START: %08" PRIX32 "\n", sts.value);
+ if (rsp.mStatus == 0) {
+ appManager.setCachedStart(mAppName, true);
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ setState(INFO);
+
+ buf.writeU8(NANOHUB_HAL_APP_INFO);
+ buf.writeU32(mFlashAddr);
+ buf.writeRaw(app_info_tags, sizeof(app_info_tags));
+
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ } else {
+ appManager.setCachedStart(mAppName, false);
+ int32_t result = NANOHUB_APP_NOT_LOADED;
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
+ complete();
+ return 0;
}
+}
- // it is either success, and we report it, or
- // it is a failure to load, and also failure to send erase command
- sendToApp(mCmd, &result, sizeof(result));
+int SystemComm::AppMgmtSession::handleInfo(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
+{
+ if (rsp.mCmd != NANOHUB_HAL_APP_INFO)
+ return 1;
+ int32_t result = 0;
+ size_t len = buf.getRoom();
+ if (len) {
+ appManager.readNanohubAppInfo(buf);
+ appManager.saveApps();
+ }
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
complete();
return 0;
}
-int SystemComm::AppMgmtSession::handleRunFailed(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleStopRun(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
- if (rsp.cmd != NANOHUB_EXT_APP_DELETE)
+ if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
return 1;
- int32_t result = -1;
+ uint8_t cmd = buf.readU8();
+
+ if (cmd != NANOHUB_HAL_APP_MGMT_STOP)
+ return 1;
- ALOGI("%s: APP DELETE [because it failed]: %08" PRIX32 "\n", __func__, rsp.status);
+ MgmtStatus sts = { .value = buf.readU32() };
- sendToApp(mCmd, &result, sizeof(result));
- complete();
+ ALOGI("Nanohub NEW APP STOP: %08" PRIX32 "\n", sts.value);
+ if (rsp.mStatus == 0) {
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ setState(RUN);
- return 0;
+ buf.writeU8(NANOHUB_HAL_APP_MGMT);
+ writeAppName(buf, mAppName);
+ buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ } else {
+ int32_t result = NANOHUB_APP_NOT_LOADED;
+
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
+ complete();
+ return 0;
+ }
}
/* reboot notification, when triggered by App request */
-int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
- if (rsp.cmd != NANOHUB_REBOOT)
+ if (rsp.mCmd != NANOHUB_HAL_SYS_MGMT)
return 1;
- ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32 "\n", rsp.status);
+
+ uint8_t cmd = buf.readU8();
+
+ if (cmd == NANOHUB_HAL_SYS_MGMT_REBOOT)
+ ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32 "\n", rsp.mStatus);
// reboot notification is sent by SessionManager
complete();
@@ -485,59 +791,102 @@ int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp)
return 0;
}
-int SystemComm::AppMgmtSession::handleMgmt(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleEraseTransfer(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{
+ if (rsp.mCmd != NANOHUB_HAL_SYS_MGMT)
+ return 1;
+
+ uint8_t cmd = buf.readU8();
+
+ if (cmd == NANOHUB_HAL_SYS_MGMT_ERASE && rsp.mStatus == 0) {
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ appManager.eraseApps();
+ setState(TRANSFER);
+
+ buf.writeU8(NANOHUB_HAL_START_UPLOAD);
+ buf.writeU8(0);
+ buf.writeU32(mLen);
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ } else {
+ int32_t result = NANOHUB_APP_NOT_LOADED;
+
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
+ complete();
+ return 0;
+ }
+}
+
+int SystemComm::AppMgmtSession::handleMgmt(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
+{
+ if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
+ return 1;
+
+ uint8_t cmd = buf.readU8();
+ MgmtStatus sts = { .value = buf.readU32() };
+
bool valid = false;
- int32_t result = rsp.status;
+ int32_t result = rsp.mStatus;
- // TODO: remove this when context hub service can handle non-zero success status
- if (result > 0) {
- // something happened; assume it worked
- result = 0;
- } else if (result == 0) {
- // nothing happened; this is provably an error
+ if (result != 0)
result = -1;
- }
- switch (rsp.cmd) {
- case NANOHUB_EXT_APPS_OFF:
+ switch (cmd) {
+ case NANOHUB_HAL_APP_MGMT_STOP:
valid = mCmd == CONTEXT_HUB_APPS_DISABLE;
+ if (valid && rsp.mStatus == 0)
+ appManager.clearRunning(mAppName);
break;
- case NANOHUB_EXT_APPS_ON:
+ case NANOHUB_HAL_APP_MGMT_START:
valid = mCmd == CONTEXT_HUB_APPS_ENABLE;
+ if (valid && rsp.mStatus == 0) {
+ appManager.setCachedStart(mAppName, true);
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ setState(INFO);
+
+ buf.writeU8(NANOHUB_HAL_APP_INFO);
+ buf.writeU32(appManager.getFlashAddr(mAppName));
+ buf.writeRaw(app_info_tags, sizeof(app_info_tags));
+
+ return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
+ }
break;
- case NANOHUB_EXT_APP_DELETE:
+ case NANOHUB_HAL_APP_MGMT_UNLOAD:
valid = mCmd == CONTEXT_HUB_UNLOAD_APP;
+ if (valid && rsp.mStatus == 0)
+ appManager.clearRunning(mAppName);
break;
default:
return 1;
}
- ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.cmd, rsp.status);
+ ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.mCmd, sts.value);
if (!valid) {
ALOGE("Invalid response for this state: APP CMD=%02X", mCmd);
return -EINVAL;
}
- sendToApp(mCmd, &result, sizeof(result));
+ sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
complete();
-
return 0;
}
-int SystemComm::KeyInfoSession::setup(const hub_message_t *) {
+int SystemComm::KeyInfoSession::setup(const hub_message_t *, uint32_t transactionId, AppManager &) {
std::lock_guard<std::mutex> _l(mLock);
+ mKeyNum = 0;
+ mKeyOffset = 0;
mRsaKeyData.clear();
setState(SESSION_USER);
mStatus = -EBUSY;
- return requestRsaKeys();
+ return requestRsaKeys(transactionId);
}
-int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf)
+int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &, bool chre)
{
std::lock_guard<std::mutex> _l(mLock);
- NanohubRsp rsp(buf, true);
+ NanohubRsp rsp(buf, transactionId, chre);
if (getState() != SESSION_USER) {
// invalid state
@@ -545,11 +894,20 @@ int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf)
return mStatus;
}
- if (buf.getRoom()) {
+ uint32_t keyLen = buf.readU32();
+ uint32_t dataLen = buf.getRoom();
+
+ if (dataLen) {
mRsaKeyData.insert(mRsaKeyData.end(),
buf.getData() + buf.getPos(),
buf.getData() + buf.getSize());
- return requestRsaKeys();
+ if (mKeyOffset + dataLen >= keyLen) {
+ mKeyNum++;
+ mKeyOffset = 0;
+ } else {
+ mKeyOffset += dataLen;
+ }
+ return requestRsaKeys(transactionId);
} else {
mStatus = 0;
complete();
@@ -557,19 +915,460 @@ int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf)
}
}
-int SystemComm::KeyInfoSession::requestRsaKeys(void)
+int SystemComm::KeyInfoSession::requestRsaKeys(uint32_t transactionId)
{
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- buf.writeU8(NANOHUB_QUERY_APPS);
- buf.writeU32(mRsaKeyData.size());
+ buf.writeU8(NANOHUB_HAL_KEY_INFO);
+ buf.writeU32(mKeyNum);
+ buf.writeU32(mKeyOffset);
+
+ return sendToSystem(buf.getData(), buf.getPos(), transactionId);
+}
+
+void SystemComm::AppManager::dumpAppInfo(std::string &result)
+{
+ char buffer[256];
+
+ for (auto &it : apps_) {
+ uint64_t id = it.first;
+ const auto &app = it.second;
+
+ snprintf(buffer, sizeof(buffer), "App: 0x%016" PRIx64 "\n", id);
+ result.append(buffer);
+ if (app->loaded) {
+ snprintf(buffer, sizeof(buffer),
+ " Version: 0x%08" PRIx32 "\n"
+ " flashAddr: 0x%08" PRIx32 "\n"
+ " Running: %s\n",
+ app->version,
+ app->flashAddr,
+ app->running ? "true" : "false");
+ result.append(buffer);
+
+ if (app->flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
+ snprintf(buffer, sizeof(buffer),
+ " flashUse: %d\n"
+ " CRC: 0x%08" PRIx32 "\n",
+ app->flashUse,
+ app->crc);
+ result.append(buffer);
+ }
+
+ if (app->running) {
+ snprintf(buffer, sizeof(buffer),
+ " TID: %04x\n"
+ " ramUse: %d\n",
+ app->tid,
+ app->ramUse);
+ result.append(buffer);
+ }
+
+ if (app->chre) {
+ snprintf(buffer, sizeof(buffer), " CHRE: %d.%d\n",
+ app->chre_major, app->chre_minor);
+ result.append(buffer);
+ }
+ }
+
+ if (app->cached_napp) {
+ snprintf(buffer, sizeof(buffer),
+ " Cached Version: 0x%08" PRIx32 "\n"
+ " Cached Start: %s\n"
+ " Cached CRC: 0x%08" PRIx32 "\n",
+ app->cached_version,
+ app->cached_start ? "true" : "false",
+ app->cached_crc);
+ result.append(buffer);
+ }
+ }
+}
+
+bool SystemComm::AppManager::saveApps()
+{
+ mkdir(CHRE_APP_DIR, CHRE_APP_DIR_PERMS);
+ File saved_apps_file(CHRE_APP_SETTINGS, "w");
+ std::shared_ptr<Json::Value> appsObject(new Json::Value);
+ status_t err;
+
+ if ((err = saved_apps_file.initCheck()) != OK) {
+ ALOGW("saved_apps file open (w) failed %d (%s)",
+ err,
+ strerror(-err));
+ return false;
+ }
+
+ for (auto &it : apps_) {
+ uint64_t id = it.first;
+ const auto &app = it.second;
+
+ if (app->cached_napp) {
+ char hexId[17];
+ snprintf(hexId, sizeof(hexId), "%016" PRIX64, id);
+ Json::Value array(Json::arrayValue);
+ array[0] = app->cached_version;
+ array[1] = app->cached_start;
+ array[2] = app->cached_crc;
+ (*appsObject)[hexId] = array;
+ }
+ }
+
+ // Write the JSON string to disk.
+ Json::StyledWriter writer;
+ std::string serializedSettings(writer.write(*appsObject));
+ size_t size = serializedSettings.size();
+ if ((err = saved_apps_file.write(serializedSettings.c_str(), size)) != (ssize_t)size) {
+ ALOGW("saved_apps file write failed %d (%s)",
+ err,
+ strerror(-err));
+ return false;
+ }
+
+ return true;
+}
+
+bool SystemComm::AppManager::restoreApps()
+{
+ File saved_apps_file(CHRE_APP_SETTINGS, "r");
+ std::shared_ptr<Json::Value> appsObject;
+ status_t err;
+
+ if ((err = saved_apps_file.initCheck()) != OK) {
+ ALOGW("saved_apps file open (r) failed %d (%s)",
+ err,
+ strerror(-err));
+ return false;
+ }
+
+ off64_t size = saved_apps_file.seekTo(0, SEEK_END);
+ saved_apps_file.seekTo(0, SEEK_SET);
+
+ if (size > 0) {
+ char *buf = (char *)malloc(size);
+ CHECK_EQ(saved_apps_file.read(buf, size), (ssize_t)size);
+
+ std::string str(buf);
+ std::shared_ptr<Json::Value> in(new Json::Value);
+ Json::Reader reader;
+ bool valid = reader.parse(str, *in);
+ free(buf);
+
+ if (valid && in->isObject()) {
+ appsObject = in;
+ }
+ }
+
+ if (appsObject == nullptr) {
+ appsObject = std::shared_ptr<Json::Value>(new Json::Value(Json::objectValue));
+ }
+
+ Json::Value::Members apps = appsObject->getMemberNames();
+ for (auto &it : apps) {
+ Json::Value &val = (*appsObject)[it];
+ if (val.isArray()) {
+ uint32_t version = val[0].asUInt();
+ uint32_t start = val[1].asUInt();
+ uint32_t crc = val[2].asUInt();
+
+ uint64_t id = strtoull(it.c_str(), nullptr, 16);
+ apps_[id] = std::unique_ptr<AppData>(new AppData);
+ apps_[id]->loaded = false;
+ apps_[id]->running = false;
+ apps_[id]->chre = false;
+ apps_[id]->cached_napp = true;
+ apps_[id]->cached_version = version;
+ apps_[id]->cached_start = start;
+ apps_[id]->cached_crc = crc;
+ }
+ }
+
+ return true;
+}
+
+bool SystemComm::AppManager::eraseApps()
+{
+ for (auto it=apps_.begin(); it != apps_.end();) {
+ if (!it->second->cached_napp)
+ it = apps_.erase(it);
+ else {
+ it->second->loaded = false;
+ it->second->running = false;
+ it->second->chre = false;
+ ++it;
+ }
+ }
+
+ return true;
+}
+
+bool SystemComm::AppManager::writeApp(hub_app_name_t &appName, const uint8_t *data, int32_t len)
+{
+ mkdir(CHRE_APP_DIR, CHRE_APP_DIR_PERMS);
+ char file[strlen(CHRE_APP_DIR) + strlen("/") + 16 + strlen(".napp") + 1];
+
+ snprintf(file, sizeof(file), "%s/%016" PRIX64 ".napp", CHRE_APP_DIR, appName.id);
- return sendToSystem(buf.getData(), buf.getPos());
+ int fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, CHRE_APP_FILE_PERMS);
+ if (fd == -1)
+ return false;
+
+ if (write(fd, data, len) == len) {
+ close(fd);
+ return true;
+ } else {
+ close(fd);
+ return false;
+ }
}
-int SystemComm::doHandleRx(uint64_t appId, const char *data, int len)
+int32_t SystemComm::AppManager::readApp(hub_app_name_t &appName, void **data)
{
+ char file[strlen(CHRE_APP_DIR) + strlen("/") + 16 + strlen(".napp") + 1];
+
+ snprintf(file, sizeof(file), "%s/%016" PRIX64 ".napp", CHRE_APP_DIR, appName.id);
+
+ int32_t ret = -1;
+ *data = nullptr;
+ int fd = open(file, O_RDONLY);
+
+ if (fd >= 0) {
+ struct stat sb;
+ if (fstat(fd, &sb) == 0) {
+ *data = malloc(sb.st_size);
+ if (*data != nullptr && read(fd, *data, sb.st_size) == sb.st_size)
+ ret = sb.st_size;
+ else {
+ free(*data);
+ *data = nullptr;
+ }
+ }
+ close(fd);
+ }
+ return ret;
+}
+
+bool SystemComm::AppManager::cmpApp(hub_app_name_t &appName, const uint8_t *data, uint32_t len)
+{
+ char file[strlen(CHRE_APP_DIR) + strlen("/") + 16 + strlen(".napp") + 1];
+
+ snprintf(file, sizeof(file), "%s/%016" PRIX64 ".napp", CHRE_APP_DIR, appName.id);
+
+ if (!isAppLoaded(appName))
+ return false;
+
+ if ((!apps_[appName.id]->cached_napp) ||
+ (apps_[appName.id]->crc != apps_[appName.id]->cached_crc))
+ return false;
+
+ bool success = false;
+ int fd = open(file, O_RDONLY);
+
+ if (fd >= 0) {
+ struct stat sb;
+ if (fstat(fd, &sb) == 0 && sb.st_size == len) {
+ void *buf = malloc(len);
+ if (buf != nullptr && read(fd, buf, sb.st_size) == sb.st_size && memcmp(data, buf, len) == 0)
+ success = true;
+ free(buf);
+ }
+ close(fd);
+ }
+ return success;
+}
+
+uint32_t SystemComm::AppManager::readNanohubAppInfo(MessageBuf &buf)
+{
+ hub_app_name_t name;
+
+ uint8_t tag, len;
+ uint32_t ramUse = 0;
+ bool ramUseValid = true;
+
+ // first tag must be the appid
+ if (buf.getRoom() < 2 + sizeof(name.id)) {
+ ALOGE("%s: failed to read object", __func__);
+ return 0;
+ }
+
+ tag = buf.readU8();
+ len = buf.readU8();
+ if (tag != NANOHUB_HAL_APP_INFO_APPID || len != sizeof(name.id)) {
+ ALOGE("%s: invalid first tag: %d", __func__, tag);
+ return 0;
+ }
+
+ readAppName(buf, name);
+ if (!isAppPresent(name)) {
+ apps_[name.id] = std::unique_ptr<AppData>(new AppData);
+ apps_[name.id]->loaded = false;
+ apps_[name.id]->chre = false;
+ apps_[name.id]->running = false;
+ apps_[name.id]->cached_napp = false;
+ }
+ const auto &app = apps_[name.id];
+
+ while (buf.getRoom() >= 2) {
+ tag = buf.readU8();
+ len = buf.readU8();
+ if (buf.getRoom() >= len) {
+ switch(tag) {
+ case NANOHUB_HAL_APP_INFO_CRC:
+ if (len == 0)
+ app->crc = 0;
+ else if (len == sizeof(app->crc))
+ app->crc = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_TID:
+ if (len == 0) {
+ app->tid = NANOHUB_TID_UNKNOWN;
+ ramUseValid = false;
+ app->loaded = true;
+ app->running = false;
+ } else if (len == sizeof(app->tid)) {
+ app->tid = buf.readU32();
+ app->loaded = true;
+ app->running = true;
+ } else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_VERSION:
+ if (len == sizeof(app->version))
+ app->version = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_ADDR:
+ if (len == sizeof(app->flashAddr))
+ app->flashAddr = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_SIZE:
+ if (len == 0)
+ app->flashUse = NANOHUB_MEM_SZ_UNKNOWN;
+ else if (len == sizeof(app->flashUse))
+ app->flashUse = buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_HEAP:
+ case NANOHUB_HAL_APP_INFO_DATA:
+ case NANOHUB_HAL_APP_INFO_BSS:
+ if (len == 0)
+ ramUseValid = false;
+ else if (len == sizeof(uint32_t))
+ ramUse += buf.readU32();
+ else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_CHRE_MAJOR:
+ if (len == 0)
+ app->chre = false;
+ else if (len == sizeof(app->chre_major)) {
+ app->chre = true;
+ app->chre_major = buf.readU8();
+ } else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_CHRE_MINOR:
+ if (len == 0)
+ app->chre = false;
+ else if (len == sizeof(app->chre_minor)) {
+ app->chre = true;
+ app->chre_minor = buf.readU8();
+ } else
+ buf.readRaw(len);
+ break;
+ case NANOHUB_HAL_APP_INFO_END:
+ if (len != 0 || buf.getRoom() != 0) {
+ ALOGE("%s: failed to read object", __func__);
+ return 0;
+ }
+ break;
+ default:
+ ALOGI("%s: unsupported tag: %d", __func__, tag);
+ buf.readRaw(len);
+ break;
+ }
+ } else {
+ ALOGE("%s: failed to read object", __func__);
+ return 0;
+ }
+ }
+
+ if (buf.getRoom() != 0) {
+ ALOGE("%s: failed to read object", __func__);
+ return 0;
+ }
+
+ if (ramUseValid)
+ app->ramUse = ramUse;
+ else
+ app->ramUse = NANOHUB_MEM_SZ_UNKNOWN;
+
+ return app->flashAddr +
+ (app->flashUse != NANOHUB_MEM_SZ_UNKNOWN ? ((app->flashUse+3)&~3) : 4);
+}
+
+void SystemComm::AppManager::sendAppInfoToApp(uint32_t transactionId) {
+ std::vector<hub_app_info> appInfo;
+ for (auto &it : apps_) {
+ uint64_t id = it.first;
+ const auto &app = it.second;
+
+ // TODO: Still have some non-chre apps that need to be reported
+ // if (!app->chre || !app->running || app->flashUse == NANOHUB_MEM_SZ_UNKNOWN)
+ if (!app->running || app->flashUse == NANOHUB_MEM_SZ_UNKNOWN)
+ continue;
+
+ hub_app_info info;
+ info.app_name = { .id = id };
+ info.version = app->version;
+ info.num_mem_ranges = 0;
+ if (app->flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
+ mem_range_t &range = info.mem_usage[info.num_mem_ranges++];
+ range.type = HUB_MEM_TYPE_MAIN;
+ range.total_bytes = app->flashUse;
+ }
+ if (app->ramUse != NANOHUB_MEM_SZ_UNKNOWN) {
+ mem_range_t &range = info.mem_usage[info.num_mem_ranges++];
+ range.type = HUB_MEM_TYPE_RAM;
+ range.total_bytes = app->ramUse;
+ }
+
+ appInfo.push_back(info);
+ }
+ sendToApp(CONTEXT_HUB_QUERY_APPS, transactionId,
+ static_cast<const void *>(appInfo.data()),
+ appInfo.size() * sizeof(appInfo[0]));
+}
+
+int SystemComm::AppManager::getAppsToStart(std::vector<hub_app_name_t> &apps)
+{
+ int cnt = 0;
+ apps.clear();
+
+ for (auto &it : apps_) {
+ uint64_t id = it.first;
+ const auto &app = it.second;
+
+ if (app->cached_napp && app->cached_start && app->loaded &&
+ !app->running && app->flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
+ apps.push_back({ .id = id });
+ cnt++;
+ }
+ }
+
+ return cnt;
+}
+
+int SystemComm::doHandleRx(uint64_t appId, uint32_t transactionId, const char *data, int len, bool chre)
+{
+ bool reboot = false;
+ uint32_t rebootStatus;
//we only care for messages from HostIF
if (appId != mHostIfAppName.id)
return 1;
@@ -580,20 +1379,36 @@ int SystemComm::doHandleRx(uint64_t appId, const char *data, int len)
}
MessageBuf buf(data, len);
if (NanoHub::messageTracingEnabled()) {
- dumpBuffer("SYS -> HAL", mHostIfAppName, 0, 0, buf.getData(), buf.getSize());
+ dumpBuffer("SYS -> HAL", mHostIfAppName, transactionId, 0, buf.getData(), buf.getSize());
}
- int status = mSessions.handleRx(buf);
+ int status = mSessions.handleRx(buf, transactionId, mAppManager, chre, reboot, rebootStatus);
if (status) {
// provide default handler for any system message, that is not properly handled
dumpBuffer(status > 0 ? "HAL (not handled)" : "HAL (error)",
- mHostIfAppName, 0, 0, buf.getData(), buf.getSize(), status);
+ mHostIfAppName, transactionId, 0, buf.getData(), buf.getSize(), status);
status = status > 0 ? 0 : status;
}
+ if (reboot) {
+ hub_message_t msg =
+ {
+ .app_name.id = appId,
+ .message_type = CONTEXT_HUB_START_APPS,
+ .message_len = sizeof(rebootStatus),
+ .message = &rebootStatus,
+ };
+
+ status = doHandleTx(&msg, 0xFFFFFFFF);
+ }
return status;
}
-int SystemComm::SessionManager::handleRx(MessageBuf &buf)
+void SystemComm::doDumpAppInfo(std::string &result)
+{
+ mAppManager.dumpAppInfo(result);
+}
+
+int SystemComm::SessionManager::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre, bool &reboot, uint32_t &rebootStatus)
{
int status = 1;
std::unique_lock<std::mutex> lk(lock);
@@ -605,36 +1420,40 @@ int SystemComm::SessionManager::handleRx(MessageBuf &buf)
continue;
}
Session *session = pos->second;
- status = session->handleRx(buf);
+ status = session->handleRx(buf, transactionId, appManager, chre);
if (status < 0) {
session->complete();
}
}
- NanohubRsp rsp(buf);
- if (rsp.cmd == NANOHUB_REBOOT) {
- // if this is reboot notification, kill all sessions
- for (auto pos = sessions_.begin(); pos != sessions_.end(); next(pos)) {
- if (!isActive(pos)) {
- continue;
+ NanohubRsp rsp(buf, transactionId, chre);
+ if (rsp.mCmd == NANOHUB_HAL_SYS_MGMT) {
+ uint8_t cmd = buf.readU8();
+
+ if (cmd == NANOHUB_HAL_SYS_MGMT_REBOOT) {
+ // if this is reboot notification, kill all sessions
+ for (auto pos = sessions_.begin(); pos != sessions_.end(); next(pos)) {
+ if (!isActive(pos)) {
+ continue;
+ }
+ Session *session = pos->second;
+ session->abort(-EINTR);
}
- Session *session = pos->second;
- session->abort(-EINTR);
- }
- lk.unlock();
- // log the reboot event, if not handled
- if (status > 0) {
- ALOGW("Nanohub reboot status [UNSOLICITED]: %08" PRIX32, rsp.status);
- status = 0;
+ lk.unlock();
+ // log the reboot event, if not handled
+ if (status > 0) {
+ ALOGW("Nanohub reboot status [UNSOLICITED]: %08" PRIX32, rsp.mStatus);
+ status = 0;
+ }
+ reboot = true;
+ rebootStatus = rsp.mStatus;
}
- // report to java apps
- sendToApp(CONTEXT_HUB_OS_REBOOT, &rsp.status, sizeof(rsp.status));
}
return status;
}
-int SystemComm::SessionManager::setup_and_add(int id, Session *session, const hub_message_t *appMsg)
+int SystemComm::SessionManager::setup_and_add(int id, Session *session, const hub_message_t *appMsg, uint32_t transactionId, AppManager &appManager)
{
std::lock_guard<std::mutex> _l(lock);
@@ -645,7 +1464,7 @@ int SystemComm::SessionManager::setup_and_add(int id, Session *session, const hu
if (sessions_.count(id) == 0 && !session->isRunning()) {
sessions_[id] = session;
- int ret = session->setup(appMsg);
+ int ret = session->setup(appMsg, transactionId, appManager);
if (ret < 0) {
session->complete();
}
@@ -654,14 +1473,14 @@ int SystemComm::SessionManager::setup_and_add(int id, Session *session, const hu
return -EBUSY;
}
-int SystemComm::doHandleTx(const hub_message_t *appMsg)
+int SystemComm::doHandleTx(const hub_message_t *appMsg, uint32_t transactionId)
{
int status = 0;
switch (appMsg->message_type) {
case CONTEXT_HUB_LOAD_APP:
if (!mKeySession.haveKeys()) {
- status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mKeySession, appMsg);
+ status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mKeySession, appMsg, transactionId, mAppManager);
if (status < 0) {
break;
}
@@ -671,21 +1490,25 @@ int SystemComm::doHandleTx(const hub_message_t *appMsg)
break;
}
}
- status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg);
+ status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg, transactionId, mAppManager);
break;
case CONTEXT_HUB_APPS_ENABLE:
case CONTEXT_HUB_APPS_DISABLE:
case CONTEXT_HUB_UNLOAD_APP:
// all APP-modifying commands share session key, to ensure they can't happen at the same time
- status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg);
+ status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg, transactionId, mAppManager);
break;
case CONTEXT_HUB_QUERY_APPS:
- status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_APPS, &mAppInfoSession, appMsg);
+ mAppManager.sendAppInfoToApp(transactionId);
break;
case CONTEXT_HUB_QUERY_MEMORY:
- status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_MEMORY, &mMemInfoSession, appMsg);
+ status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_MEMORY, &mMemInfoSession, appMsg, transactionId, mAppManager);
+ break;
+
+ case CONTEXT_HUB_START_APPS:
+ status = mSessions.setup_and_add(CONTEXT_HUB_START_APPS, &mAppMgmtSession, appMsg, transactionId, mAppManager);
break;
default:
diff --git a/contexthubhal/system_comms.h b/contexthubhal/system_comms.h
index cf388747..46ee944e 100644
--- a/contexthubhal/system_comms.h
+++ b/contexthubhal/system_comms.h
@@ -36,22 +36,66 @@
#define MSG_HANDLED 0
//messages to the HostIf nanoapp & their replies (mesages and replies both begin with u8 message_type)
-#define NANOHUB_EXT_APPS_ON 0 // () -> (char success)
-#define NANOHUB_EXT_APPS_OFF 1 // () -> (char success)
-#define NANOHUB_EXT_APP_DELETE 2 // (u64 name) -> (char success) //idempotent
-#define NANOHUB_QUERY_MEMINFO 3 // () -> (mem_info)
-#define NANOHUB_QUERY_APPS 4 // (u32 idxStart) -> (app_info[idxStart] OR EMPTY IF NO MORE)
-#define NANOHUB_QUERY_RSA_KEYS 5 // (u32 byteOffset) -> (u8 data[1 or more bytes] OR EMPTY IF NO MORE)
-#define NANOHUB_START_UPLOAD 6 // (char isOs, u32 totalLenToTx) -> (char success)
-#define NANOHUB_CONT_UPLOAD 7 // (u32 offset, u8 data[]) -> (char success)
-#define NANOHUB_FINISH_UPLOAD 8 // () -> (char success)
-#define NANOHUB_REBOOT 9 // () -> (char success)
+#define NANOHUB_HAL_APP_MGMT 0x10 // (char cmd, u64 appId, u64 appMsk) -> (int errno, u32 results)
+
+#define NANOHUB_HAL_APP_MGMT_START 0
+#define NANOHUB_HAL_APP_MGMT_STOP 1
+#define NANOHUB_HAL_APP_MGMT_UNLOAD 2
+#define NANOHUB_HAL_APP_MGMT_DELETE 3
+
+#define NANOHUB_HAL_SYS_MGMT 0x11 // (char cmd) -> (int errno)
+
+#define NANOHUB_HAL_SYS_MGMT_ERASE 0
+#define NANOHUB_HAL_SYS_MGMT_REBOOT 1
+
+#define NANOHUB_HAL_APP_INFO 0x12
+
+#define NANOHUB_HAL_APP_INFO_APPID 0x00
+#define NANOHUB_HAL_APP_INFO_CRC 0x01
+#define NANOHUB_HAL_APP_INFO_TID 0x02
+#define NANOHUB_HAL_APP_INFO_VERSION 0x03
+#define NANOHUB_HAL_APP_INFO_ADDR 0x04
+#define NANOHUB_HAL_APP_INFO_SIZE 0x05
+#define NANOHUB_HAL_APP_INFO_HEAP 0x06
+#define NANOHUB_HAL_APP_INFO_DATA 0x07
+#define NANOHUB_HAL_APP_INFO_BSS 0x08
+#define NANOHUB_HAL_APP_INFO_CHRE_MAJOR 0x09
+#define NANOHUB_HAL_APP_INFO_CHRE_MINOR 0x0A
+#define NANOHUB_HAL_APP_INFO_END 0xFF
+
+#define NANOHUB_HAL_SYS_INFO 0x13
+
+#define NANOHUB_HAL_SYS_INFO_HEAP_FREE 0x0F
+#define NANOHUB_HAL_SYS_INFO_RAM_SIZE 0x12
+#define NANOHUB_HAL_SYS_INFO_EEDATA_SIZE 0x13
+#define NANOHUB_HAL_SYS_INFO_EEDATA_FREE 0x14
+#define NANOHUB_HAL_SYS_INFO_CODE_SIZE 0x15
+#define NANOHUB_HAL_SYS_INFO_CODE_FREE 0x16
+#define NANOHUB_HAL_SYS_INFO_SHARED_SIZE 0x17
+#define NANOHUB_HAL_SYS_INFO_SHARED_FREE 0x18
+#define NANOHUB_HAL_SYS_INFO_END 0xFF
+
+#define NANOHUB_HAL_KEY_INFO 0x14
+#define NANOHUB_HAL_START_UPLOAD 0x16
+#define NANOHUB_HAL_CONT_UPLOAD 0x17
+#define NANOHUB_HAL_FINISH_UPLOAD 0x18
+
+#define NANOHUB_HAL_UPLOAD_ACCEPTED 0
+#define NANOHUB_HAL_UPLOAD_WAIT 1
+#define NANOHUB_HAL_UPLOAD_RESEND 2
+#define NANOHUB_HAL_UPLOAD_RESTART 3
+#define NANOHUB_HAL_UPLOAD_CANCEL 4
+#define NANOHUB_HAL_UPLOAD_CANCEL_NO_RETRY 5
+#define NANOHUB_HAL_UPLOAD_NO_SPACE 6
#define NANOHUB_APP_NOT_LOADED (-1)
#define NANOHUB_APP_LOADED (0)
#define NANOHUB_UPLOAD_CHUNK_SZ_MAX 64
#define NANOHUB_MEM_SZ_UNKNOWN 0xFFFFFFFFUL
+#define NANOHUB_TID_UNKNOWN 0xFFFFFFFFUL
+
+#define CONTEXT_HUB_START_APPS 8
namespace android {
@@ -60,11 +104,6 @@ namespace nanohub {
int system_comms_handle_rx(const nano_message_raw *msg);
int system_comms_handle_tx(const hub_message_t *outMsg);
-struct NanohubAppInfo {
- hub_app_name_t name;
- uint32_t version, flashUse, ramUse;
-} __attribute__((packed));
-
struct MgmtStatus {
union {
uint32_t value;
@@ -88,9 +127,10 @@ struct NanohubMemInfo {
} __attribute__((packed));
struct NanohubRsp {
- uint32_t cmd;
- int32_t status;
- explicit NanohubRsp(MessageBuf &buf, bool no_status = false);
+ uint32_t mCmd;
+ uint32_t mTransactionId;
+ int32_t mStatus;
+ explicit NanohubRsp(MessageBuf &buf, uint32_t transactionId, bool chre);
};
inline bool operator == (const hub_app_name_t &a, const hub_app_name_t &b) {
@@ -104,6 +144,8 @@ inline bool operator != (const hub_app_name_t &a, const hub_app_name_t &b) {
class SystemComm {
private:
+ class AppManager;
+
/*
* Nanohub HAL sessions
*
@@ -118,8 +160,8 @@ private:
*/
class ISession {
public:
- virtual int setup(const hub_message_t *app_msg) = 0;
- virtual int handleRx(MessageBuf &buf) = 0;
+ virtual int setup(const hub_message_t *app_msg, uint32_t transactionId, AppManager &appManager) = 0;
+ virtual int handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre) = 0;
virtual int getState() const = 0; // FSM state
virtual int getStatus() const = 0; // execution status (result code)
virtual void abort(int32_t) = 0;
@@ -199,11 +241,17 @@ private:
class AppMgmtSession : public Session {
enum {
TRANSFER = SESSION_USER,
+ QUERY_START,
+ START,
+ STOP_TRANSFER,
FINISH,
RUN,
+ STOP_RUN,
RUN_FAILED,
REBOOT,
+ ERASE_TRANSFER,
MGMT,
+ INFO,
};
uint32_t mCmd; // LOAD_APP, UNLOAD_APP, ENABLE_APP, DISABLE_APP
uint32_t mResult;
@@ -213,14 +261,21 @@ private:
uint32_t mNextPos;
uint32_t mErrCnt;
hub_app_name_t mAppName;
-
- int setupMgmt(const hub_message_t *appMsg, uint32_t cmd);
- int handleTransfer(NanohubRsp &rsp);
- int handleFinish(NanohubRsp &rsp);
- int handleRun(NanohubRsp &rsp);
- int handleRunFailed(NanohubRsp &rsp);
- int handleReboot(NanohubRsp &rsp);
- int handleMgmt(NanohubRsp &rsp);
+ uint32_t mFlashAddr;
+ std::vector<hub_app_name_t> mAppList;
+
+ int setupMgmt(const hub_message_t *appMsg, uint32_t transactionId, uint32_t cmd, AppManager &appManager);
+ int handleTransfer(NanohubRsp &rsp, MessageBuf &, AppManager &appManager);
+ int handleStopTransfer(NanohubRsp &rsp, MessageBuf &buf, AppManager &);
+ int handleQueryStart(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager);
+ int handleStart(NanohubRsp &rsp, MessageBuf &buf, AppManager &);
+ int handleFinish(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager);
+ int handleRun(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager);
+ int handleStopRun(NanohubRsp &rsp, MessageBuf &buf, AppManager &);
+ int handleReboot(NanohubRsp &rsp, MessageBuf &buf, AppManager &);
+ int handleEraseTransfer(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager);
+ int handleMgmt(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager);
+ int handleInfo(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager);
public:
AppMgmtSession() {
mCmd = 0;
@@ -229,34 +284,133 @@ private:
mLen = 0;
memset(&mAppName, 0, sizeof(mAppName));
}
- virtual int handleRx(MessageBuf &buf) override;
- virtual int setup(const hub_message_t *app_msg) override;
+ virtual int handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre) override;
+ virtual int setup(const hub_message_t *app_msg, uint32_t transactionId, AppManager &appManager) override;
};
class MemInfoSession : public Session {
public:
- virtual int setup(const hub_message_t *app_msg) override;
- virtual int handleRx(MessageBuf &buf) override;
+ virtual int setup(const hub_message_t *app_msg, uint32_t transactionId, AppManager &) override;
+ virtual int handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &, bool chre) override;
};
class KeyInfoSession : public Session {
std::vector<uint8_t> mRsaKeyData;
- int requestRsaKeys(void);
+ uint32_t mKeyNum;
+ uint32_t mKeyOffset;
+ int requestRsaKeys(uint32_t transactionId);
public:
- virtual int setup(const hub_message_t *) override;
- virtual int handleRx(MessageBuf &buf) override;
+ virtual int setup(const hub_message_t *, uint32_t, AppManager &) override;
+ virtual int handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &, bool chre) override;
bool haveKeys() const {
std::lock_guard<std::mutex> _l(mLock);
return mRsaKeyData.size() > 0 && !isRunning();
}
};
- class AppInfoSession : public Session {
- std::vector<hub_app_info> mAppInfo;
- int requestNext();
+ class AppManager {
+ struct AppData {
+ uint32_t version, flashUse, ramUse;
+ uint32_t tid, crc, flashAddr;
+ uint8_t chre_major, chre_minor;
+ bool chre, running, loaded;
+
+ bool cached_start, cached_napp;
+ uint32_t cached_version, cached_crc;
+ };
+
+ typedef std::map<uint64_t, std::unique_ptr<AppData>> AppMap;
+
+ AppMap apps_;
+
public:
- virtual int setup(const hub_message_t *) override;
- virtual int handleRx(MessageBuf &buf) override;
+ AppManager() {
+ restoreApps();
+ }
+ void dumpAppInfo(std::string &result);
+ bool saveApps();
+ bool restoreApps();
+ bool eraseApps();
+ bool writeApp(hub_app_name_t &appName, const uint8_t *data, int32_t len);
+ int32_t readApp(hub_app_name_t &appName, void **data);
+ bool cmpApp(hub_app_name_t &appName, const uint8_t *data, uint32_t len);
+ uint32_t readNanohubAppInfo(MessageBuf &buf);
+ void sendAppInfoToApp(uint32_t transactionId);
+ int getAppsToStart(std::vector<hub_app_name_t> &apps);
+ bool setCachedCrc(hub_app_name_t &appName, uint32_t crc) {
+ if (!isAppPresent(appName))
+ return false;
+ else {
+ apps_[appName.id]->cached_napp = true;
+ apps_[appName.id]->cached_crc = crc;
+ apps_[appName.id]->cached_start = false;
+ saveApps();
+ return true;
+ }
+ }
+ bool clearCachedApp(hub_app_name_t &appName) {
+ if (!isAppPresent(appName))
+ return false;
+ else {
+ apps_[appName.id]->cached_napp = false;
+ apps_[appName.id]->cached_start = false;
+ saveApps();
+ return true;
+ }
+ }
+ bool clearRunning(hub_app_name_t &appName) {
+ if (!isAppLoaded(appName))
+ return false;
+ else {
+ apps_[appName.id]->running = false;
+ return true;
+ }
+ }
+
+ bool setCachedVersion(hub_app_name_t &appName, uint32_t version) {
+ if (!isAppPresent(appName))
+ return false;
+ else {
+ apps_[appName.id]->cached_version = version;
+ return true;
+ }
+ }
+ bool setCachedStart(hub_app_name_t &appName, bool start) {
+ if (!isAppPresent(appName))
+ return false;
+ else {
+ apps_[appName.id]->cached_start = start;
+ saveApps();
+ return true;
+ }
+ }
+ bool addNewApp(hub_app_name_t &appName, uint32_t version) {
+ if (isAppLoaded(appName))
+ return false;
+ else
+ apps_[appName.id] = std::unique_ptr<AppData>(new AppData);
+ apps_[appName.id]->loaded = false;
+ apps_[appName.id]->running = false;
+ apps_[appName.id]->chre = false;
+ apps_[appName.id]->cached_napp = false;
+ apps_[appName.id]->cached_version = version;
+ return true;
+ }
+ bool isAppPresent(hub_app_name_t &appName) {
+ return apps_.count(appName.id) != 0;
+ }
+ bool isAppLoaded(hub_app_name_t &appName) {
+ return apps_.count(appName.id) != 0 && apps_[appName.id]->loaded;
+ }
+ bool isAppRunning(hub_app_name_t &appName) {
+ return apps_.count(appName.id) != 0 && apps_[appName.id]->running;
+ }
+ uint32_t getFlashAddr(hub_app_name_t &appName) {
+ if (isAppPresent(appName))
+ return apps_[appName.id]->flashAddr;
+ else
+ return 0xFFFFFFFF;
+ }
};
class SessionManager {
@@ -275,8 +429,8 @@ private:
}
public:
- int handleRx(MessageBuf &buf);
- int setup_and_add(int id, Session *session, const hub_message_t *appMsg);
+ int handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre, bool &reboot, uint32_t &rebootStatus);
+ int setup_and_add(int id, Session *session, const hub_message_t *appMsg, uint32_t transactionId, AppManager &appManager);
} mSessions;
const hub_app_name_t mHostIfAppName = {
@@ -292,33 +446,34 @@ private:
SystemComm () = default;
~SystemComm() = default;
- int doHandleTx(const hub_message_t *txMsg);
- int doHandleRx(uint64_t appId, const char *data, int len);
+ int doHandleTx(const hub_message_t *txMsg, uint32_t transactionId);
+ int doHandleRx(uint64_t appId, uint32_t transactionId, const char *data, int len, bool chre);
+ void doDumpAppInfo(std::string &result);
int doHandleRx(const nano_message_raw *rxMsg) {
- return doHandleRx(rxMsg->hdr.appId, reinterpret_cast<const char*>(rxMsg->data), rxMsg->hdr.len);
+ return doHandleRx(rxMsg->hdr.appId, 0, reinterpret_cast<const char*>(rxMsg->data), rxMsg->hdr.len, false);
}
int doHandleRx(const nano_message_chre *rxMsg) {
- return doHandleRx(rxMsg->hdr.appId, reinterpret_cast<const char*>(rxMsg->data), rxMsg->hdr.len);
+ return doHandleRx(rxMsg->hdr.appId, rxMsg->hdr.appEventId, reinterpret_cast<const char*>(rxMsg->data), rxMsg->hdr.len, true);
}
- static void sendToApp(uint32_t typ, const void *data, uint32_t len) {
+ static void sendToApp(uint32_t typ, uint32_t transactionId, const void *data, uint32_t len) {
if (NanoHub::messageTracingEnabled()) {
- dumpBuffer("HAL -> APP", get_hub_info()->os_app_name, typ, 0, data, len);
+ dumpBuffer("HAL -> APP", get_hub_info()->os_app_name, transactionId, 0, data, len);
}
- NanoHub::sendToApp(HubMessage(&get_hub_info()->os_app_name, typ, ENDPOINT_BROADCAST, data, len));
+ NanoHub::sendToApp(HubMessage(&get_hub_info()->os_app_name, typ, transactionId, ENDPOINT_BROADCAST, data, len));
}
- static int sendToSystem(const void *data, size_t len);
+ static int sendToSystem(const void *data, size_t len, uint32_t transactionId);
KeyInfoSession mKeySession;
AppMgmtSession mAppMgmtSession;
- AppInfoSession mAppInfoSession;
MemInfoSession mMemInfoSession;
+ AppManager mAppManager;
public:
- static int handleTx(const hub_message_t *txMsg) {
- return getSystem()->doHandleTx(txMsg);
+ static int handleTx(const hub_message_t *txMsg, uint32_t transactionId) {
+ return getSystem()->doHandleTx(txMsg, transactionId);
}
static int handleRx(const nano_message_raw *rxMsg) {
return getSystem()->doHandleRx(rxMsg);
@@ -326,6 +481,9 @@ public:
static int handleRx(const nano_message_chre *rxMsg) {
return getSystem()->doHandleRx(rxMsg);
}
+ static void dumpAppInfo(std::string &result) {
+ return getSystem()->doDumpAppInfo(result);
+ }
};
}; // namespace nanohub
diff --git a/util/common/Android.bp b/util/common/Android.bp
new file mode 100644
index 00000000..ac6d65d2
--- /dev/null
+++ b/util/common/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+cc_library_static {
+ name: "libhubutilcommon",
+ srcs: [
+ "file.cpp",
+ "JSONObject.cpp",
+ "ring.cpp",
+ ],
+ cflags: ["-Wall", "-Werror", "-Wextra"],
+ header_libs: [
+ "libhardware_headers",
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
+ "libutils_headers",
+ ],
+ export_header_lib_headers: [
+ "libhardware_headers",
+ "libutils_headers",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+ proprietary: true,
+}
diff --git a/util/common/Android.mk b/util/common/Android.mk
deleted file mode 100644
index 62898394..00000000
--- a/util/common/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-COMMON_CFLAGS := -Wall -Werror -Wextra
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libhubutilcommon
-LOCAL_MODULE_TAGS := optional
-LOCAL_PROPRIETARY_MODULE := true
-
-LOCAL_CFLAGS += $(COMMON_CFLAGS)
-
-LOCAL_C_INCLUDES += \
- $(LOCAL_PATH)
-
-LOCAL_SRC_FILES := \
- file.cpp \
- JSONObject.cpp \
- ring.cpp
-
-LOCAL_HEADER_LIBRARIES := \
- libhardware_headers \
- libstagefright_foundation_headers \
- libstagefright_headers \
- libutils_headers
-
-LOCAL_EXPORT_HEADER_LIBRARY_HEADERS := \
- libhardware_headers \
- libutils_headers
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_C_INCLUDES)
-
-include $(BUILD_STATIC_LIBRARY)