1 // Copyright 2022 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include <cstdint> 17 #include <optional> 18 19 #include "pw_bluetooth/types.h" 20 #include "pw_span/span.h" 21 22 namespace pw::bluetooth::gatt { 23 24 // A Handle uniquely identifies a service, characteristic, or descriptor. 25 enum class Handle : uint64_t {}; 26 27 // Possible values for the characteristic properties bitfield. These specify 28 // the GATT procedures that are allowed for a particular characteristic. 29 enum class CharacteristicPropertyBits : uint16_t { 30 kBroadcast = 0x1, 31 kRead = 0x2, 32 kWriteWithoutResponse = 0x4, 33 kWrite = 0x8, 34 kNotify = 0x10, 35 kIndicate = 0x20, 36 kAuthenticatedSignedWrites = 0x40, 37 kReliableWrite = 0x100, 38 kWritableAuxiliaries = 0x200 39 }; 40 41 // Helper operators to allow combining and comparing CharacteristicPropertyBits 42 // values. 43 inline constexpr bool operator&(CharacteristicPropertyBits left, 44 CharacteristicPropertyBits right) { 45 return static_cast<bool>( 46 static_cast<std::underlying_type_t<CharacteristicPropertyBits>>(left) & 47 static_cast<std::underlying_type_t<CharacteristicPropertyBits>>(right)); 48 } 49 50 inline constexpr CharacteristicPropertyBits operator|( 51 CharacteristicPropertyBits left, CharacteristicPropertyBits right) { 52 return static_cast<CharacteristicPropertyBits>( 53 static_cast<std::underlying_type_t<CharacteristicPropertyBits>>(left) | 54 static_cast<std::underlying_type_t<CharacteristicPropertyBits>>(right)); 55 } 56 57 inline constexpr CharacteristicPropertyBits& operator|=( 58 CharacteristicPropertyBits& left, CharacteristicPropertyBits right) { 59 return left = left | right; 60 } 61 62 // Represents encryption, authentication, and authorization permissions that can 63 // be assigned to a specific access permission. 64 struct SecurityRequirements { 65 // If true, the physical link must be encrypted to access this attribute. 66 bool encryption_required; 67 68 // If true, the physical link must be authenticated to access this 69 // attribute. 70 bool authentication_required; 71 72 // If true, the client needs to be authorized before accessing this 73 // attribute. 74 bool authorization_required; 75 }; 76 77 /// Specifies the access permissions for a specific attribute value. 78 struct AttributePermissions { 79 // Specifies whether or not an attribute has the read permission. If null, 80 // then the attribute value cannot be read. Otherwise, it can be read only if 81 // the permissions specified in the SecurityRequirements table are satisfied. 82 std::optional<SecurityRequirements> read; 83 84 // Specifies whether or not an attribute has the write permission. If null, 85 // then the attribute value cannot be written. Otherwise, it can be written 86 // only if the permissions specified in the SecurityRequirements table are 87 // satisfied. 88 std::optional<SecurityRequirements> write; 89 90 // Specifies the security requirements for a client to subscribe to 91 // notifications or indications on a characteristic. A characteristic's 92 // support for notifications or indications is specified using the NOTIFY and 93 // INDICATE characteristic properties. If a local characteristic has one of 94 // these properties then this field can not be null. Otherwise, this field 95 // must be left as null. 96 // 97 // This field is ignored for Descriptors. 98 std::optional<SecurityRequirements> update; 99 }; 100 101 // Represents a local or remote GATT characteristic descriptor. 102 struct Descriptor { 103 // Uniquely identifies this descriptor within a service. 104 // For local descriptors, the specified handle must be unique 105 // across all characteristic and descriptor handles in this service. 106 Handle handle; 107 108 // The UUID that identifies the type of this descriptor. 109 Uuid type; 110 111 // The attribute permissions of this descriptor. For remote descriptors, this 112 // value will be null until the permissions are discovered via read and write 113 // requests. 114 std::optional<AttributePermissions> permissions; 115 }; 116 117 // Represents a local or remote GATT characteristic. 118 struct Characteristic { 119 // Uniquely identifies this characteristic within a service. 120 // For local characteristics, the specified handle must be unique across 121 // all characteristic and descriptor handles in this service. 122 Handle handle; 123 124 // The UUID that identifies the type of this characteristic. 125 Uuid type; 126 127 // The characteristic properties bitfield. This is a logic or of any number of 128 // values from `CharacteristicPropertyBits` above. 129 CharacteristicPropertyBits properties; 130 131 // The attribute permissions of this characteristic. For remote 132 // characteristics, this value will be null until the permissions are 133 // discovered via read and write requests. 134 std::optional<AttributePermissions> permissions; 135 136 // The descriptors of this characteristic. 137 span<const Descriptor> descriptors; 138 }; 139 140 } // namespace pw::bluetooth::gatt