Example #1
0
    def create_generic_attribute_service(self):
        gsrv = GattService()
        gsrv.uuid = BluetoothUuid(GattConst.UUID_GENERIC_ATTRIBUTE)
        gsrv.idstr = "generic_attribute"
        gsrv.capabilities = self.capabilities

        #service->caps = db->caps_declare;
        gsrv.chars.append(
            GattCharacteristic(uuid="2a05",
                               id="service_changed_char",
                               properties=GattConst.CHR_PROPERTY_INDICATE,
                               value=GattValue(GattConst.DynamicValue,
                                               bytearray(4)),
                               permissions=GattConst.Discoverable,
                               capabilities=self.capabilities))
        gsrv.chars.append(
            GattCharacteristic(uuid="2b2a",
                               id="database_hash",
                               properties=GattConst.CHR_PROPERTY_READ,
                               value=GattValue(GattConst.DynamicValue,
                                               bytearray(16)),
                               capabilities=self.capabilities))
        gsrv.chars.append(
            GattCharacteristic(uuid="2b29",
                               id="client_support_features",
                               properties=GattConst.CHR_PROPERTY_READ
                               | GattConst.CHR_PROPERTY_WRITE,
                               value=GattValue(GattConst.DynamicValue,
                                               bytearray(1)),
                               permissions=GattConst.Discoverable
                               | GattConst.Read | GattConst.Write,
                               capabilities=self.capabilities))

        return gsrv
Example #2
0
 def uuid_handle(self, uuid):
     if (not isinstance(uuid, BluetoothUuid)):
         uuid = BluetoothUuid(uuid)
     try:
         if (uuid.isshort):
             return self.uuid16s.index(uuid)
         return self.uuid128s.index(uuid) | 0x8000
     except ValueError:
         print("Error, UUID not found:", str(uuid))
         return 0
Example #3
0
    def __build_service(self, service):
        rows = []
        service.start = len(self.attribute_rows) + 1
        permissions = GattConst.Read | GattConst.Discoverable
        # service declaration attribute:
        if service.secondary is True:
            uuid = BluetoothUuid(GattConst.UUID_SECONDARY_SERVICE)
        else:
            uuid = BluetoothUuid(GattConst.UUID_PRIMARY_SERVICE)
            if service.advertise is True:
                permissions |= GattConst.Advertise
        value = GattValue(GattConst.ConstValue, service.uuid.bytes)
        service_declare = GattAttribute(uuid=uuid,
                                        permissions=permissions,
                                        value=value,
                                        capabilities=service.capabilities)
        rows.append(service_declare)

        #service includes
        for inc in service.include_service_ids:
            a = GattAttribute(uuid=GattConst.UUID_INCLUDE_SERVICE,
                              permissions=GattConst.Read
                              | GattConst.Discoverable,
                              capabilities=service.capabilities)
            a.include = inc
            rows.append(a)
            self.__add_uuid(a.uuid)

        #characteristic
        if service.chars is not None:
            for ch in service.chars:
                rows += (self.__build_characteristic_db(
                    ch,
                    len(self.attribute_rows) + len(rows) + 1))

        service.end = service.start + len(rows) - 1

        return rows
Example #4
0
    def set_services(self, services, add_generic_attribute_service=True):
        self.uuid16s = [
            BluetoothUuid(GattConst.UUID_PRIMARY_SERVICE),
            BluetoothUuid(GattConst.UUID_SECONDARY_SERVICE),
            BluetoothUuid(GattConst.UUID_CHR)
        ]
        self.uuid128s = []
        self.services = services

        #first add all uuids, this is to replicate bgbuild behaviour
        for s in self.services:
            self.__add_uuids_in_service(s)

        #create generic service
        if (add_generic_attribute_service):
            s = self.create_generic_attribute_service()
            self.__add_uuids_in_service(s)
            self.services = [s] + self.services
        #Create all attributes
        self.__build_atrribute_rows()

        #link includes
        #for s in self.services:
        #    self.__resolve_service_relations(s, services)
        for a in self.attribute_rows:
            #find include attributes
            if a.uuid == BluetoothUuid(GattConst.UUID_INCLUDE_SERVICE):
                included = next((s for s in services if s.idstr == a.include),
                                None)
                gatt_assert(
                    included != None,
                    "Included service " + a.include + " does not exist!")
                #gatt_assert(included != service, "Included service " + id + " cannot be self!")

                a.include = included
                a.value = GattValue(GattConst.ServiceInclude, bytearray())
Example #5
0
    def __add_uuid(self, uuid):
        if type(uuid) is not BluetoothUuid:
            uuid = BluetoothUuid(uuid)

        if self.__uuid_index(uuid) == -1:
            if uuid.isshort:
                try:
                    self.uuid16s.index(uuid)
                except ValueError:
                    self.uuid16s.append(uuid)
            else:
                try:
                    self.uuid128s.index(uuid)
                except ValueError:
                    self.uuid128s.append(uuid)
        return 1
Example #6
0
    def parse_service(self, xml,parent_caps):
        s = GattService()
        s.uuid = BluetoothUuid(xml.get('uuid', "00"))
        s.idstr = xml.get('id', "")
        s.secondary = xml.get('type', "primary") == "secondary"
        s.advertise = s.secondary is False and xml.get('advertise', "false") == "true"
        s.capabilities=self.parse_capabilities(xml,parent_caps)
        # description of service is informative and not exposed in the actual GATT database
        if xml.find('description') is not None:
            s.description = xml.find('description').text

        includes = xml.iterfind('include')
        for i in includes:
            s.include_service_ids.append(i.get('id', ""))

        cnodes = xml.iterfind('characteristic')
        for c in cnodes:
            s.chars.append(self.parse_characteristic(c,s.capabilities))
        return s
Example #7
0
    def __parse_attrobj(self, xml, attr):
        if attr.uuid == "0000":
            attr.uuid = BluetoothUuid(xml.get('uuid', "00"))
        attr.idstr = xml.get('id', "")

        const_value = True
        properties = GattConst.CHR_PROPERTY_READ
        permissions = GattConst.Read | GattConst.Discoverable
        ext_properties = 0
        if xml.find('properties') is not None:
            properties, permissions, const_value, ext_properties = self.parse_properties(xml.find('properties'))
        if xml.get("const","false") == "true":
            const_value = True
        attr.properties = properties
        attr.permissions = permissions
        attr.ext_properties = ext_properties
        if  xml.find('value') is not None:
            attr.value = self.parse_value( xml.find('value'))
        #if there is no value element, then use contents of the parent tag, backwards compability
        elif xml.text is not None:
            attr.value = self.parse_value(xml)
        if attr.value!=None and const_value is True:
            attr.value.type = GattConst.ConstValue
        return attr