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