1# Copyright 2024 Google LLC 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# 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, 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"""Class to hold the GATT service/characteristic/descriptor object.""" 15 16import uuid 17 18 19class Service: 20 """Class represents Bluetooth GATT service.""" 21 22 def __init__(self, 23 instance_id=None, 24 service_type=None, 25 uuid=None, 26 characteristics=None, 27 included_services=None, 28 value=None): 29 self.instance_id = instance_id 30 self.service_type = service_type 31 self.uuid = uuid 32 self.characteristics = characteristics 33 self.included_services = included_services 34 self.value = value 35 36 def to_dict(self): 37 """Converts service object to dictionary. 38 39 Returns: 40 GATT service as dict. 41 """ 42 return { 43 'instance_id': self.instance_id, 44 'service_type': self.service_type, 45 'uuid': self.uuid, 46 'included_services': [service.to_dict() for service in self.included_services], 47 'characteristics': [characteristic.to_dict() for characteristic in self.characteristics], 48 'value': self.value 49 } 50 51 52class Characteristic: 53 """Class represents Bluetooth GATT characteristic.""" 54 55 def __init__(self, 56 instance_id=None, 57 permissions=None, 58 write_type=None, 59 descriptors=None, 60 uuid=None, 61 key_size=None, 62 properties=None, 63 value=None): 64 self.instance_id = instance_id 65 self.permissions = permissions 66 self.write_type = write_type 67 self.descriptors = descriptors 68 self.uuid = uuid 69 self.key_size = key_size 70 self.properties = properties 71 self.value = value 72 73 def to_dict(self): 74 """Converts characteristic object to dictionary. 75 76 Returns: 77 GATT characteristic as dict. 78 """ 79 return { 80 'properties': self.properties, 81 'permissions': self.permissions, 82 'uuid': self.uuid, 83 'instance_id': self.instance_id, 84 'descriptors': [descriptor.to_dict() for descriptor in self.descriptors], 85 'key_size': self.key_size, 86 'write_type': self.write_type, 87 'value': self.value 88 } 89 90 91class Descriptor: 92 """Class represents Bluetooth GATT descriptor.""" 93 94 def __init__(self, permissions=None, uuid=None, instance_id=None, value=None): 95 self.permissions = permissions 96 self.uuid = uuid 97 self.instance_id = instance_id 98 self.value = value 99 100 def to_dict(self): 101 """Converts descriptor object to dictionary. 102 103 Returns: 104 GATT descriptor as dict. 105 """ 106 return { 107 'instance_id': self.instance_id, 108 'permissions': self.permissions, 109 'uuid': self.uuid, 110 'value': self.value 111 } 112 113 114def create_gatt_service(service): 115 """Creates GATT service from a dictionary. 116 117 Args: 118 service: Bluetooth GATT service as a dictionary. 119 120 Returns: 121 Bluetooth GATT service object. 122 """ 123 return Service( 124 instance_id=service['instance_id'], 125 service_type=service['service_type'], 126 uuid=str(uuid.UUID(bytes=bytes(service['uuid']))).upper(), 127 included_services=[create_gatt_service(included_service) for included_service in service['included_services']], 128 characteristics=[create_gatt_characteristic(characteristic) for characteristic in service['characteristics']], 129 value=service.get('value')) 130 131 132def create_gatt_characteristic(characteristic): 133 """Creates GATT characteristic from a dictionary. 134 135 Args: 136 characteristic: Bluetooth GATT characteristic as a dictionary. 137 138 Returns: 139 Bluetooth GATT characteristic object. 140 """ 141 return Characteristic( 142 properties=characteristic['properties'], 143 permissions=characteristic['permissions'], 144 uuid=str(uuid.UUID(bytes=bytes(characteristic['uuid']))).upper(), 145 instance_id=characteristic['instance_id'], 146 descriptors=[create_gatt_characteristic_descriptor(descriptor) for descriptor in characteristic['descriptors']], 147 key_size=characteristic['key_size'], 148 write_type=characteristic['write_type'], 149 value=characteristic.get('value')) 150 151 152def create_gatt_characteristic_descriptor(descriptor): 153 """Creates GATT descriptor from a dictionary. 154 155 Args: 156 descriptor: Bluetooth GATT descriptor as a dictionary. 157 158 Returns: 159 Bluetooth GATT descriptor object. 160 """ 161 return Descriptor(instance_id=descriptor['instance_id'], 162 permissions=descriptor['permissions'], 163 uuid=str(uuid.UUID(bytes=bytes(descriptor['uuid']))).upper(), 164 value=descriptor.get('value')) 165 166 167def convert_object_to_dict(obj): 168 """Coverts object to dictionary. 169 170 Args: 171 obj: Service/Characteristic/Descriptor object. 172 173 Returns: 174 A dictionary represents the object. 175 """ 176 if isinstance(obj, (Descriptor, Characteristic, Service)): 177 return obj.to_dict() 178 elif isinstance(obj, list): 179 return [convert_object_to_dict(item) for item in obj] 180 else: 181 return obj 182