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 #include <stdint.h>
18 #include <inttypes.h>
19 #include <chre.h>
20 
21 #define CHRE_APP_TAG "CHRE App 0: "
22 
23 /* chre.h does not define printf format attribute for chreLog() */
24 void chreLog(enum chreLogLevel level, const char *str, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
25 
26 #define EVT_LOCAL_SETUP CHRE_EVENT_FIRST_USER_VALUE
27 
28 struct MyTimer {
29     uint32_t timerId;
30 };
31 
32 struct ExtMsg
33 {
34     uint8_t msg;
35     uint32_t val;
36 } __attribute__((packed));
37 
38 static const uint64_t kOneSecond = UINT64_C(1000000000); // in nanoseconds
39 
40 static uint32_t mMyTid;
41 static uint64_t mMyAppId;
42 static int mCnt;
43 static struct MyTimer mTimer;
44 
nanoappFreeEvent(uint16_t eventType,void * data)45 static void nanoappFreeEvent(uint16_t eventType, void *data)
46 {
47     chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "event callback invoked: eventType=%04" PRIX16
48             "; data=%p\n", eventType, data);
49 }
50 
51 // Default implementation for message free
nanoappFreeMessage(void * msg,size_t size)52 static void nanoappFreeMessage(void *msg, size_t size)
53 {
54     chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "message callback invoked: msg=%p; size=%08zu\n",
55             msg, size);
56     chreHeapFree(msg);
57 }
58 
nanoappStart(void)59 bool nanoappStart(void)
60 {
61     mMyAppId = chreGetAppId();
62     mMyTid = chreGetInstanceId();
63     mCnt = 3;
64     chreSendEvent(EVT_LOCAL_SETUP, (void*)0x87654321, nanoappFreeEvent, mMyTid);
65     chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "init\n");
66     return true;
67 }
68 
nanoappEnd(void)69 void nanoappEnd(void)
70 {
71 }
72 
nanoappHandleEvent(uint32_t srcTid,uint16_t evtType,const void * evtData)73 void nanoappHandleEvent(uint32_t srcTid, uint16_t evtType, const void* evtData)
74 {
75     switch (evtType) {
76     case  EVT_LOCAL_SETUP:
77         mTimer.timerId = chreTimerSet(kOneSecond, &mTimer, false);
78         chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "started with tid %04" PRIX32
79                                " timerid %" PRIu32
80                                "\n", mMyTid, mTimer.timerId);
81         break;
82     case CHRE_EVENT_TIMER:
83     {
84         const struct MyTimer *t = (const struct MyTimer *)evtData;
85         struct ExtMsg *extMsg = chreHeapAlloc(sizeof(*extMsg));
86 
87         chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "received timer %" PRIu32
88                                " (TIME: %" PRIu64
89                                ") cnt: %d\n", t->timerId, chreGetTime(), mCnt);
90         extMsg->msg = 0x01;
91         extMsg->val = mCnt;
92         chreSendMessageToHost(extMsg, sizeof(*extMsg), 0, nanoappFreeMessage);
93         if (mCnt-- <= 0)
94             chreTimerCancel(t->timerId);
95         break;
96     }
97     case CHRE_EVENT_MESSAGE_FROM_HOST:
98     {
99         const struct chreMessageFromHostData *msg = (const struct chreMessageFromHostData *)evtData;
100         const uint8_t *data = (const uint8_t *)msg->message;
101         const size_t size = msg->messageSize;
102         chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "message=%p; code=%d; size=%zu\n",
103                 data, (data && size) ? data[0] : 0, size);
104         break;
105     }
106     }
107 }
108