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 "hfp_hf_sdp_server.h"
17
18 #include "adapter_config.h"
19 #include "hfp_hf_data_connection.h"
20 #include "raw_address.h"
21 #include "rfcomm.h"
22
23 namespace OHOS {
24 namespace bluetooth {
GetInstance()25 HfpHfSdpServer &HfpHfSdpServer::GetInstance()
26 {
27 static HfpHfSdpServer instance;
28 return instance;
29 }
30
RegisterSdpService(uint8_t scn)31 int HfpHfSdpServer::RegisterSdpService(uint8_t scn)
32 {
33 if (scn == 0) {
34 LOG_ERROR("[HFP HF]%{public}s():Unavailable server channel number", __FUNCTION__);
35 return HFP_HF_FAILURE;
36 }
37
38 AdapterConfig::GetInstance()->GetValue(HSP_HS_STATE_SECTION_NAME, HSP_HS_STATE_PROPERY_NAME, hspState_);
39
40 // Create and register service record
41 sdpHandle_ = SDP_CreateServiceRecord();
42
43 int ret = AddServiceClassId();
44 HFP_HF_RETURN_IF_FAIL(ret);
45
46 ret = AddProtocol(scn);
47 HFP_HF_RETURN_IF_FAIL(ret);
48
49 ret = AddProfile();
50 HFP_HF_RETURN_IF_FAIL(ret);
51
52 ret = AddServiceName();
53 HFP_HF_RETURN_IF_FAIL(ret);
54
55 ret = AddFeatures();
56 HFP_HF_RETURN_IF_FAIL(ret);
57
58 ret = AddBrowseGroupList();
59 HFP_HF_RETURN_IF_FAIL(ret);
60
61 ret = SDP_RegisterServiceRecord(sdpHandle_);
62 HFP_HF_RETURN_IF_FAIL(ret);
63 return ret;
64 }
65
DeregisterSdpService()66 int HfpHfSdpServer::DeregisterSdpService()
67 {
68 int ret = SDP_DeregisterServiceRecord(sdpHandle_);
69 HFP_HF_RETURN_IF_FAIL(ret);
70
71 ret = SDP_DestroyServiceRecord(sdpHandle_);
72 HFP_HF_RETURN_IF_FAIL(ret);
73
74 sdpHandle_ = 0;
75 return ret;
76 }
77
AddServiceClassId() const78 int HfpHfSdpServer::AddServiceClassId() const
79 {
80 switch(hspState_) {
81 case HSP_HS_STATE_BOTH:
82 BtUuid classIdBoth[HFP_HF_HSP_SERVER_CLASSID_NUM];
83 classIdBoth[0].type = BT_UUID_16;
84 classIdBoth[0].uuid16 = HFP_HF_UUID_SERVCLASS_HFP_HF;
85 classIdBoth[1].type = BT_UUID_16;
86 classIdBoth[1].uuid16 = HFP_HF_UUID_SERVCLASS_GENERIC_AUDIO;
87 classIdBoth[2].type = BT_UUID_16;
88 classIdBoth[2].uuid16 = HFP_HF_UUID_SERVCLASS_HSP_HS;
89 return SDP_AddServiceClassIdList(sdpHandle_, classIdBoth, HFP_HF_HSP_SERVER_CLASSID_NUM);
90 case HSP_HS_STATE_HSP:
91 BtUuid classIdHsp[HFP_HF_SERVER_CLASSID_NUM];
92 classIdHsp[0].type = BT_UUID_16;
93 classIdHsp[0].uuid16 = HFP_HF_UUID_SERVCLASS_HSP_HS;
94 classIdHsp[1].type = BT_UUID_16;
95 classIdHsp[1].uuid16 = HFP_HF_UUID_SERVCLASS_GENERIC_AUDIO;
96 return SDP_AddServiceClassIdList(sdpHandle_, classIdHsp, HFP_HF_SERVER_CLASSID_NUM);
97 case HSP_HS_STATE_NONE:
98 BtUuid classIdHfp[HFP_HF_SERVER_CLASSID_NUM];
99 classIdHfp[0].type = BT_UUID_16;
100 classIdHfp[0].uuid16 = HFP_HF_UUID_SERVCLASS_HFP_HF;
101 classIdHfp[1].type = BT_UUID_16;
102 classIdHfp[1].uuid16 = HFP_HF_UUID_SERVCLASS_GENERIC_AUDIO;
103 return SDP_AddServiceClassIdList(sdpHandle_, classIdHfp, HFP_HF_SERVER_CLASSID_NUM);
104 default:
105 break;
106 }
107 return BT_CONFIG_ERROR;
108 }
109
AddProtocol(uint8_t scn) const110 int HfpHfSdpServer::AddProtocol(uint8_t scn) const
111 {
112 SdpProtocolDescriptor protocol[HFP_HF_SERVER_PROTOCOL_NUM];
113 protocol[0].protocolUuid.type = BT_UUID_16;
114 protocol[0].protocolUuid.uuid16 = UUID_PROTOCOL_L2CAP;
115 protocol[0].parameterNumber = 0;
116 protocol[1].protocolUuid.type = BT_UUID_16;
117 protocol[1].protocolUuid.uuid16 = UUID_PROTOCOL_RFCOMM;
118 protocol[1].parameterNumber = 1;
119 protocol[1].parameter[0].type = SDP_TYPE_UINT_8;
120 protocol[1].parameter[0].value = scn;
121 return SDP_AddProtocolDescriptorList(sdpHandle_, protocol, HFP_HF_SERVER_PROTOCOL_NUM);
122 }
123
AddProfile() const124 int HfpHfSdpServer::AddProfile() const
125 {
126 switch(hspState_) {
127 case HSP_HS_STATE_BOTH:
128 SdpProfileDescriptor profileBoth[HFP_HF_HSP_SERVER_PROFILE_NUM];
129 profileBoth[0].profileUuid.type = BT_UUID_16;
130 profileBoth[0].profileUuid.uuid16 = HFP_HF_UUID_SERVCLASS_HFP_HF;
131 profileBoth[0].versionNumber = HFP_HF_HFP_VERSION_1_7;
132 profileBoth[1].profileUuid.type = BT_UUID_16;
133 profileBoth[1].profileUuid.uuid16 = HFP_HF_UUID_SERVCLASS_HSP_HS;
134 profileBoth[1].versionNumber = HFP_HF_HSP_VERSION_1_2;
135 return SDP_AddBluetoothProfileDescriptorList(sdpHandle_, profileBoth, HFP_HF_HSP_SERVER_PROFILE_NUM);
136 case HSP_HS_STATE_HSP:
137 SdpProfileDescriptor profileHsp[HFP_HF_SERVER_PROFILE_NUM];
138 profileHsp[0].profileUuid.type = BT_UUID_16;
139 profileHsp[0].profileUuid.uuid16 = HFP_HF_UUID_SERVCLASS_HSP_HS;
140 profileHsp[0].versionNumber = HFP_HF_HSP_VERSION_1_2;
141 return SDP_AddBluetoothProfileDescriptorList(sdpHandle_, profileHsp, HFP_HF_SERVER_PROFILE_NUM);
142 case HSP_HS_STATE_NONE:
143 SdpProfileDescriptor profileHfp[HFP_HF_SERVER_PROFILE_NUM];
144 profileHfp[0].profileUuid.type = BT_UUID_16;
145 profileHfp[0].profileUuid.uuid16 = HFP_HF_UUID_SERVCLASS_HFP_HF;
146 profileHfp[0].versionNumber = HFP_HF_HFP_VERSION_1_7;
147 return SDP_AddBluetoothProfileDescriptorList(sdpHandle_, profileHfp, HFP_HF_SERVER_PROFILE_NUM);
148 default:
149 break;
150 }
151 return BT_CONFIG_ERROR;
152 }
153
AddServiceName() const154 int HfpHfSdpServer::AddServiceName() const
155 {
156 return SDP_AddServiceName(sdpHandle_, SDP_ATTRIBUTE_PRIMARY_LANGUAGE_BASE,
157 HFP_HF_SERVER_SERVICE_NAME.c_str(), HFP_HF_SERVER_SERVICE_NAME.length());
158 }
159
AddFeatures() const160 int HfpHfSdpServer::AddFeatures() const
161 {
162 uint32_t features = HfpHfDataConnection::GetLocalFeatures();
163 bool codecMSBC = (features & HFP_HF_FEATURES_CODEC_NEGOTIATION) ? true : false;
164 features &= HFP_HF_FEATURES_SDP_SPEC;
165 if (codecMSBC) {
166 // Codec bit position is different in SDP (bit 5) and in BRSF (bit 7)
167 features |= HFP_HF_AG_FEATURES_SUPPORT_WBS;
168 }
169 SdpAttribute featuresAttr;
170 featuresAttr.attributeId = HFP_HF_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
171 featuresAttr.type = SDP_TYPE_UINT_16;
172 featuresAttr.attributeValueLength = HFP_HF_SERVER_FEATURES_LENGTH;
173 featuresAttr.attributeValue = &features;
174 return AddAttribute(featuresAttr);
175 }
176
AddBrowseGroupList() const177 int HfpHfSdpServer::AddBrowseGroupList() const
178 {
179 BtUuid browseGroupList[HFP_HF_SERVER_BROWSE_LIST_NUM];
180 browseGroupList[0].type = BT_UUID_16;
181 browseGroupList[0].uuid16 = SDP_PUBLIC_BROWSE_GROUP_ROOT_UUID;
182 return SDP_AddBrowseGroupList(sdpHandle_, browseGroupList, HFP_HF_SERVER_BROWSE_LIST_NUM);
183 }
184
AddAttribute(SdpAttribute attribute) const185 int HfpHfSdpServer::AddAttribute(SdpAttribute attribute) const
186 {
187 return SDP_AddAttribute(
188 sdpHandle_, attribute.attributeId, attribute.type, attribute.attributeValue, attribute.attributeValueLength);
189 }
190 } // namespace bluetooth
191 } // namespace OHOS