/* * Copyright (C) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "sdp_util.h" #include <stdio.h> #include <string.h> #include "bt_endian.h" #include "log.h" static bool g_sdpEnableState = true; void SdpSetEnableState() { g_sdpEnableState = true; } void SdpSetDisableState() { g_sdpEnableState = false; } bool SdpGetEnableState() { return g_sdpEnableState; } void SdpReverseForBigEndian(const uint8_t *src, uint8_t *dst, int length) { for (int i = 0; i < length; i++) { dst[length - 1 - i] = src[i]; } } uint16_t SdpAddAttributeForUuid(uint8_t *buffer, uint16_t offset, const BtUuid *uuid) { switch (uuid->type) { case BT_UUID_16: /// Data Element: UUID 2 bytes (0x19) buffer[offset] = (DE_TYPE_UUID << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16; offset++; /// UUID *(uint16_t *)(buffer + offset) = H2BE_16(uuid->uuid16); offset += SDP_UUID16_LENGTH; break; case BT_UUID_32: /// Data Element: UUID 4 bytes (0x1A) buffer[offset] = (DE_TYPE_UUID << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32; offset++; /// UUID *(uint32_t *)(buffer + offset) = H2BE_32(uuid->uuid32); offset += SDP_UUID32_LENGTH; break; case BT_UUID_128: /// Data Element: UUID 16 bytes (0x1C) buffer[offset] = (DE_TYPE_UUID << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_128; offset++; /// UUID SdpReverseForBigEndian(uuid->uuid128, buffer + offset, SDP_UUID128_LENGTH); offset += SDP_UUID128_LENGTH; break; default: LOG_ERROR("[%{public}s][%{public}d] Wrong type [0x%02x]", __FUNCTION__, __LINE__, uuid->type); break; } return offset; } /** * @brief Get length from type * @details * @param * @return */ uint16_t SdpGetLengthFromType(const uint8_t *buffer, uint8_t type, uint32_t *length) { uint16_t offset = 0; SdpDescriptorSize size = type & 0x07; switch (size) { case DE_SIZE_8: offset = SDP_UINT8_LENGTH; *length = SDP_UINT8_LENGTH; break; case DE_SIZE_16: offset = SDP_UINT16_LENGTH; *length = SDP_UINT16_LENGTH; break; case DE_SIZE_32: offset = SDP_UINT32_LENGTH; *length = SDP_UINT32_LENGTH; break; case DE_SIZE_64: offset = SDP_UINT64_LENGTH; *length = SDP_UINT64_LENGTH; break; case DE_SIZE_128: offset = SDP_UINT128_LENGTH; *length = SDP_UINT128_LENGTH; break; case DE_SIZE_VAR_8: offset = 1; *length = buffer[0]; break; case DE_SIZE_VAR_16: offset = SDP_UINT16_LENGTH; *length = BE2H_16(*(uint16_t *)buffer); break; case DE_SIZE_VAR_32: offset = SDP_UINT32_LENGTH; *length = BE2H_32(*(uint32_t *)buffer); break; default: LOG_ERROR("[%{public}s][%{public}d] Wrong size [%{public}d]", __FUNCTION__, __LINE__, size); break; } return offset; } uint16_t SdpGetUuid(uint8_t *buffer, BtUuid *uuid) { uint32_t length = 0; uint16_t offset = 0; uint8_t type = buffer[0]; offset++; SdpGetLengthFromType(buffer + offset, type, &length); if ((type >> SDP_DESCRIPTOR_SIZE_BIT) != DE_TYPE_UUID) { LOG_ERROR("[%{public}s][%{public}d] Wrong type [0x%02x]", __FUNCTION__, __LINE__, type); return offset; } switch (length) { case SDP_UUID16_LENGTH: uuid->type = BT_UUID_16; uuid->uuid16 = BE2H_16(*(uint16_t *)(buffer + offset)); break; case SDP_UUID32_LENGTH: uuid->type = BT_UUID_32; uuid->uuid32 = BE2H_32(*(uint32_t *)(buffer + offset)); break; case SDP_UUID128_LENGTH: uuid->type = BT_UUID_128; SdpReverseForBigEndian(buffer + offset, uuid->uuid128, SDP_UUID128_LENGTH); break; default: LOG_ERROR("[%{public}s][%u] Wrong length [0x%02x]", __FUNCTION__, __LINE__, length); break; } offset += length; return offset; }