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 "socket_sdp_client.h"
17 #include "log.h"
18 #include "socket_service.h"
19 
20 namespace OHOS {
21 namespace bluetooth {
~SocketSdpClient()22 SocketSdpClient::~SocketSdpClient()
23 {}
24 
StartDiscovery(const std::string & addr,const Uuid & uuid,void * context)25 int SocketSdpClient::StartDiscovery(const std::string &addr, const Uuid &uuid, void *context)
26 {
27     LOG_INFO("[sock]%{public}s", __func__);
28 
29     BtAddr address;
30     address.type = BT_PUBLIC_DEVICE_ADDRESS;
31     RawAddress rawAddr(addr);
32     rawAddr.ConvertToUint8(address.addr);
33 
34     BtUuid classid[1];
35     classid[0].type = BT_UUID_128;
36     uuid.ConvertToBytesLE(classid[0].uuid128);
37     SdpUuid sdpUUid;
38     sdpUUid.uuidNum = SPP_CLASSID_NUM;
39     sdpUUid.uuid = &classid[0];
40 
41     SdpAttributeIdList attributeIdList;
42     attributeIdList.type = SDP_TYPE_LIST;
43     attributeIdList.attributeIdList.attributeIdNumber = SPP_ATTR_NUM;
44     attributeIdList.attributeIdList.attributeId[SOCK_SDP_IDX0] = SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST;
45     attributeIdList.attributeIdList.attributeId[SOCK_SDP_IDX1] = SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST;
46     attributeIdList.attributeIdList.attributeId[SOCK_SDP_IDX2] = SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST;
47 
48     int ret =
49         SDP_ServiceSearchAttribute(&address, &sdpUUid, attributeIdList, context, &SocketSdpClient::SdpSearchCallback);
50     if (ret != BT_SUCCESS) {
51         LOG_ERROR("[sock]%{public}s SearchAttribute error", __FUNCTION__);
52     }
53     return ret;
54 }
55 
SearchAttributes(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum)56 uint8_t SocketSdpClient::SearchAttributes(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum)
57 {
58     LOG_INFO("[sock]%{public}s", __func__);
59 
60     uint8_t scn = -1;
61     uint16_t num = 0;
62     while (num < serviceNum) {
63         if (!(SearchScn(serviceAry->descriptorNumber, serviceAry->descriptor, scn))) {
64             num++;
65             if (num == serviceNum) {
66                 LOG_ERROR("[sock]%{public}s search scn error", __FUNCTION__);
67             }
68         } else {
69             break;
70         }
71     }
72     return scn;
73 }
74 
SearchScn(uint16_t protocolNum,const SdpProtocolDescriptor * protocol,uint8_t & scn)75 bool SocketSdpClient::SearchScn(uint16_t protocolNum, const SdpProtocolDescriptor *protocol, uint8_t &scn)
76 {
77     uint16_t num = 0;
78 
79     while (num < protocolNum) {
80         if ((protocol[num].protocolUuid.uuid16 == UUID_PROTOCOL_RFCOMM) &&
81             (protocol[num].parameter[0].type == SDP_TYPE_UINT_8)) {
82             scn = (uint8_t)protocol[num].parameter[0].value;
83             LOG_INFO("[sock]%{public}s scn:%hhu", __func__, scn);
84             return true;
85         }
86         num++;
87     }
88     return false;
89 }
90 
SdpSearchCallback(const BtAddr * addr,const SdpService * serviceAry,uint16_t serviceNum,void * context)91 void SocketSdpClient::SdpSearchCallback(
92     const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum, void *context)
93 {
94     LOG_INFO("[sock]%{public}s", __func__);
95 
96     uint8_t scn = SearchAttributes(addr, serviceAry, serviceNum);
97     LOG_INFO("[sock]%{public}s scn:%hhu", __func__, scn);
98 
99     utility::Message msg(SOCKET_SDP_DISCOVERY_RESULT);
100     msg.arg1_ = scn;
101     msg.arg2_ = context;
102     SocketService *socketService =
103         static_cast<SocketService *>(IProfileManager::GetInstance()->GetProfileService(PROFILE_NAME_SPP));
104     socketService->GetDispatcher()->PostTask(std::bind(&SocketService::ProcessMessage, socketService, msg));
105 }
106 }  // namespace bluetooth
107 }  // namespace OHOS