summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-01-10 08:28:21 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-01-10 08:28:21 +0000
commit0a8d740c57c0184f62010517e42afbe5098b5e49 (patch)
treef6e414f37719f0862d09a6286382be07bb02122f
parent3a3c2379279ebb8250d4093c46e65a9fe8967978 (diff)
parentf378cb36e45cbfd402a26982a284dbd2933d5ef8 (diff)
downloaddevice_google_contexthub-0a8d740c57c0184f62010517e42afbe5098b5e49.tar.gz
device_google_contexthub-0a8d740c57c0184f62010517e42afbe5098b5e49.tar.bz2
device_google_contexthub-0a8d740c57c0184f62010517e42afbe5098b5e49.zip
Snap for 4535700 from f378cb36e45cbfd402a26982a284dbd2933d5ef8 to pi-release
Change-Id: I956168686270e297ae43480a4f722498ddc7bd33
-rw-r--r--contexthubhal/Android.bp57
-rw-r--r--contexthubhal/NanohubHidlAdapter.cpp542
-rw-r--r--contexthubhal/NanohubHidlAdapter.h131
-rw-r--r--contexthubhal/android.hardware.contexthub@1.0-service.nanohub.rc4
-rw-r--r--contexthubhal/legacyhal.cpp63
-rw-r--r--contexthubhal/nanohubhal.cpp32
-rw-r--r--contexthubhal/nanohubhal.h16
-rw-r--r--contexthubhal/service.cpp44
-rw-r--r--firmware/os/core/nanohubCommand.c4
9 files changed, 857 insertions, 36 deletions
diff --git a/contexthubhal/Android.bp b/contexthubhal/Android.bp
index 6f397458..93c8dcb2 100644
--- a/contexthubhal/Android.bp
+++ b/contexthubhal/Android.bp
@@ -19,6 +19,7 @@ cc_library {
"nanohubhal.cpp",
"system_comms.cpp",
"nanohubhal_default.cpp",
+ "legacyhal.cpp",
],
cflags: ["-Wall", "-Werror", "-Wextra"],
shared_libs: [
@@ -32,3 +33,59 @@ cc_library {
],
proprietary: true,
}
+
+cc_library_shared {
+ name: "android.hardware.contexthub@1.0-impl.nanohub",
+ proprietary: true,
+ relative_install_path: "hw",
+ 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_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",
+ ],
+ proprietary: true,
+}
diff --git a/contexthubhal/NanohubHidlAdapter.cpp b/contexthubhal/NanohubHidlAdapter.cpp
new file mode 100644
index 00000000..a6a471a4
--- /dev/null
+++ b/contexthubhal/NanohubHidlAdapter.cpp
@@ -0,0 +1,542 @@
+/*
+ * 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.
+ */
+
+ /*
+ * This file is based on:
+ * hardware/interfaces/contexthub/1.0/default/Contexthub.cpp
+ * with modifications to connect directly to the NanohubHAL and
+ * support endpoints.
+ */
+
+#include "NanohubHidlAdapter.h"
+#include "nanohub_perdevice.h"
+
+#include <inttypes.h>
+
+#include <log/log.h>
+#include <utils/String8.h>
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+#include <sys/endian.h>
+
+#undef LOG_TAG
+#define LOG_TAG "NanohubHidlAdapter"
+
+using namespace android::nanohub;
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);
+
+Contexthub::Contexthub()
+ : mDeathRecipient(new DeathRecipient(this)),
+ mIsTransactionPending(false) {
+}
+
+bool Contexthub::setOsAppAsDestination(hub_message_t *msg, int hubId) {
+ if (!isValidHubId(hubId)) {
+ ALOGW("%s: Hub information is null for hubHandle %d",
+ __FUNCTION__,
+ hubId);
+ return false;
+ } else {
+ msg->app_name = mCachedHubInfo[hubId].osAppName;
+ return true;
+ }
+}
+
+Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
+ std::vector<ContextHub> hubs;
+ const context_hub_t *hub = nanohub::get_hub_info();
+
+ mCachedHubInfo.clear();
+
+ CachedHubInformation info;
+ ContextHub c;
+
+ c.name = hub->name;
+ c.vendor = hub->vendor;
+ c.toolchain = hub->toolchain;
+ c.platformVersion = hub->platform_version;
+ c.toolchainVersion = hub->toolchain_version;
+ c.hubId = hub->hub_id;
+ c.peakMips = hub->peak_mips;
+ c.stoppedPowerDrawMw = hub->stopped_power_draw_mw;
+ c.sleepPowerDrawMw = hub->sleep_power_draw_mw;
+ c.peakPowerDrawMw = hub->peak_power_draw_mw;
+ // c.connectedSensors =
+ c.maxSupportedMsgLen = hub->max_supported_msg_len;
+ // TODO: get this information from nanohub
+ c.chrePlatformId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
+ c.chreApiMajorVersion = 0x01;
+ c.chreApiMinorVersion = 0x02;
+ c.chrePatchVersion = NANOHUB_OS_PATCH_LEVEL;
+
+ info.callback = nullptr;
+ info.osAppName = hub->os_app_name;
+ mCachedHubInfo[hub->hub_id] = info;
+
+ hubs.push_back(c);
+
+ _hidl_cb(hubs);
+ return Void();
+}
+
+Contexthub::DeathRecipient::DeathRecipient(sp<Contexthub> contexthub)
+ : mContexthub(contexthub) {}
+
+void Contexthub::DeathRecipient::serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+ uint32_t hubId = static_cast<uint32_t>(cookie);
+ mContexthub->handleServiceDeath(hubId);
+}
+
+bool Contexthub::isValidHubId(uint32_t hubId) {
+ if (!mCachedHubInfo.count(hubId)) {
+ ALOGW("Hub information not found for hubId %" PRIu32, hubId);
+ return false;
+ } else {
+ return true;
+ }
+}
+
+sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) {
+ if (!isValidHubId(hubId)) {
+ return nullptr;
+ } else {
+ return mCachedHubInfo[hubId].callback;
+ }
+}
+
+Return<Result> Contexthub::sendMessageToHub(uint32_t hubId,
+ const ContextHubMsg &msg) {
+ if (!isValidHubId(hubId) || msg.msg.size() > UINT32_MAX) {
+ return Result::BAD_PARAMS;
+ }
+
+ hub_message_t txMsg = {
+ .app_name.id = msg.appName,
+ .message_type = msg.msgType,
+ .message_len = static_cast<uint32_t>(msg.msg.size()), // Note the check above
+ .message = static_cast<const uint8_t *>(msg.msg.data()),
+ };
+
+ // Use a dummy to prevent send_message with empty message from failing prematurely
+ static uint8_t dummy;
+ if (txMsg.message_len == 0 && txMsg.message == nullptr) {
+ txMsg.message = &dummy;
+ }
+
+ ALOGI("Sending msg of type %" PRIu32 ", size %" PRIu32 " to app 0x%" PRIx64,
+ txMsg.message_type,
+ txMsg.message_len,
+ txMsg.app_name.id);
+
+ if(NanoHub::sendToNanohub(hubId, &txMsg, msg.hostEndPoint) != 0) {
+ return Result::TRANSACTION_FAILED;
+ }
+
+ return Result::OK;
+}
+
+Return<Result> Contexthub::registerCallback(uint32_t hubId,
+ const sp<IContexthubCallback> &cb) {
+ Return<Result> retVal = Result::BAD_PARAMS;
+
+ if (!isValidHubId(hubId)) {
+ // Initialized, but hubId is not valid
+ retVal = Result::BAD_PARAMS;
+ } else if (NanoHub::subscribeMessages(hubId,
+ contextHubCb,
+ this) == 0) {
+ // Initialized && valid hub && subscription successful
+ if (mCachedHubInfo[hubId].callback != nullptr) {
+ ALOGD("Modifying callback for hubId %" PRIu32, hubId);
+ mCachedHubInfo[hubId].callback->unlinkToDeath(mDeathRecipient);
+ }
+
+ mCachedHubInfo[hubId].callback = cb;
+ if (cb != nullptr) {
+ Return<bool> linkResult = cb->linkToDeath(mDeathRecipient, hubId);
+ bool linkSuccess = linkResult.isOk() ?
+ static_cast<bool>(linkResult) : false;
+ if (!linkSuccess) {
+ ALOGW("Couldn't link death recipient for hubId %" PRIu32,
+ hubId);
+ }
+ }
+ retVal = Result::OK;
+ } else {
+ // Initalized && valid hubId - but subscription unsuccessful
+ // This is likely an internal error in the HAL implementation, but we
+ // cannot add more information.
+ ALOGW("Could not subscribe to the hub for callback");
+ retVal = Result::UNKNOWN_FAILURE;
+ }
+
+ return retVal;
+}
+
+static bool isValidOsStatus(const uint8_t *msg,
+ size_t msgLen,
+ status_response_t *rsp) {
+ // Workaround a bug in some HALs
+ if (msgLen == 1) {
+ rsp->result = msg[0];
+ return true;
+ }
+
+ if (msg == nullptr || msgLen != sizeof(*rsp)) {
+ ALOGI("Received invalid response (is null : %d, size %zu)",
+ msg == nullptr ? 1 : 0,
+ msgLen);
+ return false;
+ }
+
+ memcpy(rsp, msg, sizeof(*rsp));
+
+ // No sanity checks on return values
+ return true;
+}
+
+int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
+ uint32_t msgType,
+ const uint8_t *msg,
+ int msgLen) {
+ int retVal = -1;
+
+
+ switch(msgType) {
+ case CONTEXT_HUB_APPS_ENABLE:
+ case CONTEXT_HUB_APPS_DISABLE:
+ case CONTEXT_HUB_LOAD_APP:
+ case CONTEXT_HUB_UNLOAD_APP:
+ {
+ struct status_response_t rsp;
+ TransactionResult result;
+ if (isValidOsStatus(msg, msgLen, &rsp) && rsp.result == 0) {
+ retVal = 0;
+ result = TransactionResult::SUCCESS;
+ } else {
+ result = TransactionResult::FAILURE;
+ }
+
+ mIsTransactionPending = false;
+ if (cb != nullptr) {
+ cb->handleTxnResult(mTransactionId, result);
+ }
+ retVal = 0;
+ break;
+ }
+
+ case CONTEXT_HUB_QUERY_APPS:
+ {
+ std::vector<HubAppInfo> apps;
+ int numApps = msgLen / sizeof(hub_app_info);
+ const hub_app_info *unalignedInfoAddr = reinterpret_cast<const hub_app_info *>(msg);
+
+ for (int i = 0; i < numApps; i++) {
+ hub_app_info query_info;
+ memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info));
+ HubAppInfo app;
+ app.appId = query_info.app_name.id;
+ app.version = query_info.version;
+ // TODO :: Add memory ranges
+
+ apps.push_back(app);
+ }
+
+ if (cb != nullptr) {
+ cb->handleAppsInfo(apps);
+ }
+ retVal = 0;
+ break;
+ }
+
+ case CONTEXT_HUB_QUERY_MEMORY:
+ {
+ // Deferring this use
+ retVal = 0;
+ break;
+ }
+
+ case CONTEXT_HUB_OS_REBOOT:
+ {
+ mIsTransactionPending = false;
+ if (cb != nullptr) {
+ cb->handleHubEvent(AsyncEventType::RESTARTED);
+ }
+ retVal = 0;
+ break;
+ }
+
+ default:
+ {
+ retVal = -1;
+ break;
+ }
+ }
+
+ return retVal;
+}
+
+void Contexthub::handleServiceDeath(uint32_t hubId) {
+ ALOGI("Callback/service died for hubId %" PRIu32, hubId);
+ int ret = NanoHub::subscribeMessages(hubId, nullptr, nullptr);
+ if (ret != 0) {
+ ALOGW("Failed to unregister callback from hubId %" PRIu32 ": %d",
+ hubId, ret);
+ }
+ mCachedHubInfo[hubId].callback.clear();
+}
+
+int Contexthub::contextHubCb(uint32_t hubId,
+ const nanohub::HubMessage &rxMsg,
+ void *cookie) {
+ Contexthub *obj = static_cast<Contexthub *>(cookie);
+
+ if (!obj->isValidHubId(hubId)) {
+ ALOGW("Invalid hub Id %" PRIu32, hubId);
+ return -1;
+ }
+
+ sp<IContexthubCallback> cb = obj->getCallBackForHubId(hubId);
+
+ if (cb == nullptr) {
+ // This should not ever happen
+ ALOGW("No callback registered, returning");
+ return -1;
+ }
+
+ if (rxMsg.message_type < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
+ obj->handleOsMessage(cb,
+ rxMsg.message_type,
+ static_cast<const uint8_t *>(rxMsg.message),
+ rxMsg.message_len);
+ } else {
+ ContextHubMsg msg;
+
+ msg.appName = rxMsg.app_name.id;
+ msg.msgType = rxMsg.message_type;
+ msg.hostEndPoint = rxMsg.message_endpoint;
+ msg.msg = std::vector<uint8_t>(static_cast<const uint8_t *>(rxMsg.message),
+ static_cast<const uint8_t *>(rxMsg.message) +
+ rxMsg.message_len);
+
+ cb->handleClientMsg(msg);
+ }
+
+ return 0;
+}
+
+Return<Result> Contexthub::unloadNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) {
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ struct apps_disable_request_t req;
+
+ msg.message_type = CONTEXT_HUB_UNLOAD_APP;
+ msg.message_len = sizeof(req);
+ msg.message = &req;
+ req.app_name.id = appId;
+
+ if(NanoHub::sendToNanohub(hubId,
+ &msg,
+ static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::loadNanoApp(uint32_t hubId,
+ const NanoAppBinary& appBinary,
+ uint32_t transactionId) {
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t hubMsg;
+
+ if (setOsAppAsDestination(&hubMsg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ // Data from the nanoapp header is passed through HIDL as explicit fields,
+ // but the legacy HAL expects it prepended to the binary, therefore we must
+ // reconstruct it here prior to passing to the legacy HAL.
+ const struct nano_app_binary_t header = {
+ .header_version = htole32(1),
+ .magic = htole32(NANOAPP_MAGIC),
+ .app_id.id = htole64(appBinary.appId),
+ .app_version = htole32(appBinary.appVersion),
+ .flags = htole32(appBinary.flags),
+ .hw_hub_type = htole64(0),
+ .target_chre_api_major_version = appBinary.targetChreApiMajorVersion,
+ .target_chre_api_minor_version = appBinary.targetChreApiMinorVersion,
+ };
+ const uint8_t *headerBytes = reinterpret_cast<const uint8_t *>(&header);
+
+ std::vector<uint8_t> binaryWithHeader(appBinary.customBinary);
+ binaryWithHeader.insert(binaryWithHeader.begin(),
+ headerBytes,
+ headerBytes + sizeof(header));
+
+ hubMsg.message_type = CONTEXT_HUB_LOAD_APP;
+ hubMsg.message_len = binaryWithHeader.size();
+ hubMsg.message = binaryWithHeader.data();
+
+ if(NanoHub::sendToNanohub(hubId,
+ &hubMsg,
+ static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::enableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) {
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ struct apps_enable_request_t req;
+
+ msg.message_type = CONTEXT_HUB_APPS_ENABLE;
+ msg.message_len = sizeof(req);
+ req.app_name.id = appId;
+ msg.message = &req;
+
+ if(NanoHub::sendToNanohub(hubId,
+ &msg,
+ static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::disableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) {
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ struct apps_disable_request_t req;
+
+ msg.message_type = CONTEXT_HUB_APPS_DISABLE;
+ msg.message_len = sizeof(req);
+ req.app_name.id = appId;
+ msg.message = &req;
+
+ if(NanoHub::sendToNanohub(hubId,
+ &msg,
+ static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::queryApps(uint32_t hubId) {
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ ALOGW("Could not find hubId %" PRIu32, hubId);
+ return Result::BAD_PARAMS;
+ }
+
+ query_apps_request_t payload;
+ payload.app_name.id = ALL_APPS; // TODO : Pass this in as a parameter
+ msg.message = &payload;
+ msg.message_len = sizeof(payload);
+ msg.message_type = CONTEXT_HUB_QUERY_APPS;
+
+ if(NanoHub::sendToNanohub(hubId,
+ &msg,
+ static_cast<uint16_t>(HostEndPoint::UNSPECIFIED)) != 0) {
+ ALOGW("Query Apps sendMessage failed");
+ return Result::TRANSACTION_FAILED;
+ }
+
+ return Result::OK;
+}
+
+IContexthub *HIDL_FETCH_IContexthub(const char *) {
+ return new Contexthub();
+}
+
+Return<void> Contexthub::debug(const hidl_handle& hh_fd,
+ const hidl_vec<hidl_string>& hh_data) {
+ String8 result;
+ int fd = hh_fd.getNativeHandle()->data[0];
+
+ if (hh_data.size() == 0) {
+ result.appendFormat("debug: %d\n", NanoHub::getDebugFlags());
+ } else if (hh_data.size() == 1) {
+ NanoHub::setDebugFlags(atoi(hh_data[0].c_str()));
+ result.appendFormat("debug: %d\n", NanoHub::getDebugFlags());
+ } else {
+ result.appendFormat("unknown debug options");
+ }
+ write(fd, result.string(), result.size());
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
diff --git a/contexthubhal/NanohubHidlAdapter.h b/contexthubhal/NanohubHidlAdapter.h
new file mode 100644
index 00000000..b8928e8c
--- /dev/null
+++ b/contexthubhal/NanohubHidlAdapter.h
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+ /*
+ * This file is based on:
+ * hardware/interfaces/contexthub/1.0/default/Contexthub.h
+ * with modifications to connect directly to the NanohubHAL and
+ * support endpoints.
+ */
+
+#ifndef _NANOHUB_HIDL_ADAPTER_H_
+#define _NANOHUB_HIDL_ADAPTER_H_
+
+#include <unordered_map>
+
+#include <android-base/macros.h>
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+#include "nanohubhal.h"
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+struct Contexthub : public ::android::hardware::contexthub::V1_0::IContexthub {
+ Contexthub();
+
+ Return<void> getHubs(getHubs_cb _hidl_cb) override;
+
+ Return<Result> registerCallback(uint32_t hubId,
+ const sp<IContexthubCallback> &cb) override;
+
+ Return<Result> sendMessageToHub(uint32_t hubId,
+ const ContextHubMsg &msg) override;
+
+ Return<Result> loadNanoApp(uint32_t hubId,
+ const NanoAppBinary& appBinary,
+ uint32_t transactionId) override;
+
+ Return<Result> unloadNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) override;
+
+ Return<Result> enableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) override;
+
+ Return<Result> disableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) override;
+
+ Return<Result> queryApps(uint32_t hubId) override;
+
+ Return<Result> reboot(uint32_t hubId);
+
+ Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
+ bool isInitialized();
+
+
+private:
+
+ struct CachedHubInformation{
+ struct hub_app_name_t osAppName;
+ sp<IContexthubCallback> callback;
+ };
+
+ class DeathRecipient : public hidl_death_recipient {
+ public:
+ DeathRecipient(const sp<Contexthub> contexthub);
+
+ void serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who) override;
+
+ private:
+ sp<Contexthub> mContexthub;
+ };
+
+ std::unordered_map<uint32_t, CachedHubInformation> mCachedHubInfo;
+
+ sp<DeathRecipient> mDeathRecipient;
+ bool mIsTransactionPending;
+ uint32_t mTransactionId;
+
+ bool isValidHubId(uint32_t hubId);
+
+ sp<IContexthubCallback> getCallBackForHubId(uint32_t hubId);
+
+ int handleOsMessage(sp<IContexthubCallback> cb,
+ uint32_t msgType,
+ const uint8_t *msg,
+ int msgLen);
+
+ // Handle the case where the callback registered for the given hub ID dies
+ void handleServiceDeath(uint32_t hubId);
+
+ static int contextHubCb(uint32_t hubId,
+ const nanohub::HubMessage &rxMsg,
+ void *cookie);
+
+ bool setOsAppAsDestination(hub_message_t *msg, int hubId);
+
+ DISALLOW_COPY_AND_ASSIGN(Contexthub);
+};
+
+extern "C" IContexthub *HIDL_FETCH_IContexthub(const char *);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
+
+#endif // _NANOHUB_HIDL_ADAPTER_H_
diff --git a/contexthubhal/android.hardware.contexthub@1.0-service.nanohub.rc b/contexthubhal/android.hardware.contexthub@1.0-service.nanohub.rc
new file mode 100644
index 00000000..a60545ef
--- /dev/null
+++ b/contexthubhal/android.hardware.contexthub@1.0-service.nanohub.rc
@@ -0,0 +1,4 @@
+service contexthub-1-0 /vendor/bin/hw/android.hardware.contexthub@1.0-service.nanohub
+ class hal
+ user system
+ group system
diff --git a/contexthubhal/legacyhal.cpp b/contexthubhal/legacyhal.cpp
new file mode 100644
index 00000000..ce2707ab
--- /dev/null
+++ b/contexthubhal/legacyhal.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#include "nanohub_perdevice.h"
+#include "nanohubhal.h"
+
+using namespace android::nanohub;
+
+static context_hub_callback *mSavedCbk = nullptr;
+
+static int legacy_cbk(uint32_t hub_id, const HubMessage &rxMsg, void *cookie)
+{
+ return mSavedCbk(hub_id, &rxMsg, cookie);
+}
+
+static int legacy_subscribe_messages(uint32_t hub_id, context_hub_callback *cbk, void *cookie)
+{
+ mSavedCbk = cbk;
+ if (cbk)
+ return NanoHub::subscribeMessages(hub_id, legacy_cbk, cookie);
+ else
+ return NanoHub::subscribeMessages(hub_id, nullptr, nullptr);
+}
+
+static int legacy_send_message(uint32_t hub_id, const hub_message_t *msg)
+{
+ return NanoHub::sendToNanohub(hub_id, msg, ENDPOINT_UNSPECIFIED);
+}
+
+static int legacy_get_hubs(context_hub_module_t*, const context_hub_t ** list)
+{
+ *list = get_hub_info();
+
+ return 1; /* we have one hub */
+}
+
+context_hub_module_t HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = CONTEXT_HUB_DEVICE_API_VERSION_1_0,
+ .hal_api_version = HARDWARE_HAL_API_VERSION,
+ .id = CONTEXT_HUB_MODULE_ID,
+ .name = "Nanohub HAL",
+ .author = "Google",
+ },
+
+ .get_hubs = legacy_get_hubs,
+ .subscribe_messages = legacy_subscribe_messages,
+ .send_message = legacy_send_message,
+};
diff --git a/contexthubhal/nanohubhal.cpp b/contexthubhal/nanohubhal.cpp
index 5b291313..46ce1e67 100644
--- a/contexthubhal/nanohubhal.cpp
+++ b/contexthubhal/nanohubhal.cpp
@@ -202,7 +202,7 @@ void* NanoHub::runAppTx()
}
HubMessage &m = mAppTxQueue.front();
lk.unlock();
- mMsgCbkFunc(0, &m, mMsgCbkData);
+ mMsgCbkFunc(0, m, mMsgCbkData);
lk.lock();
mAppTxQueue.pop_front();
};
@@ -368,7 +368,7 @@ int NanoHub::closeHub(void)
return 0;
}
-int NanoHub::doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie)
+int NanoHub::doSubscribeMessages(uint32_t hub_id, Contexthub_callback *cbk, void *cookie)
{
if (hub_id) {
return -ENODEV;
@@ -400,7 +400,7 @@ int NanoHub::doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, voi
return ret;
}
-int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg)
+int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint16_t endpoint)
{
if (hub_id) {
return -ENODEV;
@@ -427,37 +427,15 @@ int NanoHub::doSendToNanohub(uint32_t hub_id, const hub_message_t *msg)
ret = -EINVAL;
} else {
if (messageTracingEnabled()) {
- dumpBuffer("APP -> DEV", msg->app_name, msg->message_type, 0, msg->message, msg->message_len);
+ dumpBuffer("APP -> DEV", msg->app_name, msg->message_type, endpoint, msg->message, msg->message_len);
}
- ret = doSendToDevice(msg->app_name, msg->message, msg->message_len, msg->message_type);
+ ret = doSendToDevice(msg->app_name, msg->message, msg->message_len, msg->message_type, endpoint);
}
}
return ret;
}
-static int hal_get_hubs(context_hub_module_t*, const context_hub_t ** list)
-{
- *list = get_hub_info();
-
- return 1; /* we have one hub */
-}
-
}; // namespace nanohub
}; // namespace android
-
-context_hub_module_t HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = CONTEXT_HUB_DEVICE_API_VERSION_1_0,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = CONTEXT_HUB_MODULE_ID,
- .name = "Nanohub HAL",
- .author = "Google",
- },
-
- .get_hubs = android::nanohub::hal_get_hubs,
- .subscribe_messages = android::nanohub::NanoHub::subscribeMessages,
- .send_message = android::nanohub::NanoHub::sendToNanohub,
-};
diff --git a/contexthubhal/nanohubhal.h b/contexthubhal/nanohubhal.h
index 5a292f4e..1acb266a 100644
--- a/contexthubhal/nanohubhal.h
+++ b/contexthubhal/nanohubhal.h
@@ -55,9 +55,9 @@ union nano_message {
} __attribute__((packed));
class HubMessage : public hub_message_t {
- uint16_t message_endpoint;
std::unique_ptr<uint8_t> data_;
public:
+ uint16_t message_endpoint;
HubMessage(const HubMessage &other) = delete;
HubMessage &operator = (const HubMessage &other) = delete;
@@ -88,6 +88,8 @@ public:
}
};
+typedef int Contexthub_callback(uint32_t hub_id, const HubMessage &rxed_msg, void *cookie);
+
class NanoHub {
std::mutex mLock;
bool mAppQuit;
@@ -96,7 +98,7 @@ class NanoHub {
std::list<HubMessage> mAppTxQueue;
std::thread mPollThread;
std::thread mAppThread;
- context_hub_callback *mMsgCbkFunc;
+ Contexthub_callback *mMsgCbkFunc;
int mThreadClosingPipe[2];
int mFd; // [0] is read end
void * mMsgCbkData;
@@ -124,8 +126,8 @@ class NanoHub {
return &theHub;
}
- int doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie);
- int doSendToNanohub(uint32_t hub_id, const hub_message_t *msg);
+ 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);
void doSendToApp(HubMessage &&msg);
@@ -150,12 +152,12 @@ public:
// messaging interface
// define callback to invoke for APP messages
- static int subscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie) {
+ static int subscribeMessages(uint32_t hub_id, Contexthub_callback *cbk, void *cookie) {
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) {
- return hubInstance()->doSendToNanohub(hub_id, msg);
+ static int sendToNanohub(uint32_t hub_id, const hub_message_t *msg, uint16_t endpoint) {
+ return hubInstance()->doSendToNanohub(hub_id, msg, endpoint);
}
// passes message to kernel driver directly
static int sendToDevice(const hub_app_name_t *name, const void *data, uint32_t len) {
diff --git a/contexthubhal/service.cpp b/contexthubhal/service.cpp
new file mode 100644
index 00000000..645a269f
--- /dev/null
+++ b/contexthubhal/service.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.contexthub@1.0-service.nanohub"
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "NanohubHidlAdapter.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::contexthub::V1_0::IContexthub;
+using android::hardware::contexthub::V1_0::implementation::Contexthub;
+using namespace android;
+
+status_t registerContexthubService()
+{
+ sp<IContexthub> contexthub = new Contexthub();
+ return contexthub->registerAsService();
+}
+
+int main() {
+ configureRpcThreadpool(1, true);
+ status_t status = registerContexthubService();
+ if (status != OK) {
+ return status;
+ }
+ joinRpcThreadpool();
+}
diff --git a/firmware/os/core/nanohubCommand.c b/firmware/os/core/nanohubCommand.c
index 67261188..1c31bb36 100644
--- a/firmware/os/core/nanohubCommand.c
+++ b/firmware/os/core/nanohubCommand.c
@@ -951,7 +951,7 @@ static uint32_t writeEvent(void *rx, uint8_t rx_len, void *tx, uint64_t timestam
if (rx_len >= sizeof(struct HostMsgHdrChre) &&
rx_len == sizeof(struct HostMsgHdrChre) + hostPacket->len &&
osTidById(&hostPacket->appId, &tid)) {
- if (osAppChreVersion(tid) == CHRE_API_VERSION_1_1) {
+ if (osAppChreVersion(tid) >= CHRE_API_VERSION_1_1) {
struct NanohubMsgChreHdr hdr = {
.size = hostPacket->len,
.endpoint = hostPacket->endpoint,
@@ -976,7 +976,7 @@ static uint32_t writeEvent(void *rx, uint8_t rx_len, void *tx, uint64_t timestam
} else if (rx_len >= sizeof(struct HostMsgHdrChreV10) &&
rx_len == sizeof(struct HostMsgHdrChreV10) + hostPacketV10->len &&
osTidById(&hostPacketV10->appId, &tid)) {
- if (osAppChreVersion(tid) == CHRE_API_VERSION_1_1) {
+ if (osAppChreVersion(tid) >= CHRE_API_VERSION_1_1) {
struct NanohubMsgChreHdr hdr = {
.size = hostPacketV10->len,
.endpoint = CHRE_HOST_ENDPOINT_UNSPECIFIED,