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