visit
In this tutorial I am going to tell you how I hacked Lenovo Carme smart watch using Python3 in less than 100 lines of code and with basic knowledge of BLE (Bluetooth Low Energy). This code has been tested on Ubuntu 18.04. It will not work on Windows. You can find the source code for the same in my Github repository here.
What tools I’ve used?
I used Gatttool for identifying the correct characteristic to communicate with the device.Now the questions was what I want to do and what I need for that. I started with the basic things first and that is battery level. I used nrf connect to find the handle of battery level which is 0x0030 and in response I got “X” and i was like …
I searched little bit and found response of BLE devices. So it was a 1 byte string which is ASCII equivalent of 0x58. So when we unpack the byte value we will get 88 and finally which is battery level data. So lets check the code that I wrote in python below.
def battery_data(self):
self.battery_char = self.readCharacteristic(int(UUIDS.BATTERY_INFO_HND, 16))
self.battery_level = struct.unpack("<B", self.battery_char)[0]
self._log.info(f"Battery Level: {self.battery_level}")
def heart_rate_data(self):
self.hr_countdown = None
try:
service, = [s for s in self.getServices() if s.uuid == self.hrmid]
_ = service.getCharacteristics(forUUID=str(self.hrmmid))
desc = self.getDescriptors(service.hndStart, service.hndEnd)
d, = [d for d in desc if d.uuid == self.cccid]
self.writeCharacteristic(d.handle, b'\x01\x00')
def print_hr(cHandle, data):
self.hr_countdown = time.perf_counter()
self._log.info(data[1])
self.delegate.handleNotification = print_hr
self._log.info("Waiting for Heart Rate notification ...")
while True:
try:
if self.hr_countdown and (time.perf_counter() - self.hr_countdown) >= 3:
self._log.info("HRM completed")
break
else:
self.waitForNotifications(3.)
except KeyboardInterrupt:
self._log.info("HRM operation closed by user")
self.writeCharacteristic(d.handle, b'\x00\x00')
break
except BTLEException as btlE:
self._log.error(f"{btlE}")
class HW25P(Peripheral):
def __init__(self, mac_address, timeout=0.5, isSecure=False, debug=False):
FORMAT = '%(asctime)-15s %(name)s (%(levelname)s) > %(message)s'
logging.basicConfig(format=FORMAT)
log_level = logging.WARNING if not debug else logging.DEBUG
self._log = logging.getLogger(self.__class__.__name__)
self._log.setLevel(log_level)
self._log.info('Connecting to ' + mac_address)
if isSecure:
Peripheral.__init__(self, mac_address)
else:
Peripheral.__init__(self, mac_address)
self.cccid = AssignedNumbers.client_characteristic_configuration
self.hrmid = AssignedNumbers.heart_rate
self.hrmmid = AssignedNumbers.heart_rate_measurement
self._log.info('Connected')
self.timeout = timeout
self.mac_address = mac_address