diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-01-10 08:28:21 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-01-10 08:28:21 +0000 |
commit | 0a8d740c57c0184f62010517e42afbe5098b5e49 (patch) | |
tree | f6e414f37719f0862d09a6286382be07bb02122f | |
parent | 3a3c2379279ebb8250d4093c46e65a9fe8967978 (diff) | |
parent | f378cb36e45cbfd402a26982a284dbd2933d5ef8 (diff) | |
download | device_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.bp | 57 | ||||
-rw-r--r-- | contexthubhal/NanohubHidlAdapter.cpp | 542 | ||||
-rw-r--r-- | contexthubhal/NanohubHidlAdapter.h | 131 | ||||
-rw-r--r-- | contexthubhal/android.hardware.contexthub@1.0-service.nanohub.rc | 4 | ||||
-rw-r--r-- | contexthubhal/legacyhal.cpp | 63 | ||||
-rw-r--r-- | contexthubhal/nanohubhal.cpp | 32 | ||||
-rw-r--r-- | contexthubhal/nanohubhal.h | 16 | ||||
-rw-r--r-- | contexthubhal/service.cpp | 44 | ||||
-rw-r--r-- | firmware/os/core/nanohubCommand.c | 4 |
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, |