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