• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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