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