1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "buffer_object.h"
17 
18 #include "ipc_debug.h"
19 #include "log_tags.h"
20 #include "securec.h"
21 #include "sys_binder.h"
22 
23 namespace OHOS {
BufferObject()24 BufferObject::BufferObject()
25 {
26 }
27 
~BufferObject()28 BufferObject::~BufferObject()
29 {
30     if (receiveBuffer_ != nullptr) {
31         delete[] receiveBuffer_;
32         receiveBuffer_ = nullptr;
33     }
34     if (sendBuffer_ != nullptr) {
35         delete[] sendBuffer_;
36         sendBuffer_ = nullptr;
37     }
38 }
39 
40 /* update buffer need get mutex first */
UpdateSendBuffer(uint32_t userDataSize)41 void BufferObject::UpdateSendBuffer(uint32_t userDataSize)
42 {
43     if (sendBufferCursorW_ <= sendBufferCursorR_) {
44         sendBufferCursorW_ = 0;
45         sendBufferCursorR_ = 0;
46         return;
47     }
48     /* buffer is not enough, means need expand buffer */
49     if (sendBuffSize_ - sendBufferCursorW_ <= userDataSize) {
50         ExpandSendBuffer(sendBuffSize_ + sendBuffSize_);
51     }
52     /* check whether buffer size is enough, if not, move write/read cursor to head */
53     /* writeCursor always bigger than readCursor */
54     if (sendBuffSize_ - sendBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
55         sendBufferCursorW_ - sendBufferCursorR_ < sendBufferCursorR_) {
56         auto memcpyResult = memmove_s(sendBuffer_, sendBufferCursorW_ - sendBufferCursorR_,
57             sendBuffer_ + sendBufferCursorR_, sendBufferCursorW_ - sendBufferCursorR_);
58         if (memcpyResult != EOK) {
59             sendBufferCursorW_ = 0; // drop data in buffer, if memmove failed
60         } else {
61             sendBufferCursorW_ = sendBufferCursorW_ - sendBufferCursorR_;
62         }
63         sendBufferCursorR_ = 0;
64     }
65 }
66 
67 /* update buffer need get mutex first */
UpdateReceiveBuffer()68 void BufferObject::UpdateReceiveBuffer()
69 {
70     if (recvBufferCursorW_ <= recvBufferCursorR_) {
71         recvBufferCursorR_ = 0;
72         recvBufferCursorW_ = 0;
73         return;
74     }
75     /* check whether buffer size is enough, if not, move write/read cursor to head */
76     /* writeCursor always bigger than readCursor */
77     if (recvBuffSize_ - recvBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
78         recvBufferCursorW_ - recvBufferCursorR_ < recvBufferCursorR_) {
79         auto memcpyResult = memmove_s(receiveBuffer_, recvBufferCursorW_ - recvBufferCursorR_,
80             receiveBuffer_ + recvBufferCursorR_, recvBufferCursorW_ - recvBufferCursorR_);
81         if (memcpyResult != EOK) {
82             recvBufferCursorW_ = 0; // drop data in buffer, if memmove failed
83         } else {
84             recvBufferCursorW_ = recvBufferCursorW_ - recvBufferCursorR_;
85         }
86         recvBufferCursorR_ = 0;
87     }
88 }
89 
GetSendBufferAndLock(uint32_t size)90 char *BufferObject::GetSendBufferAndLock(uint32_t size)
91 {
92     uint32_t needSize = GetNeedBufferSize(size);
93     if (needSize == 0) {
94         return nullptr;
95     }
96     sendMutex_.lock();
97     if (!ExpandSendBuffer(size)) {
98         sendMutex_.unlock();
99         return nullptr;
100     }
101 
102     /* attention: need unlock mutex by caller */
103     return sendBuffer_;
104 }
105 
106 /* this function should be call in mutex locked */
ExpandSendBuffer(uint32_t size)107 bool BufferObject::ExpandSendBuffer(uint32_t size)
108 {
109     uint32_t needSize = GetNeedBufferSize(size);
110     if (needSize == 0) {
111         return true;
112     }
113     if (needSize > sendBuffSize_) {
114         char *newBuffer_ = new (std::nothrow) char[needSize];
115         if (newBuffer_ == nullptr) {
116             return false;
117         }
118 
119         if ((sendBuffer_ != nullptr) && (sendBuffSize_ != 0)) {
120             int memcpyResult = memcpy_s(newBuffer_, needSize, sendBuffer_, sendBuffSize_);
121             if (memcpyResult != 0) {
122                 delete[] newBuffer_;
123                 return false;
124             }
125         }
126 
127         delete[] sendBuffer_;
128         sendBuffer_ = newBuffer_;
129         sendBuffSize_ = needSize;
130     }
131     return true;
132 }
133 
GetReceiveBufferAndLock(uint32_t size)134 char *BufferObject::GetReceiveBufferAndLock(uint32_t size)
135 {
136     uint32_t needSize = GetNeedBufferSize(size);
137     if (needSize == 0) {
138         return nullptr;
139     }
140     recvMutex_.lock();
141     if (needSize > recvBuffSize_) {
142         char *newBuffer_ = new (std::nothrow) char[needSize];
143         if (newBuffer_ == nullptr) {
144             recvMutex_.unlock();
145             return nullptr;
146         }
147 
148         if ((receiveBuffer_ != nullptr) && (recvBuffSize_ != 0)) {
149             int memcpyResult = memcpy_s(newBuffer_, needSize, receiveBuffer_, recvBuffSize_);
150             if (memcpyResult != 0) {
151                 delete[] newBuffer_;
152                 recvMutex_.unlock();
153                 return nullptr;
154             }
155         }
156 
157         delete[] receiveBuffer_;
158         receiveBuffer_ = newBuffer_;
159         recvBuffSize_ = needSize;
160     }
161 
162     /* attention: need unlock mutex by caller */
163     return receiveBuffer_;
164 }
165 
ReleaseSendBufferLock()166 void BufferObject::ReleaseSendBufferLock()
167 {
168     sendMutex_.unlock();
169 }
170 
ReleaseReceiveBufferLock()171 void BufferObject::ReleaseReceiveBufferLock()
172 {
173     recvMutex_.unlock();
174 }
175 
GetReceiveBufferWriteCursor() const176 ssize_t BufferObject::GetReceiveBufferWriteCursor() const
177 {
178     return recvBufferCursorW_;
179 }
180 
SetReceiveBufferWriteCursor(ssize_t newWriteCursor)181 void BufferObject::SetReceiveBufferWriteCursor(ssize_t newWriteCursor)
182 {
183     recvBufferCursorW_ = newWriteCursor;
184 }
185 
GetReceiveBufferReadCursor() const186 ssize_t BufferObject::GetReceiveBufferReadCursor() const
187 {
188     return recvBufferCursorR_;
189 }
190 
SetReceiveBufferReadCursor(ssize_t newReadCursor)191 void BufferObject::SetReceiveBufferReadCursor(ssize_t newReadCursor)
192 {
193     recvBufferCursorR_ = newReadCursor;
194 }
195 
GetSendBufferWriteCursor() const196 ssize_t BufferObject::GetSendBufferWriteCursor() const
197 {
198     return sendBufferCursorW_;
199 }
200 
SetSendBufferWriteCursor(ssize_t newWriteCursor)201 void BufferObject::SetSendBufferWriteCursor(ssize_t newWriteCursor)
202 {
203     sendBufferCursorW_ = newWriteCursor;
204 }
205 
GetSendBufferReadCursor() const206 ssize_t BufferObject::GetSendBufferReadCursor() const
207 {
208     return sendBufferCursorR_;
209 }
210 
SetSendBufferReadCursor(ssize_t newReadCursor)211 void BufferObject::SetSendBufferReadCursor(ssize_t newReadCursor)
212 {
213     sendBufferCursorR_ = newReadCursor;
214 }
215 
GetNeedBufferSize(uint32_t size) const216 uint32_t BufferObject::GetNeedBufferSize(uint32_t size) const
217 {
218     if (size <= SOCKET_BUFF_SIZE_USER_S) {
219         return SOCKET_BUFF_SIZE_USER_S;
220     } else if (size <= SOCKET_BUFF_SIZE_USER_M) {
221         return SOCKET_BUFF_SIZE_USER_M;
222     } else if (size <= SOCKET_BUFF_SIZE_USER_L) {
223         return SOCKET_BUFF_SIZE_USER_L;
224     } else if (size <= SOCKET_BUFF_SIZE_USER_HUGE) {
225         return SOCKET_BUFF_SIZE_USER_HUGE;
226     } else {
227         return 0;
228     }
229 }
230 
GetSendBufferSize() const231 uint32_t BufferObject::GetSendBufferSize() const
232 {
233     return sendBuffSize_;
234 }
235 
GetRecvBufferSize() const236 uint32_t BufferObject::GetRecvBufferSize() const
237 {
238     return recvBuffSize_;
239 }
240 } // namespace OHOS
241