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