1// Copyright (C) 2022 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://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, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// An EmulatedBluetoothService represents a bluetooth Gatt device. 16// The android emulator will connect to this service to read/write and 17// observe characteristics if the emulator establishes a connection 18// to this device. 19// 20// You will need to implement this service and register the endpoint with 21// the emulator to make this device discoverable. 22syntax = "proto3"; 23 24option java_multiple_files = true; 25option java_package = "com.android.emulator.bluetooth"; 26 27package android.emulation.bluetooth; 28import "grpc_endpoint_description.proto"; 29import "google/protobuf/empty.proto"; 30 31// You can provide your own GattDevice by implementing this service 32// and registering it with the android emulator. 33// 34// The device will appear as a real bluetooth device, and you will 35// receive callbacks when the bluetooth system wants to 36// read, write or observe a characteristic. 37service GattDeviceService { 38 // A remote client has requested to read a local characteristic. 39 // 40 // Return the current observed value. 41 rpc OnCharacteristicReadRequest(CharacteristicValueRequest) 42 returns (CharacteristicValueResponse); 43 44 // A remote client has requested to write to a local characteristic. 45 // 46 // Return the current observed value. 47 rpc OnCharacteristicWriteRequest(CharacteristicValueRequest) 48 returns (CharacteristicValueResponse); 49 50 // Listens for notifications from the emulated device, the device should 51 // write to the stream with a response when a change has occurred. 52 rpc OnCharacteristicObserveRequest(CharacteristicValueRequest) 53 returns (stream CharacteristicValueResponse); 54 55 // A remote device has been connected or disconnected. 56 rpc OnConnectionStateChange(ConnectionStateChange) 57 returns (google.protobuf.Empty); 58} 59 60// A callback identifier is used by the service to identify 61// who should handle the any of the requests above. 62// 63// This is only relevant if you have a single endpoint that 64// emulates multiple devices. 65message CallbackIdentifier { 66 string identity = 1; 67} 68 69// A Device Identifier is used to uniquely identify an emulated 70// bluetooth device on the rootcanal mesh. 71message DeviceIdentifier { 72 // A string that uniquely identifies this device on the 73 // rootcanal mesh. 74 string address = 1; 75} 76 77message ConnectionStateChange { 78 enum ConnectionState { 79 CONNECTION_STATE_UNDEFINED = 0; 80 // The profile is in disconnected state 81 CONNECTION_STATE_DISCONNECTED = 1; 82 // The profile is in connected state 83 CONNECTION_STATE_CONNECTED = 2; 84 } 85 86 // The identity of the device is receiving the state change. 87 CallbackIdentifier callback_device_id = 1; 88 89 // The identity of the device that is changing state. 90 DeviceIdentifier from_device = 2; 91 92 // The current state of the device 93 ConnectionState new_state = 3; 94} 95 96// A UUID is a universally unique identifier that is guaranteed to be unique 97// across all space and all time. UUIDs can be independently created in a 98// distributed fashion. No central registry of assigned UUIDs is required. A 99// UUID is a 128-bit value. 100// 101// To reduce the burden of storing and transferring 128-bit UUID values, a range 102// of UUID values has been pre-allocated for assignment to often-used, 103// registered purposes. 104// 105// The first UUID in this pre-allocated range is known as 106// the Bluetooth Base UUID and has the value 00000000-0000-1000-8000- 107// 00805F9B34FB, from Assigned Numbers. UUID values in the pre-allocated 108// range have aliases that are represented as 16-bit or 32-bit values. 109// 110// These aliases are often called 16-bit and 32-bit UUIDs, but each actually 111// represents a 128-bit UUID value. 112// 113// The full 128-bit value of a 16-bit or 32-bit 114// UUID may be computed by a simple arithmetic operation: 115// 116// 128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID 117// 128_bit_value = 32_bit_value * 2^96 + Bluetooth_Base_UUID 118// 119// A 16-bit UUID may be converted to 32-bit UUID format by zero-extending the 120// 16-bit value to 32-bits. An equivalent method is to add the 16-bit UUID value 121// to a zero-valued 32-bit UUID. 122// 123// Note: Two 16-bit UUIDs may be compared 124// directly, as may two 32-bit UUIDs or two 128-bit UUIDs. If two UUIDs of 125// differing sizes are to be compared, the shorter UUID must be converted to the 126// longer UUID format before comparison. 127message Uuid { 128 oneof short_or_long { 129 // The shortened bluetooth uuid, either 16/32 bit. 130 uint32 id = 1; 131 132 // The first 8 hex digits of the guid, if you are using 133 // 128 bit guid. These are the least significant bits. 134 uint64 lsb = 2; 135 } 136 137 // The next 8 hex digits of the guid, ignored if the lsb value is not set. 138 // These are the most significant bits. 139 int64 msb = 3; 140} 141 142// Data exchanged to read/write bluetooth characteristics 143message CharacteristicValueRequest { 144 // The identity of the device we are making this request to. The gRPC 145 // service for the emulated device must route the request to the actual 146 // device that emulates this identity. 147 // 148 // This is needed if you wish to emulate multipe devices on a single 149 // gRPC endpoint. 150 CallbackIdentifier callback_device_id = 1; 151 152 // The identity of the device that is making this request. 153 DeviceIdentifier from_device = 2; 154 155 // The specific callback id for which this request is. This is the 156 // callback_id used to register the given characteristic. If the value 157 // was not set it will be the uuid of the characteristic. 158 Uuid callback_id = 3; 159 160 // The raw data in the request. The application developer will 161 // need to parse the data and handle it properly. 162 bytes data = 4; 163} 164 165// Data exchanged to read/write bluetooth characteristics 166message CharacteristicValueResponse { 167 enum GattStatus { 168 GATT_STATUS_UNSPECIFIED = 0; 169 // A GATT operation completed successfully 170 GATT_STATUS_SUCCESS = 1; 171 // A GATT operation failed 172 GATT_STATUS_FAILURE = 2; 173 } 174 175 // The status of the request to be sent to the remote devices 176 GattStatus status = 1; 177 178 // The data of interest, this should contain the raw data according 179 // to the bluetooth specification for the requested charactersic uuid. 180 bytes data = 2; 181} 182 183message GattCharacteristic { 184 // The Characteristic Properties bit field determines how the Characteristic 185 // Value can be used, or how the characteristic descriptors can be accessed. 186 187 // Properties Value Description. 188 enum Properties { 189 PROPERTY_UNSPECIFIED = 0; 190 191 // If set, permits broadcasts of the Characteristic 192 // Value using Server Characteristic Configuration Descriptor. If set, 193 // the Server Characteristic Configuration Descriptor shall exist. 194 PROPERTY_BROADCAST = 0x01; 195 196 // If set, permits reads of the Characteristic Value using procedures 197 // defined in Section 4.8 198 PROPERTY_READ = 0x02; 199 200 // If set, permit writes of the Characteristic Value without response 201 // using procedures defined in Section 4.9.1. 202 PROPERTY_WRITE_NO_RESPONSE = 0x04; 203 204 // If set, permits writes of the Characteristic Value with response 205 // using procedures defined in Section 4.9.3 or Section 4.9.4. 206 PROPERTY_WRITE = 0x08; 207 208 // If set, permits notifications of a Characteristic Value without 209 // acknowledgment using the procedure defined in Section 4.10. If 210 // set, the Client Characteristic Configuration Descriptor shall exist. 211 PROPERTY_NOTIFY = 0x10; 212 213 // If set, permits indications of a Characteristic Value with 214 // acknowledgment using the procedure defined in Section 4.11. If set, 215 // the Client Characteristic Configuration Descriptor shall exist. 216 PROPERTY_INDICATE = 0x20; 217 218 // If set, permits signed writes to the Characteristic Value using the 219 // procedure defined in Section 4.9.2. 220 PROPERTY_SIGNED_WRITE = 0x40; 221 222 // If set, additional characteristic properties are defined in the 223 // Characteristic Extended Properties Descriptor defined in Section 224 // 3.3.3.1. If set, the Characteristic Extended Properties Descriptor 225 PROPERTY_EXTENDED_PROPS = 0x80; 226 } 227 228 // An attribute has a set of permission values associated with it. The 229 // permissions associated with an attribute specifies that it may be read 230 // and/or written. The permissions associated with the attribute specifies 231 // the security level required for read and/or write access, as well as 232 // notification and/or indication. The permissions of a given attribute are 233 // defined by a higher layer specification, and are not discoverable using 234 // the Attribute protocol. 235 enum Permissions { 236 PERMISSION_UNSPECIFIED = 0; 237 238 // Characteristic read permission 239 PERMISSION_READ = 0x01; 240 241 // Characteristic permission: Allow encrypted read operations 242 PERMISSION_READ_ENCRYPTED = 0x02; 243 244 // Characteristic permission: Allow reading with person-in-the-middle 245 // protection 246 PERMISSION_READ_ENCRYPTED_MITM = 0x04; 247 248 // Characteristic write permission 249 PERMISSION_WRITE = 0x10; 250 251 // Characteristic permission: Allow encrypted writes 252 PERMISSION_WRITE_ENCRYPTED = 0x20; 253 254 // Characteristic permission: Allow encrypted writes with 255 // person-in-the-middle protection 256 PERMISSION_WRITE_ENCRYPTED_MITM = 0x40; 257 258 // Characteristic permission: Allow signed write operations 259 PERMISSION_WRITE_SIGNED = 0x80; 260 261 // Characteristic permission: Allow signed write operations with 262 // person-in-the-middle protection 263 PERMISSION_WRITE_SIGNED_MITM = 0x100; 264 } 265 266 // The UUID identifying this characteristic, for a list of UUIDS: 267 // https://www.bluetooth.com/specifications/assigned-numbers/ 268 // 269 // Or (the much easier to use) XML definitions: 270 // https://github.com/sputnikdev/bluetooth-gatt-parser/tree/master/src/main/resources/gatt/characteristic 271 // 272 // For example the uuid=0x2A19 indicates the "The current charge level of a 273 // battery." 274 Uuid uuid = 1; 275 276 // Contains a mask of the properties described in the properties enum. 277 // Property definitions are *ONLY* required during device registration. 278 uint32 properties = 2; 279 280 // Contains a mask of the permissions described in the permissions enum. 281 // Permission definitions are *ONLY* required during device registration. 282 uint32 permissions = 3; 283 284 // The callback_id that will be set whenever a bluetooth request 285 // comes in for this characteristic. Defaults to the value in uuid (field 1) 286 // if it is not set. You will only need to set this if the same uuid is 287 // defined multiple defines in your service, and can be used to disambiguate 288 // which characterisic is requested. 289 Uuid callback_id = 4; 290} 291 292// A Gatt service definition. 293message GattService { 294 enum ServiceType { 295 SERVICE_TYPE_UNSPECIFIED = 0; 296 297 // Primary service 298 SERVICE_TYPE_PRIMARY = 0x01; 299 300 // Secondary service (included by primary services) 301 SERVICE_TYPE_SECONDARY = 0x02; 302 } 303 304 // The uuid of this service. This can be a: 16, 32 or 128 bit uuid. This 305 // is usually a well defined UUID from the bluetooth specification. For 306 // example 0x180D indicates a heart rate monitor. See 307 // https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/ 308 // for a list of well known uuid's. 309 Uuid uuid = 1; 310 ServiceType service_type = 2; 311 repeated GattCharacteristic characteristics = 3; 312} 313 314// A Gatt profile consists of a series of services that are offered 315// to clients. Gatt profiles are well defined in the spec. You can find 316// more information about the various profiles in the official specifications: 317// https://www.bluetooth.com/specifications/specs/ 318// 319// A concrete example is the Heart Rate Monitor: 320// https://www.bluetooth.com/specifications/specs/heart-rate-service-1-0/ 321message GattProfile { 322 repeated GattService services = 1; 323} 324 325// The advertisement definition, this will be used to advertise the 326// bluetooth device to android emulator. Every device that is registered 327// will be discoverable by the emulator. 328message Advertisement { 329 // The name of the device as an UTF-8 string. This is how the device will 330 // show up when android scans for devices. Only the first 29 bytes will show 331 // up on an in initial scan. 332 string device_name = 1; 333 334 enum ConnectionMode { 335 // None specified, defaults to undirected 336 CONNECTION_MODE_UNSPECIFIED = 0; 337 // Non-connectable, as per section 3.C.9.3.2 338 CONNECTION_MODE_NON_CONNECTABLE = 1; 339 // Directed-connectable, as per section 3.C.9.3.3 340 CONNECTION_MODE_DIRECTED = 2; 341 // Undirected-connectable, as per section 3.C.9.3.4 342 CONNECTION_MODE_UNDIRECTED = 3; 343 } 344 345 // Whether the advertisement type should be connectable or non-connectable. 346 ConnectionMode connection_mode = 2; 347 348 enum DiscoveryMode { 349 // None specified, defaults to general discoverable 350 DISCOVERY_MODE_UNSPECIFIED = 0; 351 // Non-discoverable, as per section 3.C.9.2.2). 352 DISCOVERY_MODE_NON_DISCOVERABLE = 1; 353 // Limited-discoverable, as per section 3.C.9.2.3). 354 DISCOVERY_MODE_LIMITED = 2; 355 // General-discoverable, as per section 3.C.9.2.4). 356 DISCOVERY_MODE_GENERAL = 3; 357 } 358 359 DiscoveryMode discovery_mode = 3; 360} 361 362message GattDevice { 363 // The endpoint where the emulated device can be found. This endpoint should 364 // provide an implementation of the GattDeviceService and must be 365 // reachable through the provided description. 366 android.emulation.remote.Endpoint endpoint = 1; 367 368 // How this device will be advertised. 369 Advertisement advertisement = 2; 370 371 // The bluetooth profile that is made available. 372 GattProfile profile = 3; 373} 374