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 {