* Copyright (C) 2022 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.
*/
#ifndef LOG_TAG
#define LOG_TAG "bt_fwk_utils"
#endif
#include "bluetooth_utils.h"
#include <map>
#include <chrono>
#include <random>
#if defined(IOS_PLATFORM)
#include <regex>
#endif
#include "securec.h"
#include "__config"
#include "bluetooth_def.h"
#include "bluetooth_host_proxy.h"
#include "bluetooth_log.h"
#include "iosfwd"
#include "iservice_registry.h"
#include "string"
#include "system_ability_definition.h"
using namespace std;
namespace OHOS {
namespace Bluetooth {
constexpr int startPos = 6;
constexpr int endPos = 13;
#if defined(IOS_PLATFORM)
constexpr int START_POS_IOS_PLATFORM = 9;
constexpr int END_POS_IOS_PLATFORM = 22;
#endif
constexpr int RANDOM_ADDR_ARRAY_SIZE = 4;
constexpr int RANDOM_ADDR_MAC_BIT_SIZE = 12;
constexpr int RANDOM_ADDR_FIRST_BIT = 1;
constexpr int RANDOM_ADDR_LAST_BIT = 11;
constexpr int RANDOM_ADDR_SPLIT_SIZE = 2;
constexpr int HEX_BASE = 16;
constexpr int OCT_BASE = 8;
std::string GetEncryptAddr(std::string addr)
{
#if defined(IOS_PLATFORM)
const std::regex deviceIdRegex("^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$");
if (!regex_match(addr, deviceIdRegex)) {
return std::string("");
}
std::string tmp = "********-****-****-****-************";
std::string out = addr;
for (int i = START_POS_IOS_PLATFORM; i <= END_POS_IOS_PLATFORM; i++) {
out[i] = tmp[i];
}
return out;
#else
if (addr.empty() || addr.length() != ADDRESS_LENGTH) {
HILOGD("addr is invalid.");
return std::string("");
}
std::string tmp = "**:**:**:**:**:**";
std::string out = addr;
for (int i = startPos; i <= endPos; i++) {
out[i] = tmp[i];
}
return out;
#endif
}
std::string GetBtStateName(int state)
{
switch (state) {
case BTStateID::STATE_TURNING_ON:
return "STATE_TURNING_ON(0)";
case BTStateID::STATE_TURN_ON:
return "STATE_TURN_ON(1)";
case BTStateID::STATE_TURNING_OFF:
return "STATE_TURNING_OFF(2)";
case BTStateID::STATE_TURN_OFF:
return "STATE_TURN_OFF(3)";
default:
return "Unknown";
}
}
std::string GetBtTransportName(int transport)
{
switch (transport) {
case BTTransport::ADAPTER_BREDR:
return "ADAPTER_BREDR(0)";
case BTTransport::ADAPTER_BLE:
return "ADAPTER_BLE(1)";
default:
return "Unknown";
}
}
std::string GetProfileConnStateName(int state)
{
switch (state) {
case static_cast<int>(BTConnectState::CONNECTING):
return "CONNECTING(0)";
case static_cast<int>(BTConnectState::CONNECTED):
return "CONNECTED(1)";
case static_cast<int>(BTConnectState::DISCONNECTING):
return "DISCONNECTING(2)";
case static_cast<int>(BTConnectState::DISCONNECTED):
return "DISCONNECTED(3)";
default:
return "Unknown";
}
}
std::string GetUpdateOutputStackActionName(int action)
{
switch (action) {
case static_cast<int>(UpdateOutputStackAction::ACTION_WEAR):
return "WEAR(0)";
case static_cast<int>(UpdateOutputStackAction::ACTION_UNWEAR):
return "UNWEAR(1)";
case static_cast<int>(UpdateOutputStackAction::ACTION_ENABLE_FROM_REMOTE):
return "ENABLE_FROM_REMOTE(2)";
case static_cast<int>(UpdateOutputStackAction::ACTION_DISABLE_FROM_REMOTE):
return "DISABLE_FROM_REMOTE(3)";
case static_cast<int>(UpdateOutputStackAction::ACTION_ENABLE_WEAR_DETECTION):
return "ENABLE_WEAR_DETECTION(4)";
case static_cast<int>(UpdateOutputStackAction::ACTION_DISABLE_WEAR_DETECTION):
return "DISABLE_WEAR_DETECTION(5)";
case static_cast<int>(UpdateOutputStackAction::ACTION_USER_OPERATION):
return "USER_OPERATION(6)";
case static_cast<int>(UpdateOutputStackAction::ACTION_STOP_VIRTUAL_CALL):
return "STOP_VIRTUAL_CALL(7)";
case static_cast<int>(UpdateOutputStackAction::ACTION_UPDATE_DEVICE_TYPE):
return "UPDATE_DEVICE_TYPE(8)";
default:
return "Unknown";
}
}
static std::map<int32_t, std::string> BtErrCodeMap {
{ BtErrCode::BT_NO_ERROR, "BT_NO_ERROR" },
{ BtErrCode::BT_ERR_PERMISSION_FAILED, "BT_ERR_PERMISSION_FAILED" },
{ BtErrCode::BT_ERR_SYSTEM_PERMISSION_FAILED, "BT_ERR_SYSTEM_PERMISSION_FAILED" },
{ BtErrCode::BT_ERR_INVALID_PARAM, "BT_ERR_INVALID_PARAM" },
{ BtErrCode::BT_ERR_API_NOT_SUPPORT, "BT_ERR_API_NOT_SUPPORT" },
{ BtErrCode::BT_ERR_SERVICE_DISCONNECTED, "BT_ERR_SERVICE_DISCONNECTED" },
{ BtErrCode::BT_ERR_UNBONDED_DEVICE, "BT_ERR_UNBONDED_DEVICE" },
{ BtErrCode::BT_ERR_INVALID_STATE, "BT_ERR_INVALID_STATE" },
{ BtErrCode::BT_ERR_PROFILE_DISABLED, "BT_ERR_PROFILE_DISABLED" },
{ BtErrCode::BT_ERR_DEVICE_DISCONNECTED, "BT_ERR_DEVICE_DISCONNECTED" },
{ BtErrCode::BT_ERR_MAX_CONNECTION, "BT_ERR_MAX_CONNECTION" },
{ BtErrCode::BT_ERR_INTERNAL_ERROR, "BT_ERR_INTERNAL_ERROR" },
{ BtErrCode::BT_ERR_IPC_TRANS_FAILED, "BT_ERR_IPC_TRANS_FAILED" },
{ BtErrCode::BT_ERR_GATT_READ_NOT_PERMITTED, "BT_ERR_GATT_READ_NOT_PERMITTED" },
{ BtErrCode::BT_ERR_GATT_WRITE_NOT_PERMITTED, "BT_ERR_GATT_WRITE_NOT_PERMITTED" },
{ BtErrCode::BT_ERR_GATT_MAX_SERVER, "BT_ERR_GATT_MAX_SERVER" },
{ BtErrCode::BT_ERR_SPP_SERVER_STATE, "BT_ERR_SPP_SERVER_STATE" },
{ BtErrCode::BT_ERR_SPP_BUSY, "BT_ERR_SPP_BUSY" },
{ BtErrCode::BT_ERR_SPP_DEVICE_NOT_FOUND, "BT_ERR_SPP_DEVICE_NOT_FOUND" },
{ BtErrCode::BT_ERR_SPP_IO, "BT_ERR_SPP_IO" },
{ BtErrCode::BT_ERR_NO_ACTIVE_HFP_DEVICE, "Active hfp device is not exist." },
{ BtErrCode::BT_ERR_NULL_HFP_STATE_MACHINE, "Hfp state machine is not null." },
{ BtErrCode::BT_ERR_HFP_NOT_CONNECT, "Hfp is not connected." },
{ BtErrCode::BT_ERR_SCO_HAS_BEEN_CONNECTED, "Sco has been connected." },
{ BtErrCode::BT_ERR_VR_HAS_BEEN_STARTED, "Voice recognition has been started." },
{ BtErrCode::BT_ERR_AUDIO_NOT_IDLE, "Audio is not idle." },
{ BtErrCode::BT_ERR_VIRTUAL_CALL_NOT_STARTED, "Virtual call is not started." },
{ BtErrCode::BT_ERR_DISCONNECT_SCO_FAILED, "Disconnect sco failed." },
{ BtErrCode::BT_ERR_PARAM_NOT_COMPLIANT, "Param not match specification." },
{ BtErrCode::BT_ERR_UNPAIRED_DEVICE, "Device is not paired." },
{ BtErrCode::BT_ERR_HID_APPLICATION_NOT_IN_FOREGROUND, "HID application is not in the foreground."},
{ BtErrCode::BT_ERR_HID_APP_HAS_BEEN_REGISTERED, "Any HID application has been registered."},
{ BtErrCode::BT_ERR_HID_APP_NOT_REGISTER, "HID application does not register."},
{ BtErrCode::BT_ERR_HID_DEVICE_NOT_CONNECTED, "HID device not connected."},
};
std::string GetErrorCode(int32_t errCode)
{
std::string errlog = "unknown error code: ";
auto iter = BtErrCodeMap.find(errCode);
if (iter != BtErrCodeMap.end()) {
errlog = iter->second;
}
errlog.append("(").append(std::to_string(errCode)).append(")");
return errlog;
}
void ToUpper(char* arr)
{
for (size_t i = 0; i < strlen(arr); ++i) {
if (arr[i] >= 'a' && arr[i] <= 'z') {
arr[i] = toupper(arr[i]);
}
}
}
std::string GenerateRandomMacAddress()
{
std::string randomMac = "";
char strMacTmp[RANDOM_ADDR_ARRAY_SIZE] = {0};
std::mt19937_64 gen(std::chrono::high_resolution_clock::now().time_since_epoch().count());
for (int i = 0; i < RANDOM_ADDR_MAC_BIT_SIZE; i++) {
int ret = -1;
if (i != RANDOM_ADDR_FIRST_BIT) {
std::uniform_int_distribution<> distribution(0, HEX_BASE - 1);
ret = sprintf_s(strMacTmp, RANDOM_ADDR_ARRAY_SIZE, "%x", distribution(gen));
} else {
std::uniform_int_distribution<> distribution(0, OCT_BASE - 1);
ret = sprintf_s(strMacTmp, RANDOM_ADDR_ARRAY_SIZE, "%x", RANDOM_ADDR_SPLIT_SIZE * distribution(gen));
}
if (ret == -1) {
HILOGE("GenerateRandomMacAddress failed, sprintf_s return -1!");
}
ToUpper(strMacTmp);
randomMac += strMacTmp;
if ((i % RANDOM_ADDR_SPLIT_SIZE != 0 && (i != RANDOM_ADDR_LAST_BIT))) {
randomMac.append(":");
}
}
return randomMac;
}
bool CheckConnectionStrategyInvalid(int32_t strategy)
{
if (strategy == static_cast<int32_t>(BTStrategyType::CONNECTION_ALLOWED) ||
strategy == static_cast<int32_t>(BTStrategyType::CONNECTION_FORBIDDEN)) {
return true;
}
return false;
}
bool CheckAccessAuthorizationInvalid(int32_t accessAuthorization)
{
if (accessAuthorization == static_cast<int32_t>(BTPermissionType::ACCESS_UNKNOWN) ||
accessAuthorization == static_cast<int32_t>(BTPermissionType::ACCESS_ALLOWED) ||
accessAuthorization == static_cast<int32_t>(BTPermissionType::ACCESS_FORBIDDEN)) {
return true;
}
return false;
}
}
}