1 /*
2  * Copyright (c) 2016, Google. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above
10  *       copyright notice, this list of conditions and the following
11  *       disclaimer in the documentation and/or other materials provided
12  *       with the distribution.
13  *     * Neither the name of The Linux Foundation nor the names of its
14  *       contributors may be used to endorse or promote products derived
15  *       from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 
31 #ifndef _NANOHUB_HAL_H_
32 #define _NANOHUB_HAL_H_
33 
34 #include <pthread.h>
35 
36 #include <hardware/context_hub.h>
37 #include <utils/Mutex.h>
38 
39 #define NANOAPP_VENDOR_GOOGLE NANOAPP_VENDOR("Googl")
40 
41 //as per protocol
42 #define MAX_RX_PACKET           128
43 #define APP_FROM_HOST_EVENT_ID  0x000000F8
44 
45 namespace android {
46 
47 namespace nanohub {
48 
49 void dumpBuffer(const char *pfx, const hub_app_name_t &appId, uint32_t evtId, const void *data, size_t len, int status = 0);
50 
51 struct nano_message_hdr {
52     uint32_t event_id;
53     hub_app_name_t app_name;
54     uint8_t len;
55 } __attribute__((packed));
56 
57 struct nano_message {
58     nano_message_hdr hdr;
59     uint8_t data[MAX_RX_PACKET];
60 } __attribute__((packed));
61 
62 class NanoHub {
63     Mutex mLock;
64     context_hub_callback *mMsgCbkFunc;
65     int mThreadClosingPipe[2];
66     int mFd; // [0] is read end
67     void * mMsgCbkData;
68     pthread_t mWorkerThread;
69 
NanoHub()70     NanoHub() {
71         reset();
72     }
73 
reset()74     void reset() {
75         mThreadClosingPipe[0] = -1;
76         mThreadClosingPipe[1] = -1;
77         mFd = -1;
78         mMsgCbkData = nullptr;
79         mMsgCbkFunc = nullptr;
80         mWorkerThread = 0;
81     }
82 
83     static void* run(void *);
84     void* doRun();
85 
86     int openHub();
87     int closeHub();
88 
hubInstance()89     static NanoHub *hubInstance() {
90         static NanoHub theHub;
91         return &theHub;
92     }
93 
94     int doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie);
95     int doSendToNanohub(uint32_t hub_id, const hub_message_t *msg);
96     int doSendToDevice(const hub_app_name_t *name, const void *data, uint32_t len);
97     void doSendToApp(const hub_app_name_t *name, uint32_t typ, const void *data, uint32_t len);
98 
99     static constexpr unsigned int FL_MESSAGE_TRACING = 1;
100 
101     unsigned int mFlags = 0;
102 
103 public:
104 
105     // debugging interface
106 
messageTracingEnabled()107     static bool messageTracingEnabled() {
108         return hubInstance()->mFlags & FL_MESSAGE_TRACING;
109     }
getDebugFlags()110     static unsigned int getDebugFlags() {
111         return hubInstance()->mFlags;
112     }
setDebugFlags(unsigned int flags)113     static void setDebugFlags(unsigned int flags) {
114         hubInstance()->mFlags = flags;
115     }
116 
117     // messaging interface
118 
119     // define callback to invoke for APP messages
subscribeMessages(uint32_t hub_id,context_hub_callback * cbk,void * cookie)120     static int subscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie) {
121         return hubInstance()->doSubscribeMessages(hub_id, cbk, cookie);
122     }
123     // all messages from APP go here
sendToNanohub(uint32_t hub_id,const hub_message_t * msg)124     static int sendToNanohub(uint32_t hub_id, const hub_message_t *msg) {
125         return hubInstance()->doSendToNanohub(hub_id, msg);
126     }
127     // passes message to kernel driver directly
sendToDevice(const hub_app_name_t * name,const void * data,uint32_t len)128     static int sendToDevice(const hub_app_name_t *name, const void *data, uint32_t len) {
129         return hubInstance()->doSendToDevice(name, data, len);
130     }
131     // passes message to APP via callback
sendToApp(const hub_app_name_t * name,uint32_t typ,const void * data,uint32_t len)132     static void sendToApp(const hub_app_name_t *name, uint32_t typ, const void *data, uint32_t len) {
133         hubInstance()->doSendToApp(name, typ, data, len);
134     }
135 };
136 
137 }; // namespace nanohub
138 
139 }; // namespace android
140 
141 #endif
142