package com.polidea.rxandroidble2.internal.logger; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import com.polidea.rxandroidble2.LogConstants; import com.polidea.rxandroidble2.RxBleDeviceServices; import com.polidea.rxandroidble2.internal.RxBleLog; import com.polidea.rxandroidble2.internal.util.CharacteristicPropertiesParser; import com.polidea.rxandroidble2.utils.StandardUUIDsParser; import bleshadow.javax.inject.Inject; /** * --------------- ====== Printing peripheral content ====== --------------- * PERIPHERAL ADDRESS: AA-BB-CC-DD-EE-FF * PERIPHERAL NAME: Device name * ------------------------------------------------------------------------- * Primary Service - Weight Scale (ce029566-f9eb-11e7-8c3f-9a214cf093ae) * Instance ID: 1111 * <p> * -> Characteristics: * * Weight Measurement (ce029962-f9eb-11e7-8c3f-9a214cf093ae) * Properties: READ, WRITE, NOTIFY, INDICATE, etc... * -> Descriptors * * Client Characteristic Configuration (ce029bc4-f9eb-11e7-8c3f-9a214cf093ae) * * Characteristic User Description (ce02a344-f9eb-11e7-8c3f-9a214cf093ae) */ public class LoggerUtilBluetoothServices { private final CharacteristicPropertiesParser characteristicPropertiesParser; @Inject LoggerUtilBluetoothServices(CharacteristicPropertiesParser characteristicPropertiesParser) { this.characteristicPropertiesParser = characteristicPropertiesParser; } public void log(RxBleDeviceServices rxBleDeviceServices, BluetoothDevice device) { if (RxBleLog.isAtLeast(LogConstants.VERBOSE)) { RxBleLog.v("Preparing services description"); RxBleLog.v(prepareServicesDescription(rxBleDeviceServices, device)); } } private String prepareServicesDescription(RxBleDeviceServices rxBleDeviceServices, BluetoothDevice device) { StringBuilder descriptionBuilder = new StringBuilder(); appendDeviceHeader(device, descriptionBuilder); for (BluetoothGattService bluetoothGattService : rxBleDeviceServices.getBluetoothGattServices()) { descriptionBuilder.append('\n'); // New line before each service description appendServiceDescription(descriptionBuilder, bluetoothGattService); } descriptionBuilder.append("\n--------------- ====== Finished peripheral content ====== ---------------"); return descriptionBuilder.toString(); } private void appendServiceDescription(StringBuilder descriptionBuilder, BluetoothGattService bluetoothGattService) { appendServiceHeader(descriptionBuilder, bluetoothGattService); descriptionBuilder.append("-> Characteristics:"); for (BluetoothGattCharacteristic characteristic : bluetoothGattService.getCharacteristics()) { appendCharacteristicNameHeader(descriptionBuilder, characteristic); appendCharacteristicProperties(descriptionBuilder, characteristic); appendDescriptors(descriptionBuilder, characteristic); } } private static void appendDescriptors(StringBuilder descriptionBuilder, BluetoothGattCharacteristic characteristic) { if (!characteristic.getDescriptors().isEmpty()) { appendDescriptorsHeader(descriptionBuilder); for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) { appendDescriptorNameHeader(descriptionBuilder, descriptor); } } } private static void appendDescriptorsHeader(StringBuilder descriptionBuilder) { descriptionBuilder .append('\n') .append('\t') .append(" ") .append("-> Descriptors: "); } private static void appendCharacteristicNameHeader(StringBuilder descriptionBuilder, BluetoothGattCharacteristic characteristic) { descriptionBuilder .append('\n') .append('\t').append("* ").append(createCharacteristicName(characteristic)) .append(" (") .append(LoggerUtil.getUuidToLog(characteristic.getUuid())) .append(")"); } private static void appendDescriptorNameHeader(StringBuilder descriptionBuilder, BluetoothGattDescriptor descriptor) { descriptionBuilder .append('\n') .append('\t') .append('\t') .append("* ").append(createDescriptorName(descriptor)) .append(" (") .append(LoggerUtil.getUuidToLog(descriptor.getUuid())) .append(")"); } private static String createDescriptorName(BluetoothGattDescriptor descriptor) { final String descriptorName = StandardUUIDsParser.getDescriptorName(descriptor.getUuid()); return descriptorName == null ? "Unknown descriptor" : descriptorName; } private void appendCharacteristicProperties(StringBuilder descriptionBuilder, BluetoothGattCharacteristic characteristic) { descriptionBuilder .append('\n') .append('\t') .append(" ") .append("Properties: ").append(characteristicPropertiesParser.propertiesIntToString(characteristic.getProperties())); } private static String createCharacteristicName(BluetoothGattCharacteristic characteristic) { final String characteristicName = StandardUUIDsParser.getCharacteristicName(characteristic.getUuid()); return characteristicName == null ? "Unknown characteristic" : characteristicName; } private static void appendDeviceHeader(BluetoothDevice device, StringBuilder descriptionBuilder) { descriptionBuilder .append("--------------- ====== Printing peripheral content ====== ---------------\n") .append(LoggerUtil.commonMacMessage(device.getAddress())).append('\n') .append("PERIPHERAL NAME: ").append(device.getName()).append('\n') .append("-------------------------------------------------------------------------"); } private static void appendServiceHeader(StringBuilder descriptionBuilder, BluetoothGattService bluetoothGattService) { descriptionBuilder .append("\n") .append(createServiceType(bluetoothGattService)) .append(" - ") .append(createServiceName(bluetoothGattService)) .append(" (") .append(LoggerUtil.getUuidToLog(bluetoothGattService.getUuid())) .append(")\n") .append("Instance ID: ").append(bluetoothGattService.getInstanceId()) .append('\n'); } private static String createServiceName(BluetoothGattService bluetoothGattService) { final String serviceName = StandardUUIDsParser.getServiceName(bluetoothGattService.getUuid()); return serviceName == null ? "Unknown service" : serviceName; } private static String createServiceType(BluetoothGattService bluetoothGattService) { if (bluetoothGattService.getType() == BluetoothGattService.SERVICE_TYPE_PRIMARY) { return "Primary Service"; } else { return "Secondary Service"; } } }