Home | History | Annotate | Download | only in contexthubhal
      1 /*
      2  * Copyright (C) 2016 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 _NANOHUB_HAL_H_
     18 #define _NANOHUB_HAL_H_
     19 
     20 #include <mutex>
     21 #include <thread>
     22 #include <list>
     23 
     24 #include <hardware/context_hub.h>
     25 
     26 #include <nanohub/nanohub.h>
     27 
     28 //as per protocol
     29 #define MAX_RX_PACKET               128
     30 #define APP_FROM_HOST_EVENT_ID      0x000000F8
     31 #define APP_FROM_HOST_CHRE_EVENT_ID 0x000000F9
     32 
     33 namespace android {
     34 
     35 namespace nanohub {
     36 
     37 void dumpBuffer(const char *pfx, const hub_app_name_t &appId, uint32_t evtId, const void *data, size_t len, int status = 0);
     38 
     39 struct nano_message_chre {
     40     HostMsgHdrChre hdr;
     41     uint8_t data[MAX_RX_PACKET];
     42 } __attribute__((packed));
     43 
     44 struct nano_message {
     45     HostMsgHdr hdr;
     46     uint8_t data[MAX_RX_PACKET];
     47 } __attribute__((packed));
     48 
     49 class HubMessage : public hub_message_t {
     50     std::unique_ptr<uint8_t> data_;
     51 public:
     52     HubMessage(const HubMessage &other) = delete;
     53     HubMessage &operator = (const HubMessage &other) = delete;
     54 
     55     HubMessage(const hub_app_name_t *name, uint32_t typ, const void *data, uint32_t len) {
     56         app_name = *name;
     57         message_type = typ;
     58         message_len = len;
     59         message = data;
     60         if (len > 0 && data != nullptr) {
     61             data_ = std::unique_ptr<uint8_t>(new uint8_t[len]);
     62             memcpy(data_.get(), data, len);
     63             message = data_.get();
     64         }
     65     }
     66 
     67     HubMessage(HubMessage &&other) {
     68         *this = (HubMessage &&)other;
     69     }
     70 
     71     HubMessage &operator = (HubMessage &&other) {
     72         *static_cast<hub_message_t *>(this) = static_cast<hub_message_t>(other);
     73         data_ = std::move(other.data_);
     74         other.message = nullptr;
     75         other.message_len = 0;
     76         return *this;
     77     }
     78 };
     79 
     80 class NanoHub {
     81     std::mutex mLock;
     82     bool mAppQuit;
     83     std::mutex mAppTxLock;
     84     std::condition_variable mAppTxCond;
     85     std::list<HubMessage> mAppTxQueue;
     86     std::thread mPollThread;
     87     std::thread mAppThread;
     88     context_hub_callback *mMsgCbkFunc;
     89     int mThreadClosingPipe[2];
     90     int mFd; // [0] is read end
     91     void * mMsgCbkData;
     92 
     93     NanoHub();
     94     ~NanoHub();
     95 
     96     void reset() {
     97         mThreadClosingPipe[0] = -1;
     98         mThreadClosingPipe[1] = -1;
     99         mFd = -1;
    100         mMsgCbkData = nullptr;
    101         mMsgCbkFunc = nullptr;
    102         mAppQuit = false;
    103     }
    104 
    105     void* runAppTx();
    106     void* runDeviceRx();
    107 
    108     int openHub();
    109     int closeHub();
    110 
    111     static NanoHub *hubInstance() {
    112         static NanoHub theHub;
    113         return &theHub;
    114     }
    115 
    116     int doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie);
    117     int doSendToNanohub(uint32_t hub_id, const hub_message_t *msg);
    118     int doSendToDevice(const hub_app_name_t name, const void *data, uint32_t len, uint32_t messageType);
    119     void doSendToApp(HubMessage &&msg);
    120 
    121     static constexpr unsigned int FL_MESSAGE_TRACING = 1;
    122 
    123     unsigned int mFlags = 0;
    124 
    125 public:
    126 
    127     // debugging interface
    128 
    129     static bool messageTracingEnabled() {
    130         return hubInstance()->mFlags & FL_MESSAGE_TRACING;
    131     }
    132     static unsigned int getDebugFlags() {
    133         return hubInstance()->mFlags;
    134     }
    135     static void setDebugFlags(unsigned int flags) {
    136         hubInstance()->mFlags = flags;
    137     }
    138 
    139     // messaging interface
    140 
    141     // define callback to invoke for APP messages
    142     static int subscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie) {
    143         return hubInstance()->doSubscribeMessages(hub_id, cbk, cookie);
    144     }
    145     // all messages from APP go here
    146     static int sendToNanohub(uint32_t hub_id, const hub_message_t *msg) {
    147         return hubInstance()->doSendToNanohub(hub_id, msg);
    148     }
    149     // passes message to kernel driver directly
    150     static int sendToDevice(const hub_app_name_t *name, const void *data, uint32_t len) {
    151         return hubInstance()->doSendToDevice(*name, data, len, 0);
    152     }
    153     // passes message to APP via callback
    154     static void sendToApp(HubMessage &&msg) {
    155         hubInstance()->doSendToApp((HubMessage &&)msg);
    156     }
    157 };
    158 
    159 }; // namespace nanohub
    160 
    161 }; // namespace android
    162 
    163 #endif
    164