def device_from_advertisement(self, peripheral, advertisementData, power): try: uuid = iprop(peripheral.identifier).UUIDString().cString() name = iprop(peripheral.name).cString() except Exception: return data = advertisementData.objectForKey_( CBAdvertisementDataKeys.ManufacturerData) if data: announcement = c.get_from_ptr(data.bytes().arg_ref, 'C', data.length()) return BleDevice(uuid, name, power, announcement=announcement, peripheral=peripheral) uuids = advertisementData.objectForKey_( CBAdvertisementDataKeys.ServiceUUIDs) if uuids: services = [] for i in range(iprop(uuids.count)): cbuuid = uuids.objectAtIndex_(i) services.append(iprop(cbuuid.UUIDString).cString()) return BleDevice(uuid, name, power, services=services, peripheral=peripheral) return None
def peripheral_didDiscoverServices_(self, peripheral, error): print('did discover services') if peripheral == self.peripheral: print(' is my peripheral') services = {} if not error: iservices = iprop(peripheral.services) count = iprop(iservices.count) print(' found', count, 'services') for i in range(count): iservice = iservices.objectAtIndex_(i) # uuid_string = iprop(iprop(iservice.UUID).UUIDString).cString() # if len(uuid_string) == 4: # uuid_string = '0000' + uuid_string + '-0000-1000-8000-00805F9B34FB' # uuid = UUID(uuid_string) uuid = cbuuid_to_uuid(iservice.UUID) print(' ', uuid) service = BleService(uuid, iservice) self.services[uuid] = service services[uuid] = service else: error = iprop(error.localizedDescription) print('error:', error) if callable(self.on_discover): self.on_discover(services, error)
def peripheral_didUpdateValueForCharacteristic_error_( self, peripheral, characteristic, error): print('did update value for characteristic') if error: error = iprop(error.localizedDescription) print('error:', error) if peripheral == self.peripheral: print(' is my peripheral') for service in self.services.values(): if service.service == iprop(characteristic.service): print(' found service', service) for char in service.characteristics.values(): if char.characteristic == characteristic: print(' found characteristic', char) if not error: value = iprop(characteristic.value) ref = iprop(value.bytes).arg_ref length = iprop(value.length) if length: char.value = bytearray( c.get_from_ptr(ref, 'C', length)) else: char.value = None if callable(char.on_read): char.on_read(char, error) return return
def peripheral_didDiscoverCharacteristicsForService_error_( self, peripheral, iservice, error): print('did discover characteristics') if error: error = iprop(error.localizedDescription) print('error:', error) if peripheral == self.peripheral: print(' is my peripheral') for service in self.services.values(): if service.service == iservice: print(' found service', service) characteristics = {} if not error: icharacteristics = iprop(iservice.characteristics) count = iprop(icharacteristics.count) print(' found', count, 'characteristics') for i in range(count): icharacteristic = icharacteristics.objectAtIndex_( i) uuid = cbuuid_to_uuid(icharacteristic.UUID) print(' ', uuid) characteristic = BleCharacteristic( uuid, service, icharacteristic) service.characteristics[uuid] = characteristic characteristics[uuid] = characteristic if callable(service.on_discover): service.on_discover(characteristics, error) return
def peripheralManager_didReceiveReadRequest_(self, peripheral, request): uuid = iprop(request.characteristic.UUID) for service in self.services.values(): for char in service.characteristics.values(): if iprop(char.characteristic.UUID).isEqual_(uuid): if char.value: if callable(char.on_read_request): char.on_read_request(char) data = char.create_data(char.value) request.value = data peripheral.respondToRequest_withResult_(request, 0) if callable(char.on_read): char.on_read(char) return
def query_cbcentral(self): while True: while self.cbcentral.hasEvents(): oevent = self.cbcentral.getEvent() event = [ oevent.objectAtIndex_(i) for i in range(iprop(oevent.count)) ] event[0] = iprop(event[0].cString) print('received event:', event) try: getattr(self, event[0])(*event[1:]) except Exception as e: print('bad event:', e) traceback.print_exc() sleep(0.1)
def centralManagerDidUpdateState_(self, central): self.state = iprop(central.state) if self.scanning and not self.bt_on: self.stop_scanning() if callable(self.on_state): self.on_state(self.state_description)
def centralManager_didFailToConnectPeripheral_error_( self, central, peripheral, error): print('did fail to connect peripheral') self.connecting = False if self.connect_to and self.connect_to.peripheral == peripheral: if callable(self.connect_callback): self.connect_callback(self.connect_to, iprop(error.localizedDescription))
def centralManager_didDisconnectPeripheral_error_(self, central, peripheral, error): print('did disconnect peripheral') self.connecting = False if self.connect_to and self.connect_to.peripheral == peripheral: if callable(self.disconnect_callback): errstr = iprop(error.localizedDescription) if error else None self.disconnect_callback(self.connect_to, errstr)
def peripheralManagerDidStartAdvertising_error_(self, peripheral, error): if error: if callable(self.on_advertising_error): desc = iprop(error.localizedDescription).cString() self.on_advertising_error(desc) else: if callable(self.on_advertising_started): self.on_advertising_started()
def peripheral_didWriteValueForCharacteristic_error_( self, peripheral, characteristic, error): print('did write value for characteristic') if error: error = iprop(error.localizedDescription) print('error:', error) if peripheral == self.peripheral: print(' is my peripheral') for service in self.services.values(): if service.service == iprop(characteristic.service): print(' found service', service) for char in service.characteristics.values(): if char.characteristic == characteristic: print(' found characteristic', char) if callable(char.on_write): char.on_write(char, error) return return
def centralManager_didConnectPeripheral_(self, central, peripheral): print('did connect peripheral') self.connecting = False device = self.connect_to if device and device.peripheral == peripheral: print('set delegate') peripheral.setDelegate_(device) if iprop(peripheral.services): device.peripheral_didDiscoverServices_(peripheral, None) if self.connect_callback: self.connect_callback(device)
def central_discovered_peripheral(self, device): if self.connecting or self.connected: return print("discovered peripheral, state", iprop(device.peripheral.state)) uuid_bytes = self.client_base_uuid_bytes for uuid, service in device.services.items(): if uuid.bytes[4:] == uuid_bytes: Logger.info("BLE: found device {}".format(uuid)) self.ble_should_scan = False self.stop_scanning() self.connect_uuid = uuid self.connect(device) return
def start_advertising(self, name): services = [ iprop(s.service.UUID) for s in self.pending_services.values() ] servarray = objc_arr(*services) if services else None adv_dict = {CBAdvertisementDataKeys.LocalName: name} if servarray: adv_dict[CBAdvertisementDataKeys.ServiceUUIDs] = servarray data = objc_dict(adv_dict) self.peripheral.startAdvertising_(data) for service in self.pending_services.values(): self.peripheral.addService_(service.service)
def respond_to_write_request(self, peripheral, request): uuid = iprop(request.characteristic.UUID) for service in self.services.values(): for char in service.characteristics.values(): if iprop(char.characteristic.UUID).isEqual_(uuid): value = request.value length = value.length() if length: char.value = bytearray( c.get_from_ptr( iprop(value.bytes).arg_ref, 'C', length)) else: char.value = None peripheral.respondToRequest_withResult_(request, 0) if callable(char.on_write): char.on_write(char) if callable(self.on_characteristic_write): self.on_characteristic_write(service, char) return peripheral.respondToRequest_withResult_(request, 0x0a) # attribute not found
def peripheralManager_didAddService_error_(self, peripheral, service, error): uuid = UUID(iprop(service.UUID).UUIDString.cString()) pending_service = self.pending_services.get(uuid, None) if pending_service: del self.pending_services[uuid] running_service = self.services.get(uuid, None) pyservice = running_service or pending_service or None if error: if running_service: del self.services[uuid] if callable(self.on_service_error): desc = error.localizedDescription if callable(desc): desc = desc() self.on_service_error(pyservice, desc) else: if pyservice: self.services[uuid] = pyservice if callable(self.on_service_added): self.on_service_added(pyservice)
def _update(self, new): self.peripheral = new.peripheral # self.uuid = UUID(iprop(self.peripheral.identifier).UUIDString().cString()) self.uuid = cbuuid_to_uuid(self.peripheral.identifier) self.name = iprop(self.peripheral.name).cString() super(BleDevice, self)._update(new)
def peripheralManagerDidUpdateState_(self, peripheral): self.state = iprop(peripheral.state) if callable(self.on_state): self.on_state(self.state_description)
def disconnect(self): if self.connecting: print("connecting state", iprop(self.connecting.peripheral.state)) self.connecting.disconnect() if self.connected: self.connected.disconnect()
def __init__(self, uuid, service, characteristic): properties = iprop(characteristic.properties) super(BleCharacteristic, self).__init__(uuid, service, properties) self.characteristic = characteristic self.on_read = None
def cbuuid_to_uuid(cbuuid): uuid_string = iprop(iprop(cbuuid).UUIDString).cString() if len(uuid_string) == 4: uuid_string = '0000' + uuid_string + '-0000-1000-8000-00805F9B34FB' return UUID(uuid_string)