• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 "send_message.h"
18 
19 #include <pb_encode.h>
20 #include <cinttypes>
21 
22 #include "chre/util/nanoapp/callbacks.h"
23 #include "chre/util/nanoapp/log.h"
24 #include "chre_api/chre.h"
25 #include "chre_test_common.nanopb.h"
26 
27 #ifndef LOG_TAG
28 #define LOG_TAG "[TestShared]"
29 #endif
30 
31 namespace chre {
32 namespace test_shared {
33 namespace {
34 
encodeErrorMessage(pb_ostream_t * stream,const pb_field_t *,void * const * arg)35 bool encodeErrorMessage(pb_ostream_t *stream, const pb_field_t * /*field*/,
36                         void *const *arg) {
37   const char *str = static_cast<const char *>(const_cast<const void *>(*arg));
38   size_t len = strlen(str);
39   return pb_encode_tag_for_field(
40              stream, &chre_test_common_TestResult_fields
41                          [chre_test_common_TestResult_errorMessage_tag - 1]) &&
42          pb_encode_string(stream, reinterpret_cast<const pb_byte_t *>(str),
43                           len);
44 }
45 
46 }  // namespace
47 
sendTestResultWithMsgToHost(uint16_t hostEndpointId,uint32_t messageType,bool success,const char * errMessage,bool abortOnFailure)48 void sendTestResultWithMsgToHost(uint16_t hostEndpointId, uint32_t messageType,
49                                  bool success, const char *errMessage,
50                                  bool abortOnFailure) {
51   // Unspecified endpoint is not allowed in chreSendMessageToHostEndpoint.
52   if (hostEndpointId == CHRE_HOST_ENDPOINT_UNSPECIFIED) {
53     hostEndpointId = CHRE_HOST_ENDPOINT_BROADCAST;
54     LOGE("Unspecified endpoint ID is not allowed");
55     success = false;
56   }
57 
58   chre_test_common_TestResult result = chre_test_common_TestResult_init_default;
59   result.has_code = true;
60   result.code = success ? chre_test_common_TestResult_Code_PASSED
61                         : chre_test_common_TestResult_Code_FAILED;
62   if (!success && errMessage != nullptr) {
63     result.errorMessage = {.funcs = {.encode = encodeErrorMessage},
64                            .arg = const_cast<char *>(errMessage)};
65     LOGE("%s", errMessage);
66   }
67 
68   sendMessageToHost(hostEndpointId, &result, chre_test_common_TestResult_fields,
69                     messageType);
70 
71   if (!success && abortOnFailure) {
72     chreAbort(0);
73   }
74 }
75 
sendTestResultToHost(uint16_t hostEndpointId,uint32_t messageType,bool success)76 void sendTestResultToHost(uint16_t hostEndpointId, uint32_t messageType,
77                           bool success) {
78   sendTestResultWithMsgToHost(hostEndpointId, messageType, success,
79                               nullptr /* errMessage */);
80 }
81 
sendEmptyMessageToHost(uint16_t hostEndpointId,uint32_t messageType)82 void sendEmptyMessageToHost(uint16_t hostEndpointId, uint32_t messageType) {
83   // Unspecified endpoint is not allowed in chreSendMessageToHostEndpoint.
84   if (hostEndpointId == CHRE_HOST_ENDPOINT_UNSPECIFIED) {
85     hostEndpointId = CHRE_HOST_ENDPOINT_BROADCAST;
86     LOGE("Unspecified endpoint ID is not allowed");
87     // TODO: Send failure message to host
88     return;
89   }
90 
91   chreSendMessageToHostEndpoint(nullptr /* message */, 0 /* messageSize */,
92                                 messageType, hostEndpointId,
93                                 nullptr /* freeCallback */);
94 }
95 
sendMessageToHost(uint16_t hostEndpointId,const void * message,const pb_field_t * fields,uint32_t messageType)96 void sendMessageToHost(uint16_t hostEndpointId, const void *message,
97                        const pb_field_t *fields, uint32_t messageType) {
98   size_t size;
99   if (!pb_get_encoded_size(&size, fields, message)) {
100     LOGE("Failed to get message size");
101   } else {
102     pb_byte_t *bytes = static_cast<pb_byte_t *>(chreHeapAlloc(size));
103     if (size > 0 && bytes == nullptr) {
104       LOG_OOM();
105     } else {
106       pb_ostream_t stream = pb_ostream_from_buffer(bytes, size);
107       if (!pb_encode(&stream, fields, message)) {
108         LOGE("Failed to encode message error %s", PB_GET_ERROR(&stream));
109         chreHeapFree(bytes);
110       } else if (!chreSendMessageToHostEndpoint(bytes, size, messageType,
111                                                 hostEndpointId,
112                                                 heapFreeMessageCallback)) {
113         LOGE("Failed to send message to host");
114       }
115     }
116   }
117 }
118 
119 }  // namespace test_shared
120 
121 }  // namespace chre
122