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 {
32   BT_SCAN_MODE_NONE = 0,
33   BT_SCAN_MODE_CONNECTABLE = 1,
34   BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE = 2
35 };
36 
37 }  // namespace hci
38 
39 // Must be defined in bluetooth namespace
40 template <typename T, typename std::enable_if<std::is_same_v<T, hci::DeviceType>, int>::type = 0>
FromLegacyConfigString(const std::string & str)41 std::optional<hci::DeviceType> FromLegacyConfigString(const std::string& str) {
42   auto raw_value = common::Int64FromString(str);
43   if (!raw_value) {
44     return std::nullopt;
45   }
46   if (*raw_value < hci::DeviceType::UNKNOWN || *raw_value > hci::DeviceType::DUAL) {
47     return std::nullopt;
48   }
49   return static_cast<hci::DeviceType>(*raw_value);
50 }
51 
52 // Must be defined in bluetooth namespace
53 template <typename T, typename std::enable_if<std::is_same_v<T, hci::AddressType>, int>::type = 0>
FromLegacyConfigString(const std::string & str)54 std::optional<hci::AddressType> FromLegacyConfigString(const std::string& str) {
55   auto raw_value = common::Int64FromString(str);
56   if (!raw_value) {
57     return std::nullopt;
58   }
59   if (*raw_value < static_cast<int64_t>(hci::AddressType::PUBLIC_DEVICE_ADDRESS) ||
60       *raw_value > static_cast<int64_t>(hci::AddressType::RANDOM_IDENTITY_ADDRESS)) {
61     return std::nullopt;
62   }
63   return static_cast<hci::AddressType>(*raw_value);
64 }
65 
66 // Must be defined in bluetooth namespace
67 template <typename T, typename std::enable_if<std::is_same_v<T, hci::KeyType>, int>::type = 0>
FromLegacyConfigString(const std::string & str)68 std::optional<hci::KeyType> FromLegacyConfigString(const std::string& str) {
69   auto raw_value = common::Int64FromString(str);
70   if (!raw_value) {
71     return std::nullopt;
72   }
73   if (*raw_value < static_cast<int64_t>(hci::KeyType::COMBINATION) ||
74       *raw_value > static_cast<int64_t>(hci::KeyType::AUTHENTICATED_P256)) {
75     return std::nullopt;
76   }
77   return static_cast<hci::KeyType>(*raw_value);
78 }
79 
80 // Must be defined in bluetooth namespace
81 template <typename T,
82           typename std::enable_if<std::is_same_v<T, hci::LegacyScanMode>, int>::type = 0>
FromLegacyConfigString(const std::string & str)83 std::optional<hci::LegacyScanMode> FromLegacyConfigString(const std::string& str) {
84   auto raw_value = common::Int64FromString(str);
85   if (!raw_value) {
86     return std::nullopt;
87   }
88   if (*raw_value < static_cast<int64_t>(hci::LegacyScanMode::BT_SCAN_MODE_NONE) ||
89       *raw_value >
90               static_cast<int64_t>(hci::LegacyScanMode::BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE)) {
91     return std::nullopt;
92   }
93   return static_cast<hci::LegacyScanMode>(*raw_value);
94 }
95 
96 }  // namespace bluetooth
97