nanohub HAL: load nanoapp without nanohub reboot
send ENABLE_APP instead of REBOOT; as a side effect
we should now return failure in case app_init() method failed
fix couple logging issues and incorrect response handlings.
Test: execute the sequence below
Note: this requires that Nanohub OS image is built with the following
https://googleplex-android-review.git.corp.google.com/#/c/1503793/
and uploaded to context hub MCU.
As of this moment, this change is source-merged, but binary OS image is
not in sync with it.
With updated OS, execute:
adb shell 'echo 1 > /sys/class/nanohub/nanohub/erase_shared'
adb shell nanoapp_cmd download
adb shell 'echo 1 > /sys/class/nanohub/nanohub/reset'
gts-tradefed run everything --skip-system-status-check
com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker
--module GtsLocationTestCases --test
com.google.android.location.gts.ContextHubHelloWorldNanoAppTest#runTest
--primary-abi-only
gts-tradefed run everything --skip-system-status-check
com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker
--module GtsLocationTestCases --test
com.google.android.location.gts.ContextHubTrivialNanoAppsTest
--primary-abi-only
Bug: 31038843
Bug: 31360590
Change-Id: If0dfe75f7cfa8ddeeabfc6ae124aa4cd155a30a8
Signed-off-by: Alexey Polyudov <apolyudov@google.com>
diff --git a/contexthubhal/system_comms.cpp b/contexthubhal/system_comms.cpp
index 840607a..c4e9b62 100644
--- a/contexthubhal/system_comms.cpp
+++ b/contexthubhal/system_comms.cpp
@@ -281,16 +281,23 @@
return setupMgmt(appMsg, NANOHUB_EXT_APPS_OFF);
case CONTEXT_HUB_UNLOAD_APP:
return setupMgmt(appMsg, NANOHUB_EXT_APP_DELETE);
- case CONTEXT_HUB_LOAD_OS:
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(mCmd == CONTEXT_HUB_LOAD_OS ? 1 : 0);
+ buf.writeU8(0);
buf.writeU32(mLen);
return sendToSystem(buf.getData(), buf.getPos());
+ }
case CONTEXT_HUB_OS_REBOOT:
setState(REBOOT);
@@ -330,8 +337,11 @@
case FINISH:
ret = handleFinish(rsp);
break;
- case RELOAD:
- ret = handleReload(rsp);
+ case RUN:
+ ret = handleRun(rsp);
+ break;
+ case RUN_FAILED:
+ ret = handleRunFailed(rsp);
break;
case REBOOT:
ret = handleReboot(rsp);
@@ -386,9 +396,9 @@
if (success) {
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
- // until app header is passed, we don't know who to start, so we reboot
- buf.writeU8(NANOHUB_REBOOT);
- setState(RELOAD);
+ buf.writeU8(NANOHUB_EXT_APPS_ON);
+ writeAppName(buf, mAppName);
+ setState(RUN);
ret = sendToSystem(buf.getData(), buf.getPos());
} else {
int32_t result = NANOHUB_APP_NOT_LOADED;
@@ -400,15 +410,48 @@
return ret;
}
-/* reboot notification, when triggered as part of App reload sequence */
-int SystemComm::AppMgmtSession::handleReload(NanohubRsp &rsp)
+int SystemComm::AppMgmtSession::handleRun(NanohubRsp &rsp)
{
- int32_t result = NANOHUB_APP_LOADED;
+ if (rsp.cmd != NANOHUB_EXT_APPS_ON)
+ return 1;
- ALOGI("Nanohub reboot status [NEW APP START]: %08" PRIX32, rsp.status);
+ MgmtStatus sts = { .value = (uint32_t)rsp.status };
+
+ // 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;
+
+ ALOGI("Nanohub NEW APP START: %08" PRIX32 "\n", rsp.status);
+ if (result != 0) {
+ // if nanoapp failed to start we have to unload it
+ char data[MAX_RX_PACKET];
+ MessageBuf buf(data, sizeof(data));
+ buf.writeU8(NANOHUB_EXT_APP_DELETE);
+ 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__);
+ }
+
+ // 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));
+ complete();
+ return 0;
+}
+
+int SystemComm::AppMgmtSession::handleRunFailed(NanohubRsp &rsp)
+{
+ if (rsp.cmd != NANOHUB_EXT_APP_DELETE)
+ return 1;
+
+ int32_t result = -1;
+
+ ALOGI("%s: APP DELETE [because it failed]: %08" PRIX32 "\n", __func__, rsp.status);
sendToApp(mCmd, &result, sizeof(result));
-
complete();
return 0;
@@ -417,7 +460,9 @@
/* reboot notification, when triggered by App request */
int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp)
{
- ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32, rsp.status);
+ if (rsp.cmd != NANOHUB_REBOOT)
+ return 1;
+ ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32 "\n", rsp.status);
// reboot notification is sent by SessionManager
complete();
@@ -429,7 +474,6 @@
{
bool valid = false;
- ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.cmd, rsp.status);
int32_t result = rsp.status;
// TODO: remove this when context hub service can handle non-zero success status
@@ -455,6 +499,7 @@
return 1;
}
+ ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.cmd, rsp.status);
if (!valid) {
ALOGE("Invalid response for this state: APP CMD=%02X", mCmd);
return -EINVAL;
diff --git a/contexthubhal/system_comms.h b/contexthubhal/system_comms.h
index 256c8d4..e1b08e3 100644
--- a/contexthubhal/system_comms.h
+++ b/contexthubhal/system_comms.h
@@ -46,10 +46,6 @@
#define NANOHUB_FINISH_UPLOAD 8 // () -> (char success)
#define NANOHUB_REBOOT 9 // () -> (char success)
-// Custom defined private messages
-#define CONTEXT_HUB_LOAD_OS (CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE + 1)
-
-
#define NANOHUB_APP_NOT_LOADED (-1)
#define NANOHUB_APP_LOADED (0)
@@ -68,6 +64,18 @@
uint32_t version, flashUse, ramUse;
} __attribute__((packed));
+struct MgmtStatus {
+ union {
+ uint32_t value;
+ struct {
+ uint8_t app;
+ uint8_t task;
+ uint8_t op;
+ uint8_t erase;
+ } __attribute__((packed));
+ };
+} __attribute__((packed));
+
struct NanohubMemInfo {
//sizes
uint32_t flashSz, blSz, osSz, sharedSz, eeSz;
@@ -186,20 +194,23 @@
enum {
TRANSFER = SESSION_USER,
FINISH,
- RELOAD,
+ RUN,
+ RUN_FAILED,
REBOOT,
MGMT,
};
- uint32_t mCmd; // UPLOAD_APP | UPPLOAD_OS
+ uint32_t mCmd; // LOAD_APP, UNLOAD_APP, ENABLE_APP, DISABLE_APP
uint32_t mResult;
std::vector<uint8_t> mData;
uint32_t mLen;
uint32_t mPos;
+ hub_app_name_t mAppName;
int setupMgmt(const hub_message_t *appMsg, uint32_t cmd);
int handleTransfer(NanohubRsp &rsp);
int handleFinish(NanohubRsp &rsp);
- int handleReload(NanohubRsp &rsp);
+ int handleRun(NanohubRsp &rsp);
+ int handleRunFailed(NanohubRsp &rsp);
int handleReboot(NanohubRsp &rsp);
int handleMgmt(NanohubRsp &rsp);
public:
@@ -208,6 +219,7 @@
mResult = 0;
mPos = 0;
mLen = 0;
+ memset(&mAppName, 0, sizeof(mAppName));
}
virtual int handleRx(MessageBuf &buf) override;
virtual int setup(const hub_message_t *app_msg) override;