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 "obex_socket_transport.h"
17 #include <cstring>
18 #include <iomanip>
19 #include <memory>
20 #include <sstream>
21 #include "log.h"
22 #include "log_util.h"
23 #include "obex_utils.h"
24 #include "packet.h"
25 #include "transport/transport_factory.h"
26
27 namespace OHOS {
28 namespace bluetooth {
ObexSocketTransport(DataTransport * dataTransport,uint16_t sendMtu,uint16_t recvMtu,const std::string & parentTranKey)29 ObexSocketTransport::ObexSocketTransport(
30 DataTransport *dataTransport, uint16_t sendMtu, uint16_t recvMtu, const std::string &parentTranKey)
31 : dataTransport_(std::unique_ptr<DataTransport>(dataTransport))
32 {
33 // sub transport pointer need be release by this class, so we use smart pointer
34 sendMtu_ = sendMtu;
35 recvMtu_ = recvMtu;
36 isConnected_ = true;
37 remoteBtAddr_ = dataTransport_->GetRemoteAddress();
38 tranKey_ = parentTranKey + "-" + remoteBtAddr_.GetAddress();
39 HILOGI("[%{public}s] Create SubSocketTransport, sendMtu = %{public}d, recvMtu = %{public}d",
40 tranKey_.c_str(), sendMtu, recvMtu);
41 }
42
~ObexSocketTransport()43 ObexSocketTransport::~ObexSocketTransport()
44 {
45 HILOGI("Delete ~ObexSocketTransport");
46 }
47
48 // write packet
Write(Packet & pkt)49 bool ObexSocketTransport::Write(Packet &pkt)
50 {
51 HILOGI("[%{public}s] Obex Transport Write: %{public}s", tranKey_.c_str(), ObexUtils::ToDebugString(pkt).c_str());
52 return dataTransport_->Write(&pkt) == 0;
53 }
54
55 // the maximum allowed OBEX packet that can be send over the transport
GetMaxSendPacketSize()56 int ObexSocketTransport::GetMaxSendPacketSize()
57 {
58 return sendMtu_;
59 }
60
61 // the maximum allowed OBEX packet that can be received over the transport
GetMaxReceivePacketSize()62 int ObexSocketTransport::GetMaxReceivePacketSize()
63 {
64 return recvMtu_;
65 }
66
67 // This function is used to get the Bluetooth address of the peer of the connected channel
GetRemoteAddress()68 const RawAddress &ObexSocketTransport::GetRemoteAddress()
69 {
70 return remoteBtAddr_;
71 }
72
73 // is transport Connected
IsConnected()74 bool ObexSocketTransport::IsConnected()
75 {
76 return isConnected_;
77 }
78
79 // get transport key
GetTransportKey()80 const std::string &ObexSocketTransport::GetTransportKey()
81 {
82 return tranKey_;
83 }
84
85 // ObexClientSocketTransport
ObexClientSocketTransport(const Option & option,ObexTransportObserver & observer,utility::Dispatcher & dispatcher)86 ObexClientSocketTransport::ObexClientSocketTransport(
87 const Option &option, ObexTransportObserver &observer, utility::Dispatcher &dispatcher)
88 : ObexClientTransport(observer), dispatcher_(dispatcher),
89 remoteBtAddr_(RawAddress::ConvertToString(option.addr_.addr))
90 {
91 transportObserver_ = std::make_unique<TransportObserver>(*this);
92 uint16_t mtu = option.mtu_;
93 if (mtu < OBEX_MINIMUM_MTU) {
94 mtu = OBEX_MINIMUM_MTU;
95 }
96 if (option.isGoepL2capPSM_) {
97 HILOGI("CreateL2capTransport at lpsm:0x%{public}04X rpsm:0x%{public}04X", option.lpsm_, option.scn_);
98 L2capTransportInfo createInfo = {
99 &remoteBtAddr_, option.lpsm_, option.scn_, mtu, *transportObserver_, dispatcher
100 };
101 dataTransport_ = TransportFactory::CreateL2capTransport(createInfo);
102 } else {
103 OBEX_LOG_INFO("CreateRfcommTransport at scn:0x%04X", option.scn_);
104 dataTransport_ =
105 TransportFactory::CreateRfcommTransport(&remoteBtAddr_, option.scn_, mtu, *transportObserver_, dispatcher);
106 }
107 tranKey_ = MakeTransportKey(option.isGoepL2capPSM_, option.scn_);
108 HILOGI("[%{public}s] Create ObexClientSocketTransport", tranKey_.c_str());
109 }
110
~ObexClientSocketTransport()111 ObexClientSocketTransport::~ObexClientSocketTransport()
112 {}
113
MakeTransportKey(bool isGoepL2capPSM,uint16_t scn)114 std::string ObexClientSocketTransport::MakeTransportKey(bool isGoepL2capPSM, uint16_t scn)
115 {
116 std::stringstream keyStream;
117 keyStream << "CLIENT";
118 if (isGoepL2capPSM) {
119 keyStream << "-L2CAP-";
120 } else {
121 keyStream << "-RFCOMM-";
122 }
123 keyStream << std::uppercase << std::hex << std::setfill('0') << std::setw(TRANSPORT_KEY_NUM_LEN) << scn;
124 keyStream << "-" << PrivateGetRemoteAddress().GetAddress();
125 return keyStream.str();
126 }
127
Connect()128 int ObexClientSocketTransport::Connect()
129 {
130 HILOGI("[%{public}s] Call", tranKey_.c_str());
131 return dataTransport_->Connect();
132 }
133
Disconnect()134 int ObexClientSocketTransport::Disconnect()
135 {
136 HILOGI("[%{public}s] Call", tranKey_.c_str());
137 return dataTransport_->Disconnect();
138 }
139
Write(Packet & pkt)140 bool ObexClientSocketTransport::Write(Packet &pkt)
141 {
142 HILOGI("[%{public}s] Obex Transport Write: %{public}s", tranKey_.c_str(), ObexUtils::ToDebugString(pkt).c_str());
143 return dataTransport_->Write(&pkt) == 0;
144 }
145
146 // the maximum allowed OBEX packet that can be send over the transport
GetMaxSendPacketSize()147 int ObexClientSocketTransport::GetMaxSendPacketSize()
148 {
149 return sendMtu_;
150 }
151
152 // the maximum allowed OBEX packet that can be received over the transport
GetMaxReceivePacketSize()153 int ObexClientSocketTransport::GetMaxReceivePacketSize()
154 {
155 return recvMtu_;
156 }
157
158 // This function is used to get the Bluetooth address of the peer of the connected channel
GetRemoteAddress()159 const RawAddress &ObexClientSocketTransport::GetRemoteAddress()
160 {
161 return PrivateGetRemoteAddress();
162 }
163
PrivateGetRemoteAddress()164 const RawAddress &ObexClientSocketTransport::PrivateGetRemoteAddress()
165 {
166 return remoteBtAddr_;
167 }
168
169 // is transport Connected
IsConnected()170 bool ObexClientSocketTransport::IsConnected()
171 {
172 return isConnected_;
173 }
174
175 // get transport key
GetTransportKey()176 const std::string &ObexClientSocketTransport::GetTransportKey()
177 {
178 return tranKey_;
179 }
180
TransportObserver(ObexClientSocketTransport & obexTran)181 ObexClientSocketTransport::TransportObserver::TransportObserver(ObexClientSocketTransport &obexTran)
182 : obexTran_(obexTran)
183 {}
184
185 // connection success
OnConnected(DataTransport * transport,uint16_t sendMTU,uint16_t recvMTU)186 void ObexClientSocketTransport::TransportObserver::OnConnected(
187 DataTransport *transport, uint16_t sendMTU, uint16_t recvMTU)
188 {
189 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
190 obexTran_.dispatcher_.PostTask(std::bind(
191 &ObexClientSocketTransport::TransportObserver::ProcessOnConnected, this, transport, sendMTU, recvMTU));
192 }
193
194 // The event is triggered when a disconnect request is received.
OnDisconnected(DataTransport * transport)195 void ObexClientSocketTransport::TransportObserver::OnDisconnected(DataTransport *transport)
196 {
197 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
198 obexTran_.dispatcher_.PostTask(
199 std::bind(&ObexClientSocketTransport::TransportObserver::ProcessOnDisconnected, this));
200 }
201
202 // The event is triggered when the disconnection process is successful.
OnDisconnectSuccess(DataTransport * transport)203 void ObexClientSocketTransport::TransportObserver::OnDisconnectSuccess(DataTransport *transport)
204 {
205 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
206 obexTran_.dispatcher_.PostTask(
207 std::bind(&ObexClientSocketTransport::TransportObserver::ProcessOnDisconnectSuccess, this));
208 }
209
210 // when data is received from RFCOMM
OnDataAvailable(DataTransport * transport)211 void ObexClientSocketTransport::TransportObserver::OnDataAvailable(DataTransport *transport)
212 {
213 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
214 obexTran_.dispatcher_.PostTask(
215 std::bind(&ObexClientSocketTransport::TransportObserver::ProcessOnDataAvailable, this, transport, nullptr));
216 }
217
218 // when data is received from L2CAP
OnDataAvailable(DataTransport * transport,Packet * pkt)219 void ObexClientSocketTransport::TransportObserver::OnDataAvailable(DataTransport *transport, Packet *pkt)
220 {
221 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
222 obexTran_.dispatcher_.PostTask(
223 std::bind(&ObexClientSocketTransport::TransportObserver::ProcessOnDataAvailable, this, transport, pkt));
224 }
225
226 // The event is triggered when peer or RFCOMM/L2CAP is not available to receive data.
OnDataBusy(DataTransport * transport,uint8_t isBusy)227 void ObexClientSocketTransport::TransportObserver::OnDataBusy(DataTransport *transport, uint8_t isBusy)
228 {
229 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
230 obexTran_.dispatcher_.PostTask(
231 std::bind(&ObexClientSocketTransport::TransportObserver::ProcessOnDataBusy, this, isBusy));
232 }
233
234 // when peer is not available to receive data, or RFCOMM's send queue is full
OnTransportError(DataTransport * transport,int errType)235 void ObexClientSocketTransport::TransportObserver::OnTransportError(DataTransport *transport, int errType)
236 {
237 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
238 obexTran_.dispatcher_.PostTask(
239 std::bind(&ObexClientSocketTransport::TransportObserver::ProcessOnTransportError, this, errType));
240 }
241
242 // The event is triggered when connection complete successfully.
ProcessOnConnected(DataTransport * transport,uint16_t sendMTU,uint16_t recvMTU)243 void ObexClientSocketTransport::TransportObserver::ProcessOnConnected(
244 DataTransport *transport, uint16_t sendMTU, uint16_t recvMTU)
245 {
246 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
247 obexTran_.isConnected_ = true;
248 obexTran_.sendMtu_ = sendMTU;
249 obexTran_.recvMtu_ = recvMTU;
250 obexTran_.remoteBtAddr_ = transport->GetRemoteAddress();
251 HILOGI("[%{public}s] ObexClientSocketTransport Connect sendMtu = %{public}d, recvMtu = %{public}d",
252 obexTran_.tranKey_.c_str(), sendMTU, recvMTU);
253 obexTran_.observer_.OnTransportConnected(obexTran_);
254 }
255
256 // The event is triggered when a disconnect request is received.
ProcessOnDisconnected()257 void ObexClientSocketTransport::TransportObserver::ProcessOnDisconnected()
258 {
259 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
260 obexTran_.isConnected_ = false;
261 obexTran_.observer_.OnTransportDisconnected(obexTran_);
262 }
263
264 // The event is triggered when the disconnection process is successful.
ProcessOnDisconnectSuccess()265 void ObexClientSocketTransport::TransportObserver::ProcessOnDisconnectSuccess()
266 {
267 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
268 ProcessOnDisconnected();
269 }
270
ProcessOnDataBusy(uint8_t isBusy)271 void ObexClientSocketTransport::TransportObserver::ProcessOnDataBusy(uint8_t isBusy)
272 {
273 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
274 obexTran_.observer_.OnTransportDataBusy(obexTran_, isBusy);
275 }
276
277 // The event is triggered when data is received from stack.
ProcessOnDataAvailable(DataTransport * transport,Packet * pkt)278 void ObexClientSocketTransport::TransportObserver::ProcessOnDataAvailable(DataTransport *transport, Packet *pkt)
279 {
280 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
281 Packet *packetForRead = nullptr;
282 if (pkt != nullptr) {
283 packetForRead = pkt;
284 } else {
285 if (transport->Read(&packetForRead) != 0) {
286 HILOGE("error in transport.Read");
287 PacketFree(packetForRead);
288 return;
289 }
290 if (packetForRead == nullptr) {
291 HILOGE("obexPacket can't be null!");
292 return;
293 }
294 }
295 // pkt is delete by ObexPacket
296 HILOGI("Obex Transport Read: %{public}s", ObexUtils::ToDebugString(*packetForRead).c_str());
297 auto obexPacket = std::make_unique<ObexPacket>(*packetForRead);
298 obexTran_.observer_.OnTransportDataAvailable(obexTran_, *obexPacket);
299 }
300
301 // The event is triggered when process is failed.
ProcessOnTransportError(int errType)302 void ObexClientSocketTransport::TransportObserver::ProcessOnTransportError(int errType)
303 {
304 HILOGI("[%{public}s] Call", obexTran_.tranKey_.c_str());
305 obexTran_.observer_.OnTransportError(obexTran_, errType);
306 }
307
308 // ObexServerIncomingConnect
ObexServerIncomingConnect(ObexServerSocketTransport & obexTransport,const RawAddress & btAddr,int port)309 ObexServerIncomingConnect::ObexServerIncomingConnect(
310 ObexServerSocketTransport &obexTransport, const RawAddress &btAddr, int port)
311 : obexTransport_(obexTransport), btAddr_(btAddr), port_(port), operDone_(false)
312 {
313 HILOGI("Create ObexServerIncomingConnect: %{public}s", GetEncryptAddr(btAddr_.GetAddress()).c_str());
314 }
315
~ObexServerIncomingConnect()316 ObexServerIncomingConnect::~ObexServerIncomingConnect()
317 {
318 HILOGI("Delete ~ObexServerIncomingConnect");
319 }
320
321 // accept the connection request
AcceptConnection()322 int ObexServerIncomingConnect::AcceptConnection()
323 {
324 HILOGI("addr: %{public}s", GetEncryptAddr(btAddr_.GetAddress()).c_str());
325 if (operDone_) {
326 HILOGE("Operation is done!");
327 return -1;
328 }
329 operDone_ = true;
330 return obexTransport_.AcceptConnection(*this);
331 }
332
333 // reject the connection request
RejectConnection()334 int ObexServerIncomingConnect::RejectConnection()
335 {
336 HILOGI("addr: %{public}s", GetEncryptAddr(btAddr_.GetAddress()).c_str());
337 if (operDone_) {
338 HILOGE("Operation is done!");
339 return -1;
340 }
341 operDone_ = true;
342 return obexTransport_.RejectConnection(*this);
343 }
344
GetRemoteAddress()345 const RawAddress &ObexServerIncomingConnect::GetRemoteAddress()
346 {
347 return btAddr_;
348 }
349
GetPort()350 int ObexServerIncomingConnect::GetPort()
351 {
352 return port_;
353 }
354
ObexServerSocketTransport(const Option & option,ObexTransportObserver & observer,utility::Dispatcher & dispatcher)355 ObexServerSocketTransport::ObexServerSocketTransport(
356 const Option &option, ObexTransportObserver &observer, utility::Dispatcher &dispatcher)
357 : ObexServerTransport(observer), dispatcher_(dispatcher)
358 {
359 transportObserver_ = std::make_unique<TransportObserver>(*this);
360 uint16_t mtu = option.mtu_;
361 if (mtu < OBEX_MINIMUM_MTU) {
362 mtu = OBEX_MINIMUM_MTU;
363 }
364 if (option.isGoepL2capPSM_) {
365 HILOGI("ObexServerSocketTransport:CreateL2capTransport at psm:0x%{public}04X", option.scn_);
366 L2capTransportInfo createInfo = {nullptr, option.scn_, uint16_t(0), mtu, *transportObserver_, dispatcher};
367 dataTransport_ = TransportFactory::CreateL2capTransport(createInfo);
368 } else {
369 HILOGI("ObexServerSocketTransport:CreateRfcommTransport at scn:0x%{public}04X", option.scn_);
370 dataTransport_ =
371 TransportFactory::CreateRfcommTransport(nullptr, option.scn_, mtu, *transportObserver_, dispatcher);
372 }
373 tranKey_ = MakeTransportKey(option.isGoepL2capPSM_, option.scn_);
374 HILOGI("[%{public}s] Create ObexServerSocketTransport", tranKey_.c_str());
375 }
376
MakeTransportKey(bool isGoepL2capPSM,uint16_t scn)377 std::string ObexServerSocketTransport::MakeTransportKey(bool isGoepL2capPSM, uint16_t scn)
378 {
379 std::stringstream keyStream;
380 keyStream << "SERVER";
381 if (isGoepL2capPSM) {
382 keyStream << "-L2CAP-";
383 } else {
384 keyStream << "-RFCOMM-";
385 }
386 keyStream << std::uppercase << std::hex << std::setfill('0') << std::setw(TRANSPORT_KEY_NUM_LEN) << scn;
387 return keyStream.str();
388 }
389
Listen()390 int ObexServerSocketTransport::Listen()
391 {
392 HILOGI("[%{public}s] Call", tranKey_.c_str());
393 isOnListening_ = true;
394 return dataTransport_->RegisterServer();
395 }
396
Disconnect()397 int ObexServerSocketTransport::Disconnect()
398 {
399 HILOGI("[%{public}s] Call", tranKey_.c_str());
400 isOnListening_ = false;
401 for (auto &it : incomingConnectMap_) {
402 HILOGI("%{public}s: incomingConnect %{public}s hasn't been disconnected.", tranKey_.c_str(),
403 GetEncryptAddr(it.first).c_str());
404 }
405 for (auto &it : subTranMap_) {
406 HILOGI("[%{public}s] subStransport %{public}s hasn't been disconnected.",
407 tranKey_.c_str(), GetEncryptAddr(it.second->GetRemoteAddress().GetAddress()).c_str());
408 }
409 return dataTransport_->RemoveServer(true);
410 }
411
Disconnect(ObexTransport & subTransport)412 int ObexServerSocketTransport::Disconnect(ObexTransport &subTransport)
413 {
414 HILOGI("[%{public}s] Call", tranKey_.c_str());
415 DataTransport *findTransport = nullptr;
416 for (auto it = subTranMap_.begin(); it != subTranMap_.end(); ++it) {
417 if (it->second.get() == &subTransport) {
418 findTransport = it->first;
419 break;
420 }
421 }
422 if (findTransport != nullptr) {
423 HILOGI("[%{public}s] To Disconnect sub transport", tranKey_.c_str());
424 return findTransport->Disconnect();
425 }
426 return -1;
427 }
428
429 // Server accept the connection request
AcceptConnection(ObexIncomingConnect & incomingConnect)430 int ObexServerSocketTransport::AcceptConnection(ObexIncomingConnect &incomingConnect)
431 {
432 const RawAddress &addr = incomingConnect.GetRemoteAddress();
433 HILOGI("Call%{public}s , addr: %{public}s", tranKey_.c_str(), GetEncryptAddr(addr.GetAddress()).c_str());
434 return dataTransport_->AcceptConnection(addr, incomingConnect.GetPort());
435 }
436
437 // Server reject the connection request
RejectConnection(ObexIncomingConnect & incomingConnect)438 int ObexServerSocketTransport::RejectConnection(ObexIncomingConnect &incomingConnect)
439 {
440 const RawAddress &addr = incomingConnect.GetRemoteAddress();
441 HILOGI("Call %{public}s , addr: %{public}s", tranKey_.c_str(), GetEncryptAddr(addr.GetAddress()).c_str());
442 int ret = dataTransport_->RejectConnection(addr, incomingConnect.GetPort());
443 if (incomingConnectMap_.find(addr.GetAddress()) != incomingConnectMap_.end()) {
444 HILOGI("[%{public}s] Remove incomingConnect %{public}s.", tranKey_.c_str(),
445 GetEncryptAddr(addr.GetAddress()).c_str());
446 incomingConnectMap_.erase(addr.GetAddress());
447 }
448 return ret;
449 }
450
451 // get transport key
GetTransportKey()452 const std::string &ObexServerSocketTransport::GetTransportKey()
453 {
454 return tranKey_;
455 }
456
TransportObserver(ObexServerSocketTransport & mainTran)457 ObexServerSocketTransport::TransportObserver::TransportObserver(ObexServerSocketTransport &mainTran)
458 : mainTran_(mainTran)
459 {}
460
461 // connection success
OnConnectIncoming(const RawAddress & addr,uint16_t port)462 void ObexServerSocketTransport::TransportObserver::OnConnectIncoming(const RawAddress &addr, uint16_t port)
463 {
464 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
465 mainTran_.dispatcher_.PostTask(
466 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnConnectIncoming, this, addr, port));
467 }
468
OnIncomingDisconnected(const RawAddress & addr)469 void ObexServerSocketTransport::TransportObserver::OnIncomingDisconnected(const RawAddress &addr)
470 {
471 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
472 mainTran_.dispatcher_.PostTask(
473 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnIncomingDisconnected, this, addr));
474 }
475
476 // connection success
OnConnected(DataTransport * transport,uint16_t sendMTU,uint16_t recvMTU)477 void ObexServerSocketTransport::TransportObserver::OnConnected(
478 DataTransport *transport, uint16_t sendMTU, uint16_t recvMTU)
479 {
480 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
481 mainTran_.dispatcher_.PostTask(std::bind(
482 &ObexServerSocketTransport::TransportObserver::ProcessOnConnected, this, transport, sendMTU, recvMTU));
483 }
484
485 // connection failed
OnDisconnected(DataTransport * transport)486 void ObexServerSocketTransport::TransportObserver::OnDisconnected(DataTransport *transport)
487 {
488 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
489 mainTran_.dispatcher_.PostTask(
490 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnDisconnected, this, transport));
491 }
492
OnDisconnectSuccess(DataTransport * transport)493 void ObexServerSocketTransport::TransportObserver::OnDisconnectSuccess(DataTransport *transport)
494 {
495 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
496 mainTran_.dispatcher_.PostTask(
497 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnDisconnectSuccess, this, transport));
498 }
499
500 // when data is received from RFCOMM
OnDataAvailable(DataTransport * transport)501 void ObexServerSocketTransport::TransportObserver::OnDataAvailable(DataTransport *transport)
502 {
503 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
504 mainTran_.dispatcher_.PostTask(
505 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnDataAvailable, this, transport, nullptr));
506 }
507
508 // when data is received from L2CAP
OnDataAvailable(DataTransport * transport,Packet * pkt)509 void ObexServerSocketTransport::TransportObserver::OnDataAvailable(DataTransport *transport, Packet *pkt)
510 {
511 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
512 mainTran_.dispatcher_.PostTask(
513 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnDataAvailable, this, transport, pkt));
514 }
515
516 // when peer is not available to receive data, or RFCOMM's send queue is full
OnTransportError(DataTransport * transport,int errType)517 void ObexServerSocketTransport::TransportObserver::OnTransportError(DataTransport *transport, int errType)
518 {
519 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
520 mainTran_.dispatcher_.PostTask(
521 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnTransportError, this, transport, errType));
522 }
523
524 // The event is triggered when peer or RFCOMM/L2CAP is not available to receive data.
OnDataBusy(DataTransport * transport,uint8_t isBusy)525 void ObexServerSocketTransport::TransportObserver::OnDataBusy(DataTransport *transport, uint8_t isBusy)
526 {
527 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
528 mainTran_.dispatcher_.PostTask(
529 std::bind(&ObexServerSocketTransport::TransportObserver::ProcessOnDataBusy, this, transport, isBusy));
530 }
531
532 // The event is triggered when server accept a new connection.
ProcessOnConnectIncoming(RawAddress btAddr,uint16_t port)533 void ObexServerSocketTransport::TransportObserver::ProcessOnConnectIncoming(RawAddress btAddr, uint16_t port)
534 {
535 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
536 std::string tranKey = mainTran_.tranKey_;
537 const std::string &strAddr = btAddr.GetAddress();
538 HILOGI("[%{public}s] BtAddr:%{public}s : 0x%{public}04X", tranKey.c_str(), GetEncryptAddr(strAddr).c_str(), port);
539 if (!mainTran_.isOnListening_) {
540 HILOGE("[%{public}s] Server has been stopped! Reject incoming %{public}s",
541 tranKey.c_str(), GetEncryptAddr(strAddr).c_str());
542 mainTran_.dataTransport_->RejectConnection(btAddr, port);
543 return;
544 }
545 if (mainTran_.incomingConnectMap_.find(strAddr) != mainTran_.incomingConnectMap_.end()) {
546 HILOGI("[%{public}s] Incoming connect is already exists, So Reject: %{public}s", tranKey.c_str(),
547 GetEncryptAddr(btAddr.GetAddress()).c_str());
548 mainTran_.dataTransport_->RejectConnection(btAddr, port);
549 return;
550 }
551 HILOGI("[%{public}s] Create incoming connect :%{public}s, %{public}d",
552 tranKey.c_str(), GetEncryptAddr(strAddr).c_str(), port);
553 mainTran_.incomingConnectMap_[strAddr] = std::make_unique<ObexServerIncomingConnect>(mainTran_, btAddr, port);
554 mainTran_.observer_.OnTransportConnectIncoming(*mainTran_.incomingConnectMap_.at(strAddr).get());
555 }
556
557 // The event is triggered when new connection disconnect before accept.
ProcessOnIncomingDisconnected(RawAddress btAddr)558 void ObexServerSocketTransport::TransportObserver::ProcessOnIncomingDisconnected(RawAddress btAddr)
559 {
560 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
561 std::string strAddr = btAddr.GetAddress();
562 HILOGI("[%{public}s] BtAddr:%{public}s", mainTran_.tranKey_.c_str(), GetEncryptAddr(strAddr).c_str());
563 if (mainTran_.incomingConnectMap_.find(strAddr) != mainTran_.incomingConnectMap_.end()) {
564 mainTran_.incomingConnectMap_.erase(strAddr);
565 mainTran_.observer_.OnTransportIncomingDisconnected(strAddr);
566 }
567 }
568
569 // The event is triggered when connection complete successfully.
ProcessOnConnected(DataTransport * transport,uint16_t sendMTU,uint16_t recvMTU)570 void ObexServerSocketTransport::TransportObserver::ProcessOnConnected(
571 DataTransport *transport, uint16_t sendMTU, uint16_t recvMTU)
572 {
573 HILOGI("[%{public}s] transport", mainTran_.tranKey_.c_str());
574 int i = 0;
575 for (auto &it : mainTran_.subTranMap_) {
576 std::string addr = it.second->GetRemoteAddress().GetAddress();
577 HILOGI("%{public}s subStransport: %{public}d, addr: %{public}s",
578 mainTran_.tranKey_.c_str(), i, GetEncryptAddr(addr).c_str());
579 i++;
580 }
581 std::string strAddr = transport->GetRemoteAddress().GetAddress();
582 mainTran_.incomingConnectMap_.erase(strAddr);
583 auto subTransport =
584 std::make_unique<ObexSocketTransport>(transport, sendMTU, recvMTU, mainTran_.GetTransportKey());
585 ObexTransport *subTran = subTransport.get();
586 HILOGI("[%{public}s] Add sub transport %{public}s",
587 mainTran_.tranKey_.c_str(), subTransport->GetTransportKey().c_str());
588 mainTran_.subTranMap_[transport] = std::move(subTransport);
589
590 mainTran_.observer_.OnTransportConnected(*subTran);
591 }
592
593 // The event is triggered when a disconnect request is received.
ProcessOnDisconnected(DataTransport * transport)594 void ObexServerSocketTransport::TransportObserver::ProcessOnDisconnected(DataTransport *transport)
595 {
596 std::string tranKey = mainTran_.tranKey_;
597 HILOGI("[%{public}s] OnDisconnected", tranKey.c_str());
598
599 uint32_t i = 0;
600 for (auto &it : mainTran_.subTranMap_) {
601 std::string addr = it.second->GetRemoteAddress().GetAddress();
602 HILOGI("%{public}s subStransport: %{public}d address: %{public}s",
603 tranKey.c_str(), i, GetEncryptAddr(addr).c_str());
604 i++;
605 }
606 if (mainTran_.subTranMap_.find(transport) != mainTran_.subTranMap_.end()) {
607 ObexSocketTransport *subTran = mainTran_.subTranMap_.at(transport).get();
608 mainTran_.observer_.OnTransportDisconnected(*subTran);
609 HILOGI("[%{public}s] Remove sub transport %{public}s", tranKey.c_str(), subTran->GetTransportKey().c_str());
610 mainTran_.subTranMap_.erase(transport);
611 } else {
612 HILOGE("[%{public}s] DataTransport isn't exists!", tranKey.c_str());
613 }
614 }
615
616 // The event is triggered when the disconnection process is successful.
ProcessOnDisconnectSuccess(DataTransport * transport)617 void ObexServerSocketTransport::TransportObserver::ProcessOnDisconnectSuccess(DataTransport *transport)
618 {
619 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
620 ProcessOnDisconnected(transport);
621 }
622
623 // The event is triggered when data is received from stack.
ProcessOnDataAvailable(DataTransport * transport,Packet * pkt)624 void ObexServerSocketTransport::TransportObserver::ProcessOnDataAvailable(DataTransport *transport, Packet *pkt)
625 {
626 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
627 uint32_t i = 0;
628 for (auto &it : mainTran_.subTranMap_) {
629 std::string addr = it.second->GetRemoteAddress().GetAddress();
630 HILOGI("%{public}s subStransport: %{public}d, addr: %{public}s",
631 mainTran_.tranKey_.c_str(), i, GetEncryptAddr(addr).c_str());
632 i++;
633 }
634 if (mainTran_.subTranMap_.find(transport) != mainTran_.subTranMap_.end()) {
635 Packet *packetForRead = nullptr;
636 if (pkt != nullptr) {
637 packetForRead = pkt;
638 } else {
639 if (transport->Read(&packetForRead) != 0) {
640 HILOGI("[%{public}s] error in transport.Read", mainTran_.tranKey_.c_str());
641 PacketFree(packetForRead);
642 return;
643 }
644 if (packetForRead == nullptr) {
645 HILOGI("[%{public}s] obexPacket can't be null!", mainTran_.tranKey_.c_str());
646 return;
647 }
648 }
649 // packetForRead is delete by ObexPacket
650 HILOGI("[%{public}s] Obex Transport Read: %{public}s",
651 mainTran_.tranKey_.c_str(), ObexUtils::ToDebugString(*packetForRead).c_str());
652 auto obexPacket = std::make_unique<ObexPacket>(*packetForRead);
653 ObexSocketTransport *subTran = mainTran_.subTranMap_.at(transport).get();
654 HILOGI("[%{public}s] Receive data on sub transport %{public}s",
655 mainTran_.tranKey_.c_str(), subTran->GetTransportKey().c_str());
656 mainTran_.observer_.OnTransportDataAvailable(*subTran, *obexPacket);
657 } else {
658 HILOGE("[%{public}s] Receive data on sub transport, but it isn't exists in subTransportMap!",
659 mainTran_.tranKey_.c_str());
660 if (pkt != nullptr) {
661 PacketFree(pkt);
662 }
663 }
664 }
665
ProcessOnDataBusy(DataTransport * transport,uint8_t isBusy)666 void ObexServerSocketTransport::TransportObserver::ProcessOnDataBusy(DataTransport *transport, uint8_t isBusy)
667 {
668 HILOGI("[%{public}s] Call, isBusy %{public}d", mainTran_.tranKey_.c_str(), isBusy);
669 if (transport != nullptr && mainTran_.subTranMap_.find(transport) != mainTran_.subTranMap_.end()) {
670 ObexSocketTransport *subTran = mainTran_.subTranMap_.at(transport).get();
671 mainTran_.observer_.OnTransportDataBusy(*subTran, isBusy);
672 }
673 }
674
675 // The event is triggered when process is failed.
ProcessOnTransportError(DataTransport * transport,int errType)676 void ObexServerSocketTransport::TransportObserver::ProcessOnTransportError(DataTransport *transport, int errType)
677 {
678 HILOGI("[%{public}s] Call", mainTran_.tranKey_.c_str());
679 if (transport != nullptr && mainTran_.subTranMap_.find(transport) != mainTran_.subTranMap_.end()) {
680 ObexSocketTransport *subTran = mainTran_.subTranMap_.at(transport).get();
681 HILOGE("[%{public}s] Error on sub transport %{public}s, errorCode=%{public}d",
682 mainTran_.tranKey_.c_str(), subTran->GetTransportKey().c_str(), errType);
683 mainTran_.observer_.OnTransportError(*subTran, errType);
684 } else {
685 HILOGE("[%{public}s] Error occur in server socket transport? error code:%{public}d",
686 mainTran_.tranKey_.c_str(), errType);
687 }
688 }
689 } // namespace bluetooth
690 } // namespace OHOS
691