• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "chre/util/pigweed/chre_channel_output.h"
18 
19 #include "chre/util/memory.h"
20 #include "chre/util/nanoapp/callbacks.h"
21 
22 namespace chre {
23 namespace {
24 
nappMessageFreeCb(uint16_t,void * eventData)25 void nappMessageFreeCb(uint16_t /* eventType */, void *eventData) {
26   chreHeapFree(eventData);
27 }
28 
29 }  // namespace
30 
ChreChannelOutputBase()31 ChreChannelOutputBase::ChreChannelOutputBase() : ChannelOutput("CHRE") {}
32 
setEndpointId(uint16_t endpointId)33 void ChreChannelOutputBase::setEndpointId(uint16_t endpointId) {
34   mEndpointId = endpointId;
35 }
36 
MaximumTransmissionUnit()37 size_t ChreChannelOutputBase::MaximumTransmissionUnit() {
38   return CHRE_MESSAGE_TO_HOST_MAX_SIZE;
39 }
40 
setNanoappEndpoint(uint32_t nanoappInstanceId)41 void ChreNanoappChannelOutput::setNanoappEndpoint(uint32_t nanoappInstanceId) {
42   CHRE_ASSERT(nanoappInstanceId <= UINT16_MAX);
43   if (nanoappInstanceId <= UINT16_MAX) {
44     mEndpointId = static_cast<uint16_t>(nanoappInstanceId);
45   } else {
46     mEndpointId = CHRE_HOST_ENDPOINT_UNSPECIFIED;
47   }
48 }
49 
Send(std::span<const std::byte> buffer)50 pw::Status ChreNanoappChannelOutput::Send(std::span<const std::byte> buffer) {
51   CHRE_ASSERT(mEndpointId != CHRE_HOST_ENDPOINT_UNSPECIFIED);
52   pw::Status returnCode = PW_STATUS_OK;
53 
54   if (buffer.size() > 0) {
55     auto *data = static_cast<ChrePigweedNanoappMessage *>(
56         chreHeapAlloc(buffer.size() + sizeof(ChrePigweedNanoappMessage)));
57     if (data == nullptr) {
58       returnCode = PW_STATUS_RESOURCE_EXHAUSTED;
59     } else {
60       data->msgSize = buffer.size();
61       memcpy(data->msg, buffer.data(), buffer.size());
62       if (!chreSendEvent(PW_RPC_CHRE_NAPP_EVENT_TYPE, data, nappMessageFreeCb,
63                          mEndpointId)) {
64         returnCode = PW_STATUS_INVALID_ARGUMENT;
65       }
66     }
67   }
68 
69   return returnCode;
70 }
71 
setHostEndpoint(uint16_t hostEndpoint)72 void ChreHostChannelOutput::setHostEndpoint(uint16_t hostEndpoint) {
73   setEndpointId(hostEndpoint);
74 }
75 
Send(std::span<const std::byte> buffer)76 pw::Status ChreHostChannelOutput::Send(std::span<const std::byte> buffer) {
77   CHRE_ASSERT(mEndpointId != CHRE_HOST_ENDPOINT_UNSPECIFIED);
78   pw::Status returnCode = PW_STATUS_OK;
79 
80   if (buffer.size() > 0) {
81     uint8_t *data = memoryAlloc<uint8_t>(buffer.size());
82     if (data == nullptr) {
83       returnCode = PW_STATUS_RESOURCE_EXHAUSTED;
84     } else {
85       memcpy(data, buffer.data(), buffer.size());
86       // TODO(b/210138227): Make this pass permissions too.
87       if (!chreSendMessageWithPermissions(
88               data, buffer.size(), PW_RPC_CHRE_HOST_MESSAGE_TYPE, mEndpointId,
89               CHRE_MESSAGE_PERMISSION_NONE, heapFreeMessageCallback)) {
90         returnCode = PW_STATUS_INVALID_ARGUMENT;
91       }
92     }
93   }
94 
95   return returnCode;
96 }
97 
98 }  // namespace chre
99