From c6d2fd49533ae7d36f60ffe8ce61bcf1edd98bf5 Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Thu, 12 Jan 2017 14:47:58 -0800 Subject: [PATCH] contexthub: Explicitly pass nanoapp binary header data Parse the nanoapp binary header in the framework and pass the relevant data to the HAL explicitly in the NanoAppBinary structure. Note that not all fields from the header are carried forward into NanoAppBinary, as they are either implied by the HAL API (version, magic), or inherent in the implementation-specific data (hwHubType), or unused and will only be added via a future HAL version bump (second reserved field). Also, convert the flags field in struct MemRange to a bitmask, which is the proper representation for its use. Bug: 34182159 Test: run hello world context hub GTS test Change-Id: I13da9883b851e978d760548ec4265094ce81510a --- contexthub/1.0/IContexthub.hal | 5 +- contexthub/1.0/default/Contexthub.cpp | 34 ++++++++-- contexthub/1.0/default/Contexthub.h | 2 +- contexthub/1.0/types.hal | 89 ++++++++++++++------------- 4 files changed, 80 insertions(+), 50 deletions(-) diff --git a/contexthub/1.0/IContexthub.hal b/contexthub/1.0/IContexthub.hal index 42f2e2d8f6..c0928d582d 100644 --- a/contexthub/1.0/IContexthub.hal +++ b/contexthub/1.0/IContexthub.hal @@ -77,7 +77,8 @@ interface IContexthub { * device. * * @param hubId identifer of the contextHub - * appBinary serialized NanoApppBinary for the nanoApp + * appBinary contains the binary representation of the nanoApp, plus + * metadata * transactionId transactionId for this call * * @return result OK if transation started @@ -88,7 +89,7 @@ interface IContexthub { * */ loadNanoApp(uint32_t hubId, - vec appBinary, + NanoAppBinary appBinary, uint32_t transactionId) generates (Result result); diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp index 5f78004c9f..4a6b3f278b 100644 --- a/contexthub/1.0/default/Contexthub.cpp +++ b/contexthub/1.0/default/Contexthub.cpp @@ -22,6 +22,7 @@ #include #include +#include #undef LOG_TAG #define LOG_TAG "ContextHubHalAdapter" @@ -385,7 +386,7 @@ Return Contexthub::unloadNanoApp(uint32_t hubId, } Return Contexthub::loadNanoApp(uint32_t hubId, - const ::android::hardware::hidl_vec& appBinary, + const NanoAppBinary& appBinary, uint32_t transactionId) { if (!isInitialized()) { return Result::NOT_INIT; @@ -401,11 +402,34 @@ Return Contexthub::loadNanoApp(uint32_t hubId, return Result::BAD_PARAMS; } - hubMsg.message_type = CONTEXT_HUB_LOAD_APP; - hubMsg.message_len = appBinary.size(); - hubMsg.message = appBinary.data(); + // 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. + uint32_t targetChreApiVersion = + (appBinary.targetChreApiMajorVersion << 24) | + (appBinary.targetChreApiMinorVersion << 16); + 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), + .reserved[0] = htole32(targetChreApiVersion), + .reserved[1] = 0, + }; + const uint8_t *headerBytes = reinterpret_cast(&header); - if(mContextHubModule->send_message(hubId, &hubMsg) != 0) { + std::vector 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 (mContextHubModule->send_message(hubId, &hubMsg) != 0) { return Result::TRANSACTION_FAILED; } else { mTransactionId = transactionId; diff --git a/contexthub/1.0/default/Contexthub.h b/contexthub/1.0/default/Contexthub.h index 0883ce8215..236e0798f2 100644 --- a/contexthub/1.0/default/Contexthub.h +++ b/contexthub/1.0/default/Contexthub.h @@ -40,7 +40,7 @@ struct Contexthub : public ::android::hardware::contexthub::V1_0::IContexthub { const ContextHubMsg &msg) override; Return loadNanoApp(uint32_t hubId, - const ::android::hardware::hidl_vec& appBinary, + const NanoAppBinary& appBinary, uint32_t transactionId) override; Return unloadNanoApp(uint32_t hubId, diff --git a/contexthub/1.0/types.hal b/contexthub/1.0/types.hal index 2326b58f65..4950627a2d 100644 --- a/contexthub/1.0/types.hal +++ b/contexthub/1.0/types.hal @@ -26,35 +26,26 @@ enum Result : uint32_t { }; enum NanoAppFlags : uint32_t { - SIGNED = (1<<0), // Signed nanoapp - ENCRYPTED = (1<<1),// Encrypted nanoapp -}; - -enum HostEndPoint : uint16_t { - BROADCAST = 0xFFFF, // The message endpoint is a broadcast end point. - // This value must never be used for a message from - // the host to the hub. - // If BROADCAST is specified as a destination for a - // message from the context hub to the ContextHub - // service, the message must be broadcast to all - // registered clients by the Context Hub service. - UNSPECIFIED = 0xFFFE, // The message endpoint is unspecified. This value - // must not be used for messages from the hub to host. - // This value may be used for messages from the host - // to the hub. + SIGNED = 1 << 0, + ENCRYPTED = 1 << 1, }; struct NanoAppBinary { - uint32_t headerVersion; // 0x1 for this version - uint32_t magic; // "NANO" - uint64_t appId; // App ID (contains vendor ID in most significant - // 5 bytes) - uint32_t appVersion; // Version of the app - uint32_t flags; // Mask of NanoAppFlags - uint64_t hwHubType; // Which hub type is this app is compiled for. A - // unique ID for each h/w + toolchain - // combination. - vec customBinary; // start of custom binary data + uint64_t appId; // Nanoapp identifier + uint32_t appVersion; // Version of the app (semantics defined by app) + bitfield flags; + + // The version of the CHRE API that this nanoApp was compiled against. See + // the CHRE API header file chre/version.h for more information. The hub + // implementation must use this to confirm compatibility before loading + // this nanoApp. + uint8_t targetChreApiMajorVersion; + uint8_t targetChreApiMinorVersion; + + // Implementation-specific binary nanoapp data. This does not include the + // common nanoapp header that contains the app ID, etc., as this data is + // explicitly passed through the other fields in this struct. + vec customBinary; }; enum SensorType : uint32_t { @@ -130,20 +121,34 @@ struct ContextHub { // be sent to the hub in one chunk (in bytes) // Machine-readable CHRE platform ID, returned to nanoapps in the CHRE API - // function call chreGetPlatformId(). The most significant 5 bytes of this - // value identify the vendor, while the remaining bytes are set by the - // vendor to uniquely identify each different CHRE implementation/hardware - // that the vendor supplies. This field pairs with the patch version part of - // chreVersion to fully specify the CHRE implementation version. See also - // the CHRE API header file chre/version.h. + // function call chreGetPlatformId(). This field pairs with + // chreApiMajorVersion, chreApiMinorVersion, and chrePatchVersion to fully + // specify the CHRE implementation version. See also the CHRE API header + // file chre/version.h. uint64_t chrePlatformId; - // CHRE implementation version, returned to nanoApps in the CHRE API - // function call chreGetVersion(). This value consists of the implemented - // CHRE API version (major version in most significant byte, followed by - // minor version), and the platform-specific implementation patch version - // in the lower two bytes. See also the CHRE API header file chre/version.h. - uint32_t chreVersion; + // The version of the CHRE implementation returned to nanoApps in the CHRE + // API function call chreGetVersion(). The major and minor version specify + // the implemented version of the CHRE API, while the patch version + // describes the implementation version within the scope of the platform + // ID. See also the CHRE API header file chre/version.h. + uint8_t chreApiMajorVersion; + uint8_t chreApiMinorVersion; + uint16_t chrePatchVersion; +}; + +enum HostEndPoint : uint16_t { + BROADCAST = 0xFFFF, // The message endpoint is a broadcast end point. + // This value must never be used for a message from + // the host to the hub. + // If BROADCAST is specified as a destination for a + // message from the context hub to the ContextHub + // service, the message must be broadcast to all + // registered clients by the Context Hub service. + UNSPECIFIED = 0xFFFE, // The message endpoint is unspecified. This value + // must not be used for messages from the hub to host. + // This value may be used for messages from the host + // to the hub. }; struct ContextHubMsg { @@ -160,16 +165,16 @@ enum HubMemoryType : uint32_t { }; enum HubMemoryFlag : uint32_t { - READ = (1<<0), // Readable - WRITE = (1<<1), // Writable - EXEC = (1<<2), // Executable + READ = 1 << 0, // Readable + WRITE = 1 << 1, // Writable + EXEC = 1 << 2, // Executable }; struct MemRange { uint32_t totalBytes; // Total capacity in bytes uint32_t freeBytes; // Free capacity in bytes HubMemoryType type; // Type of memory, see HubMemoryType - uint32_t flags; // Mask of HubMemoryFlag + bitfield flags; }; enum AsyncEventType : uint32_t {