1 /*
2 * Copyright (C) 2022 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 "opp_sdp_client.h"
17
18 #include "btstack.h"
19 #include "log.h"
20 #include "opp_service.h"
21 #include "raw_address.h"
22
23 namespace OHOS {
24 namespace bluetooth {
OppSdpClient(std::string address)25 OppSdpClient::OppSdpClient(std::string address)
26 {
27 address_ = address;
28 }
29
~OppSdpClient()30 OppSdpClient::~OppSdpClient()
31 {
32 }
33
SdpSearch()34 int OppSdpClient::SdpSearch()
35 {
36 HILOGI("[OPP SDP CLIENT]:enter");
37
38 BtAddr address;
39 address.type = BT_PUBLIC_DEVICE_ADDRESS;
40 RawAddress rawAddr(address_);
41 rawAddr.ConvertToUint8(address.addr);
42
43 BtUuid classid;
44 classid.type = BT_UUID_16;
45 classid.uuid16 = OPP_UUID16;
46 SdpUuid sdpUUid;
47 sdpUUid.uuidNum = 1;
48 sdpUUid.uuid = &classid;
49
50 SdpAttributeIdList attributeIdList;
51 attributeIdList.type = SDP_TYPE_RANGE;
52 attributeIdList.attributeIdRange.start = 0x0000;
53 attributeIdList.attributeIdRange.end = 0xFFFF;
54
55 int ret = SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, this, SdpSearchCallback);
56 if (ret != BT_SUCCESS) {
57 HILOGE("[OPP SDP CLIENT]:SDP_ServiceSearchAttribute failed!");
58 }
59
60 return ret;
61 }
62
SdpSearchCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)63 void OppSdpClient::SdpSearchCallback(const BtAddr *addr, const SdpService *serviceAry,
64 uint16_t serviceNum, void *context)
65 {
66 auto pThis = static_cast<OppSdpClient *>(context);
67 if ((pThis == nullptr) || (addr == nullptr)) {
68 HILOGE("[OPP SDP CLIENT]:OppSdpClient or addr is null.");
69 return;
70 }
71 pThis->SdpSearchCallback_(addr, serviceAry, serviceNum);
72 }
73
SdpSearchCallback_(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum)74 void OppSdpClient::SdpSearchCallback_(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum)
75 {
76 OppSdpInformation sdpInfo;
77 for (int serviceCount = 0; serviceCount < serviceNum; ++serviceCount, ++serviceAry) {
78 BtUuid *classId = serviceAry->classId;
79 if (classId->uuid16 != OPP_UUID16) {
80 continue;
81 }
82 sdpInfo.rfcommNo = FindRFCommChannel(*serviceAry);
83 sdpInfo.psm = FindL2capPSM(*serviceAry);
84 }
85
86 if ((sdpInfo.psm != 0) || (sdpInfo.rfcommNo != 0)) {
87 OppMessage event(OPP_SDP_CMPL_EVT, OPP_SDP_SUCCESS);
88 event.dev_ = address_;
89 event.sdpInfo_ = sdpInfo;
90 OppService::GetService()->PostEvent(event);
91 } else {
92 OppMessage event(OPP_SDP_CMPL_EVT, OPP_SDP_FAILED);
93 event.dev_ = address_;
94 OppService::GetService()->PostEvent(event);
95 HILOGE("[OPP SDP CLIENT] serviceNum = %{public}d", int(serviceNum));
96 }
97 }
98
FindRFCommChannel(const SdpService & serviceAry)99 uint8_t OppSdpClient::FindRFCommChannel(const SdpService &serviceAry)
100 {
101 uint8_t rfcommNo = 0;
102 SdpProtocolDescriptor *descriptor = serviceAry.descriptor;
103 for (int descriptorCount = 0; descriptorCount < serviceAry.descriptorNumber; ++descriptorCount, ++descriptor) {
104 if (descriptor->protocolUuid.uuid16 == UUID_PROTOCOL_RFCOMM) {
105 if (&(descriptor->parameter[0]) != nullptr) {
106 rfcommNo = descriptor->parameter[0].value;
107 break;
108 }
109 }
110 }
111 return rfcommNo;
112 }
113
FindL2capPSM(const SdpService & serviceAry)114 uint16_t OppSdpClient::FindL2capPSM(const SdpService &serviceAry)
115 {
116 uint16_t psm = 0;
117 SdpAttribute *attribute = serviceAry.attribute;
118 for (uint16_t attSeqCount = 0; attSeqCount < serviceAry.attributeNumber; ++attSeqCount, ++attribute) {
119 if (attribute->attributeId == OPP_GOEP_L2CAP_PSM_ATTRIBUTE_ID) {
120 psm = *static_cast<uint16_t*>(attribute->attributeValue);
121 }
122 }
123 return psm;
124 }
125 } // namespace bluetooth
126 } // namespace OHOS