1 /*
2 * Copyright (C) 2021-2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "bt_fwk_socket"
17 #endif
18
19 #include "bluetooth_socket.h"
20
21 #include <sys/socket.h>
22 #include <string>
23 #include <unistd.h>
24 #include <atomic>
25 #include "bluetooth_log.h"
26 #include "bluetooth_host.h"
27 #include "bluetooth_host_proxy.h"
28 #include "bluetooth_utils.h"
29 #include "bluetooth_socket_proxy.h"
30 #include "hisysevent.h"
31 #include "ipc_skeleton.h"
32 #include "iservice_registry.h"
33 #include "securec.h"
34 #include "system_ability_definition.h"
35 #include "raw_address.h"
36 #include "bluetooth_socket_observer_stub.h"
37 #include "bluetooth_profile_manager.h"
38 #ifdef RES_SCHED_SUPPORT
39 #include "res_type.h"
40 #include "res_sched_client.h"
41 #endif
42
43 namespace OHOS {
44 namespace Bluetooth {
45 const int LENGTH = 18;
46 const int MIN_BUFFER_SIZE_TO_SET = 4 * 1024; // 4KB
47 const int MAX_BUFFER_SIZE_TO_SET = 50 * 1024; // 50KB
48 const int ADDR_OFFSET = 1; // state(1)
49 const int TX_OFFSET = 7; // state(1)+addr(6)
50 const int RX_OFFSET = 9; // state(1)+addr(6)+tx(2)
51 const int SOCKET_RECV_ADDR_SIZE = 6;
52 const int SOCKET_RECV_TXRX_SIZE = 2;
53 const int SOCKET_RECV_CHANNEL_SIZE = 4;
54 const int SOCKET_RECV_FD_SIZE = 14;
55 const int SOCKET_RECV_FD_SIGNAL = 11; // state(1)+addr(6)+tx(2)+rx(2)
56
57 constexpr char BLUETOOTH_UE_DOMAIN[] = "BLUETOOTH_UE";
58 std::mutex g_socketProxyMutex;
59
60 #define SPTR_SOCKET_CBACK(cbSptr, func, ...) \
61 do { \
62 if (cbSptr) { \
63 cbSptr->func(__VA_ARGS__); \
64 } else { \
65 HILOGE(#cbSptr ": callback is nullptr"); \
66 } \
67 } while (0)
68
ReportDataToRss(const std::string & action,int id,const std::string & address,int pid,int uid)69 static void ReportDataToRss(const std::string &action, int id, const std::string &address, int pid, int uid)
70 {
71 #ifdef RES_SCHED_SUPPORT
72 HILOGD("report SPP_CONNECT_STATE");
73 std::unordered_map<std::string, std::string> payload;
74 payload["ACTION"] = action;
75 payload["ID"] = std::to_string(id);
76 payload["ADDRESS"] = address;
77 payload["PID"] = std::to_string(pid);
78 payload["UID"] = std::to_string(uid);
79 ResourceSchedule::ResSchedClient::GetInstance().ReportData(
80 OHOS::ResourceSchedule::ResType::RES_TYPE_BT_SERVICE_EVENT,
81 OHOS::ResourceSchedule::ResType::BtServiceEvent::SPP_CONNECT_STATE,
82 payload);
83 #endif
84 }
85
86 struct ClientSocket::impl {
87 impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth);
88 impl(int fd, std::string address, BtSocketType type);
89 impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth,
90 std::shared_ptr<BluetoothConnectionObserver> observer);
~implOHOS::Bluetooth::ClientSocket::impl91 ~impl()
92 {
93 if (fd_ > 0) {
94 shutdown(fd_, SHUT_RD);
95 shutdown(fd_, SHUT_WR);
96 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
97 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty",
98 "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
99 HiSysEventWrite(BLUETOOTH_UE_DOMAIN, "SOCKET_DISCONN", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
100 "PNAMEID", "Bluetooth", "PVERSIONID", "1.0", "DEV_ADDRESS", GetEncryptAddr(address_),
101 "SCENE_CODE", fd_);
102 ReportDataToRss("close", fd_, "empty", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
103 HILOGI("fd closed, fd_: %{public}d", fd_);
104 close(fd_);
105 fd_ = -1;
106 }
107 }
108
109 __attribute__((no_sanitize("cfi")))
CloseOHOS::Bluetooth::ClientSocket::impl110 void Close()
111 {
112 HILOGD("enter");
113 if (socketStatus_ == SOCKET_CLOSED) {
114 HILOGD("The socketStatus_ is already SOCKET_CLOSED");
115 return;
116 } else {
117 socketStatus_ = SOCKET_CLOSED;
118 if (fd_ > 0) {
119 shutdown(fd_, SHUT_RD);
120 shutdown(fd_, SHUT_WR);
121 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
122 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty",
123 "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
124 HiSysEventWrite(BLUETOOTH_UE_DOMAIN, "SOCKET_DISCONN", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
125 "PNAMEID", "Bluetooth", "PVERSIONID", "1.0", "DEV_ADDRESS", GetEncryptAddr(address_),
126 "SCENE_CODE", fd_);
127 ReportDataToRss("close", fd_, "empty", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
128 HILOGI("fd closed, fd_: %{public}d", fd_);
129 close(fd_);
130 fd_ = -1;
131 } else {
132 HILOGE("socket not created");
133 }
134 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
135 CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
136 bluetooth::Uuid tempUuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits());
137 if (!observerImp_) {
138 HILOGD("observerImp_ is nullptr");
139 return;
140 }
141 proxy->DeregisterClientObserver(BluetoothRawAddress(remoteDevice_.GetDeviceAddr()), tempUuid,
142 observerImp_);
143 }
144 }
145
GetPacketSizeFromBufOHOS::Bluetooth::ClientSocket::impl146 uint16_t GetPacketSizeFromBuf(const uint8_t recvBuf[], int recvBufLen) const
147 {
148 uint16_t shortBuf;
149 CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf");
150 CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen");
151 CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0,
152 "getpacketsize failed, memcpy_s fail");
153 return shortBuf;
154 }
155
RecvSocketSignalOHOS::Bluetooth::ClientSocket::impl156 bool RecvSocketSignal()
157 {
158 uint8_t signalBuf[SOCKET_RECV_FD_SIGNAL] = {0};
159 #ifdef DARWIN_PLATFORM
160 int recvBufSize = recv(fd_, signalBuf, sizeof(signalBuf), 0);
161 #else
162 int recvBufSize = recv(fd_, signalBuf, sizeof(signalBuf), MSG_WAITALL);
163 #endif
164 CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_FD_SIGNAL, false, "recv signal error, service closed");
165 bool state = signalBuf[0];
166 // remote addr has been obtained, no need obtain again
167 maxTxPacketSize_ = GetPacketSizeFromBuf(signalBuf + TX_OFFSET, SOCKET_RECV_FD_SIGNAL - TX_OFFSET);
168 maxRxPacketSize_ = GetPacketSizeFromBuf(signalBuf + RX_OFFSET, SOCKET_RECV_FD_SIGNAL - RX_OFFSET);
169
170 return state;
171 }
172
getSecurityFlagsOHOS::Bluetooth::ClientSocket::impl173 int getSecurityFlags()
174 {
175 int flags = 0;
176 if (auth_) {
177 flags |= FLAG_AUTH;
178 flags |= FLAG_ENCRYPT;
179 }
180 return flags;
181 }
182
GetInputStreamOHOS::Bluetooth::ClientSocket::impl183 std::shared_ptr<InputStream> GetInputStream()
184 {
185 HILOGD("enter");
186 if (inputStream_ == nullptr) {
187 HILOGE("inputStream is NULL, failed. please Connect");
188 }
189 return inputStream_;
190 }
191
GetOutputStreamOHOS::Bluetooth::ClientSocket::impl192 std::shared_ptr<OutputStream> GetOutputStream()
193 {
194 HILOGD("enter");
195 if (outputStream_ == nullptr) {
196 HILOGE("outputStream is NULL, failed. please Connect");
197 }
198 return outputStream_;
199 }
200
GetRemoteDeviceOHOS::Bluetooth::ClientSocket::impl201 BluetoothRemoteDevice &GetRemoteDevice()
202 {
203 HILOGD("enter");
204 return remoteDevice_;
205 }
206
IsConnectedOHOS::Bluetooth::ClientSocket::impl207 bool IsConnected()
208 {
209 HILOGD("enter");
210 return socketStatus_ == SOCKET_CONNECTED;
211 }
212
SetBufferSizeOHOS::Bluetooth::ClientSocket::impl213 int SetBufferSize(int bufferSize)
214 {
215 HILOGI("SetBufferSize bufferSize is %{public}d.", bufferSize);
216 if (bufferSize < MIN_BUFFER_SIZE_TO_SET || bufferSize > MAX_BUFFER_SIZE_TO_SET) {
217 HILOGE("SetBufferSize param is invalid.");
218 return RET_BAD_PARAM;
219 }
220
221 if (fd_ <= 0) {
222 HILOGE("SetBufferSize socket fd invalid.");
223 return RET_BAD_STATUS;
224 }
225
226 const std::pair<const char*, int> sockOpts[] = {
227 {"recvBuffer", SO_RCVBUF},
228 {"sendBuffer", SO_SNDBUF},
229 };
230 for (auto opt : sockOpts) {
231 int curSize = 0;
232 socklen_t optlen = sizeof(curSize);
233 if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) {
234 HILOGE("SetBufferSize getsockopt %{public}s failed.", opt.first);
235 return RET_BAD_STATUS;
236 }
237 HILOGI("SetBufferSize %{public}s before set size is %{public}d.", opt.first, curSize);
238
239 if (curSize != bufferSize) {
240 int setSize = bufferSize / 2;
241 if (setsockopt(fd_, SOL_SOCKET, opt.second, &setSize, sizeof(setSize)) != 0) {
242 HILOGE("SetBufferSize setsockopt %{public}s failed.", opt.first);
243 return RET_BAD_STATUS;
244 }
245
246 curSize = 0;
247 if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) {
248 HILOGE("SetBufferSize after getsockopt %{public}s failed.", opt.first);
249 return RET_BAD_STATUS;
250 }
251 HILOGI("SetBufferSize %{public}s after set size is %{public}d.", opt.first, curSize);
252 }
253 }
254
255 return RET_NO_ERROR;
256 }
257
RecvSocketPsmOrScnOHOS::Bluetooth::ClientSocket::impl258 bool RecvSocketPsmOrScn()
259 {
260 int channel = 0;
261 #ifdef DARWIN_PLATFORM
262 int recvBufSize = recv(fd_, &channel, sizeof(channel), 0);
263 #else
264 int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL);
265 #endif
266 CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false,
267 "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_);
268 CHECK_AND_RETURN_LOG_RET(channel > 0, false, "recv channel error, invalid channel:%{public}d", channel);
269 HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_);
270 socketChannel_ = channel;
271 return true;
272 }
273
274 // user register observer
275 std::shared_ptr<BluetoothConnectionObserver> observer_;
276 class BluetoothSocketObserverImp;
277
278 // socket observer
279 sptr<BluetoothSocketObserverImp> observerImp_ = nullptr;
280 std::shared_ptr<InputStream> inputStream_ {
281 nullptr
282 };
283 std::shared_ptr<OutputStream> outputStream_ {
284 nullptr
285 };
286 bool Init(std::weak_ptr<ClientSocket> client);
287 BluetoothRemoteDevice remoteDevice_;
288 UUID uuid_;
289 BtSocketType type_;
290 std::string address_;
291 int fd_;
292 bool auth_;
293 int socketStatus_;
294 std::atomic<int> socketChannel_{ -1 };
295 std::atomic<uint32_t> maxTxPacketSize_{ 0 };
296 std::atomic<uint32_t> maxRxPacketSize_{ 0 };
297 };
298
299 class ClientSocket::impl::BluetoothSocketObserverImp : public BluetoothClientSocketObserverStub {
300 public:
GetClientSocketSptr(void)301 inline std::shared_ptr<ClientSocket> GetClientSocketSptr(void)
302 {
303 auto clientSptr = clientSocket_.lock();
304 if (!clientSptr) {
305 HILOGE("clientSocket_ is nullptr");
306 return nullptr;
307 }
308 return clientSptr;
309 }
310
BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket)311 explicit BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket) : clientSocket_(clientSocket)
312 {
313 HILOGD("enter");
314 }
~BluetoothSocketObserverImp()315 ~BluetoothSocketObserverImp()
316 {
317 HILOGD("enter");
318 }
319
320 __attribute__((no_sanitize("cfi")))
OnConnectionStateChanged(const CallbackParam & callbackParam)321 void OnConnectionStateChanged(const CallbackParam &callbackParam) override
322 {
323 HILOGD("dev: %{public}s, uuid:%{public}s, status: %{public}d, psm: %{public}d, result: %{public}d",
324 GetEncryptAddr((callbackParam.dev).GetAddress()).c_str(), callbackParam.uuid.ToString().c_str(),
325 callbackParam.status, callbackParam.psm, callbackParam.result);
326 BluetoothRemoteDevice device(callbackParam.dev.GetAddress(), BTTransport::ADAPTER_BREDR);
327 UUID btUuid = UUID::ConvertFrom128Bits(callbackParam.uuid.ConvertTo128Bits());
328 auto clientSptr = GetClientSocketSptr();
329 if (!clientSptr) {
330 HILOGE("clientSptr is nullptr");
331 return;
332 }
333 if (!clientSptr->pimpl) {
334 HILOGE("impl is nullptr");
335 return;
336 }
337 CallbackConnectParam callbackConnectParam = {
338 .addr = device,
339 .uuid = btUuid,
340 .status = callbackParam.status,
341 .result = callbackParam.result,
342 .type = callbackParam.type,
343 .psm = callbackParam.psm,
344 };
345 SPTR_SOCKET_CBACK(clientSptr->pimpl->observer_, OnConnectionStateChanged, callbackConnectParam);
346 }
347
348 private:
349 std::weak_ptr<ClientSocket> clientSocket_;
350 };
351
Init(std::weak_ptr<ClientSocket> client)352 bool ClientSocket::impl::Init(std::weak_ptr<ClientSocket> client)
353 {
354 if (observerImp_ != nullptr) {
355 return true;
356 }
357 observerImp_ = new(std::nothrow) BluetoothSocketObserverImp(client);
358 if (observerImp_ == nullptr) {
359 return false;
360 }
361 return true;
362 }
363
impl(const BluetoothRemoteDevice & addr,UUID uuid,BtSocketType type,bool auth)364 ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth)
365 : inputStream_(nullptr),
366 outputStream_(nullptr),
367 remoteDevice_(addr),
368 uuid_(uuid),
369 type_(type),
370 fd_(-1),
371 auth_(auth),
372 socketStatus_(SOCKET_INIT)
373 {
374 HILOGD("enter 4 parameters");
375 }
376
impl(int fd,std::string address,BtSocketType type)377 ClientSocket::impl::impl(int fd, std::string address, BtSocketType type)
378 : inputStream_(std::make_unique<InputStream>(fd)),
379 outputStream_(std::make_unique<OutputStream>(fd)),
380 remoteDevice_(BluetoothRemoteDevice(address, 0)),
381 type_(type),
382 address_(address),
383 fd_(fd),
384 auth_(false),
385 socketStatus_(SOCKET_CONNECTED)
386 {
387 HILOGD("enter 3 parameters");
388 }
389
impl(const BluetoothRemoteDevice & addr,UUID uuid,BtSocketType type,bool auth,std::shared_ptr<BluetoothConnectionObserver> observer)390 ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth,
391 std::shared_ptr<BluetoothConnectionObserver> observer)
392 : observer_(observer),
393 inputStream_(nullptr),
394 outputStream_(nullptr),
395 remoteDevice_(addr),
396 uuid_(uuid),
397 type_(type),
398 fd_(-1),
399 auth_(auth),
400 socketStatus_(SOCKET_INIT)
401 {
402 HILOGD("enter 5 parameters");
403 }
404
ClientSocket(const BluetoothRemoteDevice & bda,UUID uuid,BtSocketType type,bool auth)405 ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth)
406 : pimpl(new ClientSocket::impl(bda, uuid, type, auth))
407 {}
408
ClientSocket(int fd,std::string address,BtSocketType type)409 ClientSocket::ClientSocket(int fd, std::string address, BtSocketType type)
410 : pimpl(new ClientSocket::impl(fd, address, type))
411 {}
412
ClientSocket(const BluetoothRemoteDevice & bda,UUID uuid,BtSocketType type,bool auth,std::shared_ptr<BluetoothConnectionObserver> observer)413 ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth,
414 std::shared_ptr<BluetoothConnectionObserver> observer)
415 : pimpl(new ClientSocket::impl(bda, uuid, type, auth, observer))
416 {}
417
~ClientSocket()418 ClientSocket::~ClientSocket()
419 {}
420
Init()421 bool ClientSocket::Init()
422 {
423 HILOGI("ClientSocket Init");
424 return pimpl->Init(weak_from_this());
425 }
426
Connect(int psm)427 int ClientSocket::Connect(int psm)
428 {
429 HILOGD("enter");
430 if (pimpl->type_ == TYPE_L2CAP_LE) {
431 CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON");
432 } else {
433 CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON");
434 }
435
436 if (!pimpl->Init(weak_from_this())) {
437 HILOGE("clientSocket proxy is nullptr");
438 return BT_ERR_INTERNAL_ERROR;
439 }
440
441 pimpl->address_ = pimpl->remoteDevice_.GetDeviceAddr();
442 std::string tempAddress = pimpl->address_;
443 CHECK_AND_RETURN_LOG_RET(tempAddress.size(), BtStatus::BT_FAILURE, "address size error");
444 CHECK_AND_RETURN_LOG_RET(pimpl->socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE, "socket closed");
445 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
446 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "proxy is nullptr");
447
448 bluetooth::Uuid tempUuid = bluetooth::Uuid::ConvertFrom128Bits(pimpl->uuid_.ConvertTo128Bits());
449 int ret = proxy->RegisterClientObserver(BluetoothRawAddress(pimpl->address_), tempUuid,
450 pimpl->observerImp_);
451 CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, ret, "regitser observer fail, ret = %d", ret);
452
453 ConnectSocketParam param {
454 .addr = tempAddress,
455 .uuid = tempUuid,
456 .securityFlag = (int32_t)pimpl->getSecurityFlags(),
457 .type = (int32_t)pimpl->type_,
458 .psm = psm
459 };
460 ret = proxy->Connect(param, pimpl->fd_);
461 CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, ret, "Connect error %{public}d", ret);
462
463 HILOGI("fd_: %{public}d", pimpl->fd_);
464 CHECK_AND_RETURN_LOG_RET(pimpl->fd_ != -1, BtStatus::BT_FAILURE, "connect failed!");
465 CHECK_AND_RETURN_LOG_RET(pimpl->RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed");
466
467 bool recvret = pimpl->RecvSocketSignal();
468 HILOGI("recvret: %{public}d", recvret);
469 pimpl->inputStream_ = std::make_unique<InputStream>(pimpl->fd_);
470 pimpl->outputStream_ = std::make_unique<OutputStream>(pimpl->fd_);
471 CHECK_AND_RETURN_LOG_RET(recvret, BtStatus::BT_FAILURE, "recvSocketSignal connect failed!");
472 pimpl->socketStatus_ = SOCKET_CONNECTED;
473 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
474 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", pimpl->fd_, "ADDRESS",
475 GetEncryptAddr(tempAddress), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
476 ReportDataToRss("connect", pimpl->fd_, GetEncryptAddr(tempAddress), IPCSkeleton::GetCallingPid(),
477 IPCSkeleton::GetCallingUid());
478 return BtStatus::BT_SUCCESS;
479 }
480
Close()481 void ClientSocket::Close()
482 {
483 HILOGD("enter");
484 return pimpl->Close();
485 }
486
GetInputStream()487 std::shared_ptr<InputStream> ClientSocket::GetInputStream()
488 {
489 HILOGD("enter");
490 return pimpl->GetInputStream();
491 }
492
GetOutputStream()493 std::shared_ptr<OutputStream> ClientSocket::GetOutputStream()
494 {
495 HILOGD("enter");
496 return pimpl->GetOutputStream();
497 }
498
GetRemoteDevice()499 BluetoothRemoteDevice &ClientSocket::GetRemoteDevice()
500 {
501 HILOGD("enter");
502 return pimpl->GetRemoteDevice();
503 }
504
IsConnected() const505 bool ClientSocket::IsConnected() const
506 {
507 HILOGD("enter");
508 return pimpl->IsConnected();
509 }
510
SetBufferSize(int bufferSize)511 int ClientSocket::SetBufferSize(int bufferSize)
512 {
513 HILOGD("enter");
514 return pimpl->SetBufferSize(bufferSize);
515 }
516
GetSocketFd()517 int ClientSocket::GetSocketFd()
518 {
519 HILOGD("enter");
520 return pimpl->fd_;
521 }
522
GetL2capPsm()523 int ClientSocket::GetL2capPsm()
524 {
525 HILOGI("psm:%{public}d", pimpl->socketChannel_.load());
526 return pimpl->socketChannel_;
527 }
528
GetRfcommScn()529 int ClientSocket::GetRfcommScn()
530 {
531 HILOGI("scn:%{public}d", pimpl->socketChannel_.load());
532 return pimpl->socketChannel_;
533 }
534
GetMaxTransmitPacketSize()535 uint32_t ClientSocket::GetMaxTransmitPacketSize()
536 {
537 HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load());
538 return pimpl->maxTxPacketSize_;
539 }
540
GetMaxReceivePacketSize()541 uint32_t ClientSocket::GetMaxReceivePacketSize()
542 {
543 HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load());
544 return pimpl->maxRxPacketSize_;
545 }
546
IsAllowSocketConnect(int socketType)547 bool ClientSocket::IsAllowSocketConnect(int socketType)
548 {
549 HILOGI("socketType: %{public}d", socketType);
550 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
551 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, true, "proxy is nullptr");
552 bool isAllowed = true;
553 int ret = proxy->IsAllowSocketConnect(socketType, pimpl->remoteDevice_.GetDeviceAddr(), isAllowed);
554 CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, true, "check if socket allowed failed, error: %{public}d", ret);
555 return isAllowed;
556 }
557
558 struct ServerSocket::impl {
559 impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt);
~implOHOS::Bluetooth::ServerSocket::impl560 ~impl()
561 {
562 if (fd_ > 0) {
563 shutdown(fd_, SHUT_RD);
564 shutdown(fd_, SHUT_WR);
565 close(fd_);
566 HILOGI("fd closed, fd_: %{public}d", fd_);
567 fd_ = -1;
568 }
569 }
570
ListenOHOS::Bluetooth::ServerSocket::impl571 int Listen()
572 {
573 HILOGD("enter");
574 if (type_ == TYPE_L2CAP_LE) {
575 CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON");
576 } else {
577 CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON");
578 }
579
580 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
581 if (!proxy) {
582 HILOGE("failed, proxy is nullptr");
583 socketStatus_ = SOCKET_CLOSED;
584 return BT_ERR_SERVICE_DISCONNECTED;
585 }
586 CHECK_AND_RETURN_LOG_RET(socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE,
587 "failed, socketStatus_ is SOCKET_CLOSED");
588
589 ListenSocketParam param {
590 .name = name_,
591 .uuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits()),
592 .securityFlag = (int32_t)getSecurityFlags(),
593 .type = (int32_t)type_,
594 .observer = observer_
595 };
596 int ret = proxy->Listen(param, fd_);
597 if (ret != BT_NO_ERROR) {
598 HILOGE("Listen error %{public}d.", ret);
599 socketStatus_ = SOCKET_CLOSED;
600 return ret;
601 }
602
603 if (fd_ == BT_INVALID_SOCKET_FD) {
604 HILOGE("listen socket failed");
605 socketStatus_ = SOCKET_CLOSED;
606 return BT_ERR_INVALID_STATE;
607 }
608
609 CHECK_AND_RETURN_LOG_RET(RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed");
610
611 if (socketStatus_ == SOCKET_INIT) {
612 socketStatus_ = SOCKET_LISTENING;
613 } else {
614 HILOGE("failed, socketStatus_: %{public}d is not SOCKET_INIT", socketStatus_);
615 close(fd_);
616 socketStatus_ = SOCKET_CLOSED;
617 return BT_ERR_INVALID_STATE;
618 }
619
620 return BT_NO_ERROR;
621 }
622
getSecurityFlagsOHOS::Bluetooth::ServerSocket::impl623 int getSecurityFlags()
624 {
625 int flags = 0;
626 if (encrypt_) {
627 flags |= FLAG_AUTH;
628 flags |= FLAG_ENCRYPT;
629 }
630 return flags;
631 }
632
AcceptOHOS::Bluetooth::ServerSocket::impl633 std::shared_ptr<ClientSocket> Accept(int timeout)
634 {
635 HILOGD("enter");
636 if (socketStatus_ != SOCKET_LISTENING) {
637 HILOGE("socket is not in listen state");
638 return nullptr;
639 }
640 // If timeout < 0, keeps waiting in blocking mode
641 if (timeout > 0) {
642 struct timeval time = {timeout, 0};
643 setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
644 setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
645 }
646
647 acceptFd_ = RecvSocketFd();
648 HILOGI("RecvSocketFd acceptFd: %{public}d", acceptFd_);
649 if (acceptFd_ <= 0) {
650 return nullptr;
651 }
652 if (timeout > 0) {
653 struct timeval time = {0, 0};
654 setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
655 setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
656 }
657
658 std::shared_ptr<ClientSocket> clientSocket = std::make_shared<ClientSocket>(acceptFd_, acceptAddress_, type_);
659
660 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
661 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", acceptFd_, "ADDRESS",
662 GetEncryptAddr(acceptAddress_), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
663 ReportDataToRss("connect", acceptFd_, GetEncryptAddr(acceptAddress_), IPCSkeleton::GetCallingPid(),
664 IPCSkeleton::GetCallingUid());
665 return clientSocket;
666 }
667
RecvSocketFdOHOS::Bluetooth::ServerSocket::impl668 int RecvSocketFd()
669 {
670 HILOGD("enter");
671 char ccmsg[CMSG_SPACE(sizeof(int))];
672 char buffer[SOCKET_RECV_FD_SIZE];
673 struct iovec io = {.iov_base = buffer, .iov_len = sizeof(buffer)};
674 struct msghdr msg;
675 (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
676 msg.msg_control = ccmsg;
677 msg.msg_controllen = sizeof(ccmsg);
678 msg.msg_iov = &io;
679 msg.msg_iovlen = 1;
680
681 #ifdef DARWIN_PLATFORM
682 int rv = TEMP_FAILURE_RETRY(recvmsg(fd_, &msg, 0));
683 #else
684 int rv = TEMP_FAILURE_RETRY(recvmsg(fd_, &msg, MSG_NOSIGNAL));
685 #endif
686 if (rv == -1) {
687 HILOGE("[sock] recvmsg error %{public}d, fd: %{public}d", errno, fd_);
688 return BtStatus::BT_FAILURE;
689 }
690 struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
691 CHECK_AND_RETURN_LOG_RET(cmptr != nullptr, BtStatus::BT_FAILURE, "cmptr error");
692 CHECK_AND_RETURN_LOG_RET(cmptr->cmsg_len == CMSG_LEN(sizeof(int)) && cmptr->cmsg_level == SOL_SOCKET
693 && cmptr->cmsg_type == SCM_RIGHTS, BtStatus::BT_FAILURE,
694 "recvmsg error, len:%{public}d level:%{public}d type:%{public}d",
695 cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);
696 int clientFd = *(reinterpret_cast<int *>(CMSG_DATA(cmptr)));
697
698 uint8_t recvBuf[rv];
699 (void)memset_s(&recvBuf, sizeof(recvBuf), 0, sizeof(recvBuf));
700 CHECK_AND_RETURN_LOG_RET(memcpy_s(recvBuf, sizeof(recvBuf), (uint8_t *)msg.msg_iov[0].iov_base, rv) == EOK,
701 BtStatus::BT_FAILURE, "RecvSocketFd, recvBuf memcpy_s fail");
702
703 uint8_t buf[SOCKET_RECV_ADDR_SIZE] = {0};
704 CHECK_AND_RETURN_LOG_RET(memcpy_s(buf, sizeof(buf), &recvBuf[ADDR_OFFSET], sizeof(buf)) == EOK,
705 BtStatus::BT_FAILURE, "RecvSocketFd, buf memcpy_s fail");
706
707 char token[LENGTH] = {0};
708 (void)sprintf_s(token, sizeof(token), "%02X:%02X:%02X:%02X:%02X:%02X",
709 buf[0x05], buf[0x04], buf[0x03], buf[0x02], buf[0x01], buf[0x00]);
710 BluetoothRawAddress rawAddr {token};
711 // If the random address fails to be obtained, the actual address is returned by default.
712 std::string randomAddr = rawAddr.GetAddress();
713 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
714 host->GetRandomAddress(rawAddr.GetAddress(), randomAddr);
715 acceptAddress_ = randomAddr;
716
717 maxTxPacketSize_ = GetPacketSizeFromBuf(recvBuf + TX_OFFSET, rv - TX_OFFSET);
718 maxRxPacketSize_ = GetPacketSizeFromBuf(recvBuf + RX_OFFSET, rv - RX_OFFSET);
719 return clientFd;
720 }
721
GetPacketSizeFromBufOHOS::Bluetooth::ServerSocket::impl722 uint16_t GetPacketSizeFromBuf(uint8_t recvBuf[], int recvBufLen)
723 {
724 uint16_t shortBuf;
725 CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf");
726 CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen");
727 CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0,
728 "getpacketsize failed, memcpy_s fail");
729 return shortBuf;
730 }
731
RecvSocketPsmOrScnOHOS::Bluetooth::ServerSocket::impl732 bool RecvSocketPsmOrScn()
733 {
734 int channel = 0;
735 #ifdef DARWIN_PLATFORM
736 int recvBufSize = recv(fd_, &channel, sizeof(channel), 0);
737 #else
738 int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL);
739 #endif
740 CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false,
741 "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_);
742 CHECK_AND_RETURN_LOG_RET(channel > 0, false,
743 "recv channel error, errno:%{public}d, fd_:%{public}d", errno, fd_);
744 HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_);
745 socketChannel_ = channel;
746 return true;
747 }
748
CloseOHOS::Bluetooth::ServerSocket::impl749 void Close()
750 {
751 HILOGD("enter");
752 if (socketStatus_ == SOCKET_CLOSED) {
753 HILOGD("The socketStatus_ is already SOCKET_CLOSED");
754 return;
755 } else {
756 socketStatus_ = SOCKET_CLOSED;
757 if (fd_ > 0) {
758 shutdown(fd_, SHUT_RD);
759 shutdown(fd_, SHUT_WR);
760 HILOGI("fd closed, fd_: %{public}d", fd_);
761 close(fd_);
762 fd_ = -1;
763 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
764 CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
765 proxy->DeregisterServerObserver(observer_);
766 return;
767 } else {
768 HILOGE("socket not created");
769 return;
770 }
771 }
772 }
773
GetStringTagOHOS::Bluetooth::ServerSocket::impl774 const std::string &GetStringTag()
775 {
776 HILOGD("enter");
777 if (socketStatus_ == SOCKET_CLOSED) {
778 HILOGE("socketStatus_ is SOCKET_CLOSED");
779 socketServiceType_ = "";
780 } else {
781 socketServiceType_ = "ServerSocket:";
782 socketServiceType_.append(" Type: ").append(ConvertTypeToString(type_))
783 .append(" ServerName: ").append(name_);
784 }
785 return socketServiceType_;
786 }
787
ConvertTypeToStringOHOS::Bluetooth::ServerSocket::impl788 static std::string ConvertTypeToString(BtSocketType type)
789 {
790 std::string retStr;
791 if (type == TYPE_RFCOMM) {
792 retStr = "TYPE_RFCOMM";
793 } else if (type == TYPE_L2CAP) {
794 retStr = "TYPE_L2CAP";
795 } else if (type == TYPE_L2CAP_LE) {
796 retStr = "TYPE_L2CAP_LE";
797 } else {
798 retStr = "TYPE_UNKNOW";
799 }
800 return retStr;
801 }
802
803 sptr<BluetoothServerSocketObserverStub> observer_ = nullptr;
804
805 sptr<IBluetoothSocket> proxy;
806 UUID uuid_;
807 BtSocketType type_;
808 bool encrypt_;
809 int fd_;
810 int socketStatus_;
811 std::string name_ {
812 ""
813 };
814 int acceptFd_ = 0;
815 std::string acceptAddress_;
816 std::string socketServiceType_ {
817 ""
818 };
819 std::atomic<int> socketChannel_{ -1 };
820 std::atomic<uint32_t> maxTxPacketSize_{ 0 };
821 std::atomic<uint32_t> maxRxPacketSize_{ 0 };
822 };
823
impl(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)824 ServerSocket::impl::impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
825 : uuid_(uuid), type_(type), encrypt_(encrypt), fd_(-1), socketStatus_(SOCKET_INIT), name_(name)
826 {
827 HILOGD("(4 parameters) starts");
828 observer_ = new BluetoothServerSocketObserverStub();
829 }
830
ServerSocket(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)831 ServerSocket::ServerSocket(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
832 : pimpl(new ServerSocket::impl(name, uuid, type, encrypt))
833 {
834 HILOGD("type:%{public}d encrypt:%{public}d", type, encrypt);
835 }
836
~ServerSocket()837 ServerSocket::~ServerSocket()
838 {}
839
Listen()840 int ServerSocket::Listen()
841 {
842 HILOGD("enter");
843 return pimpl->Listen();
844 }
845
Accept(int timeout)846 std::shared_ptr<ClientSocket> ServerSocket::Accept(int timeout)
847 {
848 HILOGD("enter");
849 return pimpl->Accept(timeout);
850 }
851
Close()852 void ServerSocket::Close()
853 {
854 HILOGD("enter");
855 return pimpl->Close();
856 }
857
GetStringTag()858 const std::string &ServerSocket::GetStringTag()
859 {
860 HILOGD("enter");
861 return pimpl->GetStringTag();
862 }
863
GetL2capPsm()864 int ServerSocket::GetL2capPsm()
865 {
866 HILOGI("psm:%{public}d", pimpl->socketChannel_.load());
867 return pimpl->socketChannel_;
868 }
869
GetRfcommScn()870 int ServerSocket::GetRfcommScn()
871 {
872 HILOGI("scn:%{public}d", pimpl->socketChannel_.load());
873 return pimpl->socketChannel_;
874 }
875
GetMaxTransmitPacketSize()876 uint32_t ServerSocket::GetMaxTransmitPacketSize()
877 {
878 HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load());
879 return pimpl->maxTxPacketSize_;
880 }
881
GetMaxReceivePacketSize()882 uint32_t ServerSocket::GetMaxReceivePacketSize()
883 {
884 HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load());
885 return pimpl->maxRxPacketSize_;
886 }
887
GetSocketFd()888 int ServerSocket::GetSocketFd()
889 {
890 return pimpl->fd_;
891 }
892
BuildInsecureRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)893 std::shared_ptr<ClientSocket> SocketFactory::BuildInsecureRfcommDataSocketByServiceRecord(
894 const BluetoothRemoteDevice &device, const UUID &uuid)
895 {
896 HILOGD("enter");
897 if (device.IsValidBluetoothRemoteDevice()) {
898 return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, false);
899 } else {
900 HILOGE("[sock] Device is not valid.");
901 return nullptr;
902 }
903 }
904
BuildRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)905 std::shared_ptr<ClientSocket> SocketFactory::BuildRfcommDataSocketByServiceRecord(
906 const BluetoothRemoteDevice &device, const UUID &uuid)
907 {
908 HILOGD("enter");
909 if (device.IsValidBluetoothRemoteDevice()) {
910 return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, true);
911 } else {
912 HILOGE("[sock] Device is not valid.");
913 return nullptr;
914 }
915 }
916
DataListenInsecureRfcommByServiceRecord(const std::string & name,const UUID & uuid)917 std::shared_ptr<ServerSocket> SocketFactory::DataListenInsecureRfcommByServiceRecord(
918 const std::string &name, const UUID &uuid)
919 {
920 HILOGD("enter");
921 return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, false);
922 }
923
DataListenRfcommByServiceRecord(const std::string & name,const UUID & uuid)924 std::shared_ptr<ServerSocket> SocketFactory::DataListenRfcommByServiceRecord(const std::string &name, const UUID &uuid)
925 {
926 HILOGD("enter");
927 return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, true);
928 }
929
UpdateCocConnectionParams(CocUpdateSocketParam & param)930 int ClientSocket::UpdateCocConnectionParams(CocUpdateSocketParam ¶m)
931 {
932 HILOGI("UpdateCocConnectionParams enter");
933 BluetoothSocketCocInfo info;
934
935 info.addr = param.addr;
936 info.minInterval = param.minInterval;
937 info.maxInterval = param.maxInterval;
938 info.peripheralLatency = param.peripheralLatency;
939 info.supervisionTimeout = param.supervisionTimeout;
940 info.minConnEventLen = param.minConnEventLen;
941 info.maxConnEventLen = param.maxConnEventLen;
942 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
943 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "proxy is null");
944 return proxy->UpdateCocConnectionParams(info);
945 }
946 } // namespace Bluetooth
947 } // namespace OHOS