Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef CHRE_CORE_HOST_COMMS_MANAGER_H_
     18 #define CHRE_CORE_HOST_COMMS_MANAGER_H_
     19 
     20 #include <cstddef>
     21 
     22 #include "chre_api/chre/event.h"
     23 #include "chre/core/event_loop.h"
     24 #include "chre/platform/host_link.h"
     25 #include "chre/util/dynamic_vector.h"
     26 #include "chre/util/non_copyable.h"
     27 #include "chre/util/synchronized_memory_pool.h"
     28 
     29 namespace chre {
     30 
     31 //! Only valid for messages from host to CHRE - indicates that the sender of the
     32 //! message is not specified.
     33 constexpr uint16_t kHostEndpointUnspecified = CHRE_HOST_ENDPOINT_UNSPECIFIED;
     34 
     35 //! Only valid for messages from CHRE to host - delivers the message to all
     36 //! registered clients of the Context Hub HAL, which is the default behavior.
     37 constexpr uint16_t kHostEndpointBroadcast = CHRE_HOST_ENDPOINT_BROADCAST;
     38 
     39 /**
     40  * Data associated with a message either to or from the host.
     41  */
     42 struct HostMessage : public NonCopyable {
     43   // This union must be first, as this structure is aliased with
     44   // chreMessageFromHostData
     45   union {
     46     // Fields use when the message was received from the host
     47     struct chreMessageFromHostData fromHostData;
     48 
     49     // Fields used when the messsage is directed to the host
     50     struct {
     51       //! Application-specific message ID
     52       uint32_t messageType;
     53 
     54       //! Padding used to align this structure with chreMessageFromHostData
     55       uint32_t reserved;
     56 
     57       //! Message free callback supplied by the nanoapp. Must only be invoked from
     58       //! the EventLoop where the nanoapp runs.
     59       chreMessageFreeFunction *nanoappFreeFunction;
     60 
     61       //! Identifier for the host-side entity that should receive this message, or
     62       //! that which sent it
     63       uint16_t hostEndpoint;
     64     } toHostData;
     65   };
     66 
     67   //! Source/destination nanoapp ID
     68   uint64_t appId;
     69 
     70   //! Application-defined message data
     71   DynamicVector<uint8_t> message;
     72 };
     73 
     74 typedef HostMessage MessageFromHost;
     75 typedef HostMessage MessageToHost;
     76 
     77 /**
     78  * Manages bi-directional communications with the host. There must only be one
     79  * instance of this class per CHRE instance, as the HostLink is not multiplexed
     80  * per-EventLoop.
     81  */
     82 class HostCommsManager : public NonCopyable {
     83  public:
     84   /**
     85    * @see HostLink::flushMessagesSentByNanoapp
     86    */
     87   void flushMessagesSentByNanoapp(uint64_t appId);
     88 
     89   /**
     90    * Formulates a MessageToHost using the supplied message contents and passes
     91    * it to HostLink for transmission to the host.
     92    *
     93    * @param nanoapp The sender of this message
     94    * @param messageData Pointer to message payload. Can be null if messageSize
     95    *        is 0. This buffer must remain valid until freeCallback is invoked.
     96    * @param messageSize Size of the message to send, in bytes
     97    * @param messageType Application-defined identifier for the message
     98    * @param hostEndpoint Identifier for the entity on the host that should
     99    *        receive this message
    100    * @param freeCallback Optional callback to invoke when the messageData is no
    101    *        longer needed (the message has been sent or an error occurred)
    102    *
    103    * @return true if the message was accepted into the outbound message queue.
    104    *         If this function returns false, it does *not* invoke freeCallback.
    105    *         If it returns true, freeCallback will be invoked (if non-null) on
    106    *         either success or failure.
    107    *
    108    * @see chreSendMessageToHost
    109    */
    110   bool sendMessageToHostFromNanoapp(
    111       Nanoapp *nanoapp, void *messageData, size_t messageSize,
    112       uint32_t messageType, uint16_t hostEndpoint,
    113       chreMessageFreeFunction *freeCallback);
    114 
    115   /**
    116    * Makes a copy of the supplied message data and posts it to the queue for
    117    * later delivery to the addressed nanoapp.
    118    *
    119    * This function is safe to call from any thread.
    120    *
    121    * @param appId Identifier for the destination nanoapp
    122    * @param messageType Application-defined message identifier
    123    * @param hostEndpoint Identifier for the entity on the host that sent this
    124    *        message
    125    * @param messageData Buffer containing application-specific message data; can
    126    *        be null if messageSize is 0
    127    * @param messageSize Size of messageData, in bytes
    128    */
    129   void sendMessageToNanoappFromHost(
    130       uint64_t appId, uint32_t messageType, uint16_t hostEndpoint,
    131       const void *messageData, size_t messageSize);
    132 
    133   /**
    134    * Invoked by the HostLink platform layer when it is done with a message to
    135    * the host: either it successfully sent it, or encountered an error.
    136    *
    137    * This function is thread-safe.
    138    *
    139    * @param message A message pointer previously given to HostLink::sendMessage
    140    */
    141   void onMessageToHostComplete(const MessageToHost *msgToHost);
    142 
    143  private:
    144   //! The maximum number of messages we can have outstanding at any given time
    145   static constexpr size_t kMaxOutstandingMessages = 32;
    146 
    147   //! Memory pool used to allocate message metadata (but not the contents of the
    148   //! messages themselves). Must be synchronized as the same HostCommsManager
    149   //! handles communications for all EventLoops, and also to support freeing
    150   //! messages directly in onMessageToHostComplete.
    151   SynchronizedMemoryPool<HostMessage, kMaxOutstandingMessages> mMessagePool;
    152 
    153   //! The platform-specific link to the host that we manage
    154   HostLink mHostLink;
    155 
    156   /**
    157    * Allocates and populates the event structure used to notify a nanoapp of an
    158    * incoming message from the host, and posts an event to the nanoapp for
    159    * processing. Used to implement sendMessageToNanoappFromHost() - see that
    160    * function for parameter documentation.
    161    *
    162    * All parameters must be sanitized before invoking this function.
    163    *
    164    * @param targetInstanceId Instance ID of the destination nanoapp
    165    *
    166    * @see sendMessageToNanoappFromHost
    167    */
    168   void deliverNanoappMessageFromHost(
    169       uint64_t appId, uint16_t hostEndpoint, uint32_t messageType,
    170       const void *messageData, uint32_t messageSize, uint32_t targetInstanceId);
    171 
    172   /**
    173    * Releases memory associated with a message to the host, including invoking
    174    * the Nanoapp's free callback (if given). Must be called from within the
    175    * context of the EventLoop that contains the sending Nanoapp.
    176    *
    177    * @param msgToHost The message to free
    178    */
    179   void freeMessageToHost(MessageToHost *msgToHost);
    180 
    181   /**
    182    * Event free callback used to release memory allocated to deliver a message
    183    * to a nanoapp from the host.
    184    *
    185    * @param type Event type
    186    * @param data Event data
    187    */
    188   static void freeMessageFromHostCallback(uint16_t type, void *data);
    189 };
    190 
    191 } // namespace chre
    192 
    193 #endif  // CHRE_CORE_HOST_COMMS_MANAGER_H_
    194