1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <type_traits>
19 
20 #include "common/strings.h"
21 #include "hci/hci_packets.h"
22 
23 // Define new enums or parsers for existing enums
24 namespace bluetooth {
25 namespace hci {
26 
27 // Must be 0b00, 0b01, 0b10, and 0b11 as this is a bit mask
28 enum DeviceType { UNKNOWN = 0, BR_EDR = 1, LE = 2, DUAL = 3 };
29 
30 // Scan mode from legacy stack, which is different from hci::ScanEnable
31 enum LegacyScanMode { BT_SCAN_MODE_NONE = 0, BT_SCAN_MODE_CONNECTABLE = 1, BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE = 2 };
32 
33 }  // namespace hci
34 
35 // Must be defined in bluetooth namespace
36 template <typename T, typename std::enable_if<std::is_same_v<T, hci::DeviceType>, int>::type = 0>
FromLegacyConfigString(const std::string & str)37 std::optional<hci::DeviceType> FromLegacyConfigString(const std::string& str) {
38   auto raw_value = common::Int64FromString(str);
39   if (!raw_value) {
40     return std::nullopt;
41   }
42   if (*raw_value < hci::DeviceType::UNKNOWN || *raw_value > hci::DeviceType::DUAL) {
43     return std::nullopt;
44   }
45   return static_cast<hci::DeviceType>(*raw_value);
46 }
47 
48 // Must be defined in bluetooth namespace
49 template <typename T, typename std::enable_if<std::is_same_v<T, hci::AddressType>, int>::type = 0>
FromLegacyConfigString(const std::string & str)50 std::optional<hci::AddressType> FromLegacyConfigString(const std::string& str) {
51   auto raw_value = common::Int64FromString(str);
52   if (!raw_value) {
53     return std::nullopt;
54   }
55   if (*raw_value < static_cast<int64_t>(hci::AddressType::PUBLIC_DEVICE_ADDRESS) ||
56       *raw_value > static_cast<int64_t>(hci::AddressType::RANDOM_IDENTITY_ADDRESS)) {
57     return std::nullopt;
58   }
59   return static_cast<hci::AddressType>(*raw_value);
60 }
61 
62 // Must be defined in bluetooth namespace
63 template <typename T, typename std::enable_if<std::is_same_v<T, hci::KeyType>, int>::type = 0>
FromLegacyConfigString(const std::string & str)64 std::optional<hci::KeyType> FromLegacyConfigString(const std::string& str) {
65   auto raw_value = common::Int64FromString(str);
66   if (!raw_value) {
67     return std::nullopt;
68   }
69   if (*raw_value < static_cast<int64_t>(hci::KeyType::COMBINATION) ||
70       *raw_value > static_cast<int64_t>(hci::KeyType::AUTHENTICATED_P256)) {
71     return std::nullopt;
72   }
73   return static_cast<hci::KeyType>(*raw_value);
74 }
75 
76 // Must be defined in bluetooth namespace
77 template <typename T, typename std::enable_if<std::is_same_v<T, hci::LegacyScanMode>, int>::type = 0>
FromLegacyConfigString(const std::string & str)78 std::optional<hci::LegacyScanMode> FromLegacyConfigString(const std::string& str) {
79   auto raw_value = common::Int64FromString(str);
80   if (!raw_value) {
81     return std::nullopt;
82   }
83   if (*raw_value < static_cast<int64_t>(hci::LegacyScanMode::BT_SCAN_MODE_NONE) ||
84       *raw_value > static_cast<int64_t>(hci::LegacyScanMode::BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE)) {
85     return std::nullopt;
86   }
87   return static_cast<hci::LegacyScanMode>(*raw_value);
88 }
89 
90 }  // namespace bluetooth