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_ag_sdp_server.h"
17
18 #include "adapter_config.h"
19 #include "hfp_ag_data_connection.h"
20 #include "hfp_ag_defines.h"
21 #include "raw_address.h"
22 #include "rfcomm.h"
23
24 namespace OHOS {
25 namespace bluetooth {
GetInstance()26 HfpAgSdpServer &HfpAgSdpServer::GetInstance()
27 {
28 static HfpAgSdpServer instance;
29 return instance;
30 }
31
RegisterSdpService(uint8_t scn)32 int HfpAgSdpServer::RegisterSdpService(uint8_t scn)
33 {
34 if (scn == 0) {
35 LOG_ERROR("[HFP AG]%{public}s():Unavailable server channel number", __FUNCTION__);
36 return HFP_AG_FAILURE;
37 }
38
39 AdapterConfig::GetInstance()->GetValue(HSP_AG_STATE_SECTION_NAME, HSP_AG_STATE_PROPERY_NAME, hspState_);
40 LOG_INFO("[HFP AG]HSP STATE = %{public}d", hspState_);
41
42 // Create and register service record
43 sdpHandle_ = SDP_CreateServiceRecord();
44
45 int ret = AddServiceClassId();
46 HFP_AG_RETURN_IF_FAIL(ret);
47
48 ret = AddProtocol(scn);
49 HFP_AG_RETURN_IF_FAIL(ret);
50
51 ret = AddProfile();
52 HFP_AG_RETURN_IF_FAIL(ret);
53
54 ret = AddServiceName();
55 HFP_AG_RETURN_IF_FAIL(ret);
56
57 ret = AddNetwork();
58 HFP_AG_RETURN_IF_FAIL(ret);
59
60 ret = AddFeatures();
61 HFP_AG_RETURN_IF_FAIL(ret);
62
63 ret = AddBrowseGroupList();
64 HFP_AG_RETURN_IF_FAIL(ret);
65
66 ret = SDP_RegisterServiceRecord(sdpHandle_);
67 HFP_AG_RETURN_IF_FAIL(ret);
68 return ret;
69 }
70
DeregisterSdpService()71 int HfpAgSdpServer::DeregisterSdpService()
72 {
73 int ret = SDP_DeregisterServiceRecord(sdpHandle_);
74 HFP_AG_RETURN_IF_FAIL(ret);
75
76 ret = SDP_DestroyServiceRecord(sdpHandle_);
77 HFP_AG_RETURN_IF_FAIL(ret);
78
79 sdpHandle_ = 0;
80 return ret;
81 }
82
AddServiceClassId() const83 int HfpAgSdpServer::AddServiceClassId() const
84 {
85 switch(hspState_) {
86 case HSP_AG_STATE_BOTH:
87 BtUuid classIdBoth[HFP_AG_HSP_SERVER_CLASSID_NUM];
88 classIdBoth[0].type = BT_UUID_16;
89 classIdBoth[0].uuid16 = HFP_AG_UUID_SERVCLASS_HFP_AG;
90 classIdBoth[1].type = BT_UUID_16;
91 classIdBoth[1].uuid16 = HFP_AG_UUID_SERVCLASS_GENERIC_AUDIO;
92 classIdBoth[2].type = BT_UUID_16;
93 classIdBoth[2].uuid16 = HSP_AG_UUID_SERVCLASS;
94 return SDP_AddServiceClassIdList(sdpHandle_, classIdBoth, HFP_AG_HSP_SERVER_CLASSID_NUM);
95 case HSP_AG_STATE_HSP:
96 BtUuid classIdHsp[HFP_AG_SERVER_CLASSID_NUM];
97 classIdHsp[0].type = BT_UUID_16;
98 classIdHsp[0].uuid16 = HSP_AG_UUID_SERVCLASS;
99 classIdHsp[1].type = BT_UUID_16;
100 classIdHsp[1].uuid16 = HFP_AG_UUID_SERVCLASS_GENERIC_AUDIO;
101 return SDP_AddServiceClassIdList(sdpHandle_, classIdHsp, HFP_AG_SERVER_CLASSID_NUM);
102 case HSP_AG_STATE_NONE:
103 BtUuid classIdHfp[HFP_AG_SERVER_CLASSID_NUM];
104 classIdHfp[0].type = BT_UUID_16;
105 classIdHfp[0].uuid16 = HFP_AG_UUID_SERVCLASS_HFP_AG;
106 classIdHfp[1].type = BT_UUID_16;
107 classIdHfp[1].uuid16 = HFP_AG_UUID_SERVCLASS_GENERIC_AUDIO;
108 return SDP_AddServiceClassIdList(sdpHandle_, classIdHfp, HFP_AG_SERVER_CLASSID_NUM);
109 default:
110 break;
111 }
112 return BT_CONFIG_ERROR;
113 }
114
AddProtocol(uint8_t scn) const115 int HfpAgSdpServer::AddProtocol(uint8_t scn) const
116 {
117 SdpProtocolDescriptor protocol[HFP_AG_SERVER_PROTOCOL_NUM];
118 protocol[0].protocolUuid.type = BT_UUID_16;
119 protocol[0].protocolUuid.uuid16 = UUID_PROTOCOL_L2CAP;
120 protocol[0].parameterNumber = 0;
121 protocol[1].protocolUuid.type = BT_UUID_16;
122 protocol[1].protocolUuid.uuid16 = UUID_PROTOCOL_RFCOMM;
123 protocol[1].parameterNumber = 1;
124 protocol[1].parameter[0].type = SDP_TYPE_UINT_8;
125 protocol[1].parameter[0].value = scn;
126 return SDP_AddProtocolDescriptorList(sdpHandle_, protocol, HFP_AG_SERVER_PROTOCOL_NUM);
127 }
128
AddProfile() const129 int HfpAgSdpServer::AddProfile() const
130 {
131 switch(hspState_) {
132 case HSP_AG_STATE_BOTH:
133 SdpProfileDescriptor profileBoth[HFP_AG_HSP_SERVER_PROFILE_NUM];
134 profileBoth[0].profileUuid.type = BT_UUID_16;
135 profileBoth[0].profileUuid.uuid16 = HFP_AG_UUID_SERVCLASS_HFP_AG;
136 profileBoth[0].versionNumber = HFP_AG_HFP_VERSION_1_7;
137 profileBoth[1].profileUuid.type = BT_UUID_16;
138 profileBoth[1].profileUuid.uuid16 = HSP_AG_UUID_SERVCLASS;
139 profileBoth[1].versionNumber = HSP_AG_HSP_VERSION_1_2;
140 return SDP_AddBluetoothProfileDescriptorList(sdpHandle_, profileBoth, HFP_AG_HSP_SERVER_PROFILE_NUM);
141 case HSP_AG_STATE_HSP:
142 SdpProfileDescriptor profileHsp[HFP_AG_SERVER_PROFILE_NUM];
143 profileHsp[0].profileUuid.type = BT_UUID_16;
144 profileHsp[0].profileUuid.uuid16 = HSP_AG_UUID_SERVCLASS;
145 profileHsp[0].versionNumber = HSP_AG_HSP_VERSION_1_2;
146 return SDP_AddBluetoothProfileDescriptorList(sdpHandle_, profileHsp, HFP_AG_SERVER_PROFILE_NUM);
147 case HSP_AG_STATE_NONE:
148 SdpProfileDescriptor profileHfp[HFP_AG_SERVER_PROFILE_NUM];
149 profileHfp[0].profileUuid.type = BT_UUID_16;
150 profileHfp[0].profileUuid.uuid16 = HFP_AG_UUID_SERVCLASS_HFP_AG;
151 profileHfp[0].versionNumber = HFP_AG_HFP_VERSION_1_7;
152 return SDP_AddBluetoothProfileDescriptorList(sdpHandle_, profileHfp, HFP_AG_SERVER_PROFILE_NUM);
153 default:
154 break;
155 }
156 return BT_CONFIG_ERROR;
157 }
158
AddServiceName() const159 int HfpAgSdpServer::AddServiceName() const
160 {
161 return SDP_AddServiceName(sdpHandle_, SDP_ATTRIBUTE_PRIMARY_LANGUAGE_BASE,
162 HFP_AG_SERVER_SERVICE_NAME.c_str(), HFP_AG_SERVER_SERVICE_NAME.length());
163 }
164
AddNetwork() const165 int HfpAgSdpServer::AddNetwork() const
166 {
167 uint32_t features = HfpAgDataConnection::GetLocalFeatures();
168 uint8_t networkValue = (features & HFP_AG_FEATURES_REJECT_CALL) ? 1 : 0;
169 SdpAttribute network;
170 network.attributeId = HFP_AG_SDP_ATTRIBUTE_DATA_STORES_OR_NETWORK;
171 network.type = SDP_TYPE_UINT_8;
172 network.attributeValueLength = HFP_AG_SERVER_NETWORK_LENGTH;
173 network.attributeValue = &networkValue;
174 return AddAttribute(network);
175 }
176
AddFeatures() const177 int HfpAgSdpServer::AddFeatures() const
178 {
179 uint32_t features = HfpAgDataConnection::GetLocalFeatures();
180 bool codecMSBC = (features & HFP_AG_FEATURES_CODEC_NEGOTIATION) ? true : false;
181 features &= HFP_AG_FEATURES_SDP_SPEC;
182 if (codecMSBC) {
183 // Codec bit position is different in SDP (bit 5) and in BRSF (bit 7)
184 features |= HFP_AG_HF_FEATURES_SUPPORT_WBS;
185 }
186 SdpAttribute featuresAttr;
187 featuresAttr.attributeId = HFP_AG_SDP_ATTRIBUTE_SUPPORTED_FEATURES;
188 featuresAttr.type = SDP_TYPE_UINT_16;
189 featuresAttr.attributeValueLength = HFP_AG_SERVER_FEATURES_LENGTH;
190 featuresAttr.attributeValue = &features;
191 return AddAttribute(featuresAttr);
192 }
193
AddBrowseGroupList() const194 int HfpAgSdpServer::AddBrowseGroupList() const
195 {
196 BtUuid browseGroupList[HFP_AG_SERVER_BROWSE_LIST_NUM];
197 browseGroupList[0].type = BT_UUID_16;
198 browseGroupList[0].uuid16 = SDP_PUBLIC_BROWSE_GROUP_ROOT_UUID;
199 return SDP_AddBrowseGroupList(sdpHandle_, browseGroupList, HFP_AG_SERVER_BROWSE_LIST_NUM);
200 }
201
AddAttribute(const SdpAttribute & attribute) const202 int HfpAgSdpServer::AddAttribute(const SdpAttribute &attribute) const
203 {
204 return SDP_AddAttribute(
205 sdpHandle_, attribute.attributeId, attribute.type, attribute.attributeValue, attribute.attributeValueLength);
206 }
207 } // namespace bluetooth
208 } // namespace OHOS