Java Code Examples for android.bluetooth.BluetoothGattCharacteristic#PROPERTY_WRITE_NO_RESPONSE

The following examples show how to use android.bluetooth.BluetoothGattCharacteristic#PROPERTY_WRITE_NO_RESPONSE . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MainActivity.java    From easyble-x with Apache License 2.0 6 votes vote down vote up
private String getPropertiesString(Item node) {
    StringBuilder sb = new StringBuilder();
    int[] properties = new int[]{BluetoothGattCharacteristic.PROPERTY_WRITE, BluetoothGattCharacteristic.PROPERTY_INDICATE,
            BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PROPERTY_READ,
            BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE, BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE};
    String[] propertyStrs = new String[]{"WRITE", "INDICATE", "NOTIFY", "READ", "SIGNED_WRITE", "WRITE_NO_RESPONSE"};
    for (int i = 0; i < properties.length; i++) {
        int property = properties[i];
        if ((node.characteristic.getProperties() & property) != 0) {
            if (sb.length() != 0) {
                sb.append(", ");
            }
            sb.append(propertyStrs[i]);
            if (property == BluetoothGattCharacteristic.PROPERTY_NOTIFY || property == BluetoothGattCharacteristic.PROPERTY_INDICATE) {
                node.hasNotifyProperty = true;
            }
            if (property == BluetoothGattCharacteristic.PROPERTY_WRITE || property == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) {
                node.hasWriteProperty = true;
            }
            if (property == BluetoothGattCharacteristic.PROPERTY_READ) {
                node.hasReadProperty = true;
            }
        }
    }
    return sb.toString();
}
 
Example 2
Source File: P_DeviceServiceManager.java    From AsteroidOSSync with GNU General Public License v3.0 6 votes vote down vote up
private static int getProperty(BleDevice.ReadWriteListener.Type type)
{
	switch(type)
	{
		case READ:
		case POLL:
		case PSUEDO_NOTIFICATION:	return		BluetoothGattCharacteristic.PROPERTY_READ;
		
           case WRITE_NO_RESPONSE:     return      BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
           case WRITE_SIGNED:          return      BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE;
           case WRITE:					return		BluetoothGattCharacteristic.PROPERTY_WRITE;
   
		case ENABLING_NOTIFICATION:
		case DISABLING_NOTIFICATION:
		case NOTIFICATION:
		case INDICATION:			return		BluetoothGattCharacteristic.PROPERTY_INDICATE			|
												BluetoothGattCharacteristic.PROPERTY_NOTIFY				;
	}
	
	return 0x0;
}
 
Example 3
Source File: McuMgrBleTransport.java    From mcumgr-android with Apache License 2.0 6 votes vote down vote up
@Override
protected boolean isRequiredServiceSupported(@NonNull BluetoothGatt gatt) {
    mSmpService = gatt.getService(SMP_SERVICE_UUID);
    if (mSmpService == null) {
        LOG.error("Device does not support SMP service");
        return false;
    }
    mSmpCharacteristic = mSmpService.getCharacteristic(SMP_CHAR_UUID);
    if (mSmpCharacteristic == null) {
        LOG.error("Device does not support SMP characteristic");
        return false;
    } else {
        final int rxProperties = mSmpCharacteristic.getProperties();
        boolean write = (rxProperties &
                BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0;
        boolean notify = (rxProperties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0;
        if (!write || !notify) {
            LOG.error("SMP characteristic does not support either write ({}) or notify ({})", write, notify);
            return false;
        }
    }
    return true;
}
 
Example 4
Source File: DeviceControlActivity.java    From AndroidBleManager with Apache License 2.0 6 votes vote down vote up
/**
 * get property,http://blog.csdn.net/chenxh515/article/details/45723299
 * @param property
 * @return
 */
private String getPropertyString(int property){
    StringBuilder sb = new StringBuilder("(");
    //Read
    if ((property & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
        sb.append("Read ");
    }
    //Write
    if ((property & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0
            || (property & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
        sb.append("Write ");
    }
    //Notify
    if ((property & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0
            || (property & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
        sb.append("Notity Indicate ");
    }
    //Broadcast
    if ((property & BluetoothGattCharacteristic.PROPERTY_BROADCAST) > 0){
        sb.append("Broadcast ");
    }
    sb.deleteCharAt(sb.length() - 1);
    sb.append(")");
    return sb.toString();
}
 
Example 5
Source File: SerialSocket.java    From SimpleBluetoothLeTerminal with MIT License 5 votes vote down vote up
private void connectCharacteristics3(BluetoothGatt gatt) {
    int writeProperties = writeCharacteristic.getProperties();
    if((writeProperties & (BluetoothGattCharacteristic.PROPERTY_WRITE +     // Microbit,HM10-clone have WRITE
            BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) ==0) { // HM10,TI uart,Telit have only WRITE_NO_RESPONSE
        onSerialConnectError(new IOException("write characteristic not writable"));
        return;
    }
    if(!gatt.setCharacteristicNotification(readCharacteristic,true)) {
        onSerialConnectError(new IOException("no notification for read characteristic"));
        return;
    }
    BluetoothGattDescriptor readDescriptor = readCharacteristic.getDescriptor(BLUETOOTH_LE_CCCD);
    if(readDescriptor == null) {
        onSerialConnectError(new IOException("no CCCD descriptor for read characteristic"));
        return;
    }
    int readProperties = readCharacteristic.getProperties();
    if((readProperties & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
        Log.d(TAG, "enable read indication");
        readDescriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
    }else if((readProperties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
        Log.d(TAG, "enable read notification");
        readDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    } else {
        onSerialConnectError(new IOException("no indication/notification for read characteristic ("+readProperties+")"));
        return;
    }
    Log.d(TAG,"writing read characteristic descriptor");
    if(!gatt.writeDescriptor(readDescriptor)) {
        onSerialConnectError(new IOException("read characteristic CCCD descriptor not writable"));
    }
    // continues asynchronously in onDescriptorWrite()
}
 
Example 6
Source File: BleGattCallback.java    From attach with GNU General Public License v3.0 5 votes vote down vote up
private String getProperties(int bitmask) {
    String properties = "";

    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_BROADCAST) != 0) {
        properties += "broadcast, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) != 0) {
        properties += "extended props, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
        properties += "indicate, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
        properties += "notify, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_READ) != 0) {
        properties += "read, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) != 0) {
        properties += "signed write, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0) {
        properties += "write, ";
    }
    if ((bitmask & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) {
        properties += "write no response, ";
    }

    return properties.isEmpty() ? "" : properties.substring(0, properties.length() - 2);
}
 
Example 7
Source File: BleManager.java    From Android-nRF-Toolbox with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private boolean internalWriteCharacteristic(final BluetoothGattCharacteristic characteristic) {
	final BluetoothGatt gatt = bluetoothGatt;
	if (gatt == null || characteristic == null)
		return false;

	// Check characteristic property
	final int properties = characteristic.getProperties();
	if ((properties & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) == 0)
		return false;

	return gatt.writeCharacteristic(characteristic);
}
 
Example 8
Source File: BleConnector.java    From FastBle with Apache License 2.0 5 votes vote down vote up
/**
 * write
 */
public void writeCharacteristic(byte[] data, BleWriteCallback bleWriteCallback, String uuid_write) {
    if (data == null || data.length <= 0) {
        if (bleWriteCallback != null)
            bleWriteCallback.onWriteFailure(new OtherException("the data to be written is empty"));
        return;
    }

    if (mCharacteristic == null
            || (mCharacteristic.getProperties() & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) == 0) {
        if (bleWriteCallback != null)
            bleWriteCallback.onWriteFailure(new OtherException("this characteristic not support write!"));
        return;
    }

    if (mCharacteristic.setValue(data)) {
        handleCharacteristicWriteCallback(bleWriteCallback, uuid_write);
        if (!mBluetoothGatt.writeCharacteristic(mCharacteristic)) {
            writeMsgInit();
            if (bleWriteCallback != null)
                bleWriteCallback.onWriteFailure(new OtherException("gatt writeCharacteristic fail"));
        }
    } else {
        if (bleWriteCallback != null)
            bleWriteCallback.onWriteFailure(new OtherException("Updates the locally stored value of this characteristic fail"));
    }
}
 
Example 9
Source File: UARTManager.java    From Android-nRF-Toolbox with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
@Override
public boolean isRequiredServiceSupported(@NonNull final BluetoothGatt gatt) {
	final BluetoothGattService service = gatt.getService(UART_SERVICE_UUID);
	if (service != null) {
		rxCharacteristic = service.getCharacteristic(UART_RX_CHARACTERISTIC_UUID);
		txCharacteristic = service.getCharacteristic(UART_TX_CHARACTERISTIC_UUID);
	}

	boolean writeRequest = false;
	boolean writeCommand = false;
	if (rxCharacteristic != null) {
		final int rxProperties = rxCharacteristic.getProperties();
		writeRequest = (rxProperties & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0;
		writeCommand = (rxProperties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0;

		// Set the WRITE REQUEST type when the characteristic supports it.
		// This will allow to send long write (also if the characteristic support it).
		// In case there is no WRITE REQUEST property, this manager will divide texts
		// longer then MTU-3 bytes into up to MTU-3 bytes chunks.
		if (writeRequest)
			rxCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
		else
			useLongWrite = false;
	}

	return rxCharacteristic != null && txCharacteristic != null && (writeRequest || writeCommand);
}
 
Example 10
Source File: BluetoothUtils.java    From AndroidBleManager with Apache License 2.0 5 votes vote down vote up
public static boolean isCharacteristicWrite(int property){
    if ((property & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0
            || (property & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
        return true;
    }
    return false;
}
 
Example 11
Source File: CharacteristicDetailsActivity.java    From BLEService with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public static String getCharacteristicPropertiesString(int props) {
 String propertiesString = String.format("0x%04X [", props);
 if((props & BluetoothGattCharacteristic.PROPERTY_READ) != 0) propertiesString += "read ";
 if((props & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0) propertiesString += "write ";
 if((props & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) propertiesString += "notify ";
 if((props & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) propertiesString += "indicate ";
 if((props & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) propertiesString += "write_no_response ";
 propertiesString += "]";
 return propertiesString;

}
 
Example 12
Source File: BluetoothDebug.java    From openScale with GNU General Public License v3.0 5 votes vote down vote up
private boolean isWriteType(int property, int writeType) {
    switch (property) {
        case BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE:
            return writeType == BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE;
        case BluetoothGattCharacteristic.PROPERTY_WRITE:
            return writeType == BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT;
        case BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE:
            return writeType == BluetoothGattCharacteristic.WRITE_TYPE_SIGNED;
    }
    return false;
}
 
Example 13
Source File: Helper.java    From react-native-ble-manager with Apache License 2.0 4 votes vote down vote up
public static WritableMap decodeProperties(BluetoothGattCharacteristic characteristic) {

		// NOTE: props strings need to be consistent across iOS and Android
		WritableMap props = Arguments.createMap();
		int properties = characteristic.getProperties();

		if ((properties & BluetoothGattCharacteristic.PROPERTY_BROADCAST) != 0x0 ) {
			props.putString("Broadcast", "Broadcast");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) != 0x0 ) {
			props.putString("Read", "Read");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0x0 ) {
			props.putString("WriteWithoutResponse", "WriteWithoutResponse");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0x0 ) {
			props.putString("Write", "Write");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0x0 ) {
			props.putString("Notify", "Notify");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0x0 ) {
			props.putString("Indicate", "Indicate");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) != 0x0 ) {
			// Android calls this "write with signature", using iOS name for now
			props.putString("AuthenticateSignedWrites", "AuthenticateSignedWrites");
		}

		if ((properties & BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) != 0x0 ) {
			props.putString("ExtendedProperties", "ExtendedProperties");
		}

//      iOS only?
//
//            if ((p & CBCharacteristicPropertyNotifyEncryptionRequired) != 0x0) {  // 0x100
//                [props addObject:@"NotifyEncryptionRequired"];
//            }
//
//            if ((p & CBCharacteristicPropertyIndicateEncryptionRequired) != 0x0) { // 0x200
//                [props addObject:@"IndicateEncryptionRequired"];
//            }

		return props;
	}
 
Example 14
Source File: P_DeviceServiceManager.java    From AsteroidOSSync with GNU General Public License v3.0 4 votes vote down vote up
static BleDevice.ReadWriteListener.Type modifyResultType(BleCharacteristicWrapper char_native, BleDevice.ReadWriteListener.Type type)
{
	if( !char_native.isNull())
	{
		if( type == Type.NOTIFICATION )
		{
			if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0x0 )
			{
				if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0x0 )
				{
					type = Type.INDICATION;
				}
			}
		}
		else if( type == Type.WRITE )
		{
			if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0x0 )
			{
				if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0x0 )
				{
					type = Type.WRITE_NO_RESPONSE;
				}
				else if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) != 0x0 )
				{
					type = Type.WRITE_SIGNED;
				}
			}
			//--- RB > Check the write type on the characteristic, in case this char has multiple write types
			int writeType = char_native.getCharacteristic().getWriteType();
			if (writeType == BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
			{
				type = Type.WRITE_NO_RESPONSE;
			}
			else if (writeType == BluetoothGattCharacteristic.WRITE_TYPE_SIGNED)
			{
				type = Type.WRITE_SIGNED;
			}
		}
	}
	
	return type;
}
 
Example 15
Source File: P_DeviceServiceManager.java    From SweetBlue with GNU General Public License v3.0 4 votes vote down vote up
static BleDevice.ReadWriteListener.Type modifyResultType(BleCharacteristicWrapper char_native, BleDevice.ReadWriteListener.Type type)
{
	if( !char_native.isNull())
	{
		if( type == Type.NOTIFICATION )
		{
			if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0x0 )
			{
				if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0x0 )
				{
					type = Type.INDICATION;
				}
			}
		}
		else if( type == Type.WRITE )
		{
			if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0x0 )
			{
				if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0x0 )
				{
					type = Type.WRITE_NO_RESPONSE;
				}
				else if( (char_native.getCharacteristic().getProperties() & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) != 0x0 )
				{
					type = Type.WRITE_SIGNED;
				}
			}
			//--- RB > Check the write type on the characteristic, in case this char has multiple write types
			int writeType = char_native.getCharacteristic().getWriteType();
			if (writeType == BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
			{
				type = Type.WRITE_NO_RESPONSE;
			}
			else if (writeType == BluetoothGattCharacteristic.WRITE_TYPE_SIGNED)
			{
				type = Type.WRITE_SIGNED;
			}
		}
	}
	
	return type;
}
 
Example 16
Source File: BLEUtils.java    From android with MIT License 4 votes vote down vote up
/**
 * @return Returns <b>true</b> if property is writable
 */
public static boolean isCharacteristicWriteable(BluetoothGattCharacteristic pChar) {
    return (pChar.getProperties() & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) != 0;
}
 
Example 17
Source File: CharacteristicListFragment.java    From FastBle with Apache License 2.0 4 votes vote down vote up
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView != null) {
        holder = (ViewHolder) convertView.getTag();
    } else {
        convertView = View.inflate(context, R.layout.adapter_service, null);
        holder = new ViewHolder();
        convertView.setTag(holder);
        holder.txt_title = (TextView) convertView.findViewById(R.id.txt_title);
        holder.txt_uuid = (TextView) convertView.findViewById(R.id.txt_uuid);
        holder.txt_type = (TextView) convertView.findViewById(R.id.txt_type);
        holder.img_next = (ImageView) convertView.findViewById(R.id.img_next);
    }

    BluetoothGattCharacteristic characteristic = characteristicList.get(position);
    String uuid = characteristic.getUuid().toString();

    holder.txt_title.setText(String.valueOf(getActivity().getString(R.string.characteristic) + "(" + position + ")"));
    holder.txt_uuid.setText(uuid);

    StringBuilder property = new StringBuilder();
    int charaProp = characteristic.getProperties();
    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
        property.append("Read");
        property.append(" , ");
    }
    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
        property.append("Write");
        property.append(" , ");
    }
    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) {
        property.append("Write No Response");
        property.append(" , ");
    }
    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
        property.append("Notify");
        property.append(" , ");
    }
    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
        property.append("Indicate");
        property.append(" , ");
    }
    if (property.length() > 1) {
        property.delete(property.length() - 2, property.length() - 1);
    }
    if (property.length() > 0) {
        holder.txt_type.setText(String.valueOf(getActivity().getString(R.string.characteristic) + "( " + property.toString() + ")"));
        holder.img_next.setVisibility(View.VISIBLE);
    } else {
        holder.img_next.setVisibility(View.INVISIBLE);
    }

    return convertView;
}
 
Example 18
Source File: GattDatabase.java    From SweetBlue with GNU General Public License v3.0 4 votes vote down vote up
public final Properties write_no_response()
{
    m_properties |= BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
    return this;
}
 
Example 19
Source File: BleConnectWorker.java    From Android-BluetoothKit with Apache License 2.0 4 votes vote down vote up
private boolean isCharacteristicNoRspWritable(BluetoothGattCharacteristic characteristic) {
    return characteristic != null && (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0;
}
 
Example 20
Source File: GattPlugin.java    From bitgatt with Mozilla Public License 2.0 4 votes vote down vote up
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
String getStringRepresentationOfPropertiesForCharacteristic(BluetoothGattCharacteristic characteristic) {
    StringBuilder propertyBuilder = new StringBuilder();
    ArrayList<Integer> properties = new ArrayList<>(8);
    int characteristicProperties = characteristic.getProperties();
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_READ) == BluetoothGattCharacteristic.PROPERTY_READ) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_READ);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_WRITE) == BluetoothGattCharacteristic.PROPERTY_WRITE) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_WRITE);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_BROADCAST) == BluetoothGattCharacteristic.PROPERTY_BROADCAST) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_BROADCAST);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) == BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == BluetoothGattCharacteristic.PROPERTY_INDICATE) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_INDICATE);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == BluetoothGattCharacteristic.PROPERTY_NOTIFY) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_NOTIFY);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) == BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE);
    }
    if ((characteristicProperties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) {
        properties.add(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE);
    }
    for (int i = 0; i < properties.size(); i++) {
        int property = properties.get(i);
        switch (property) {
            case BluetoothGattCharacteristic.PROPERTY_READ:
                propertyBuilder.append("read");
                break;
            case BluetoothGattCharacteristic.PROPERTY_WRITE:
                propertyBuilder.append("write");
                break;
            case BluetoothGattCharacteristic.PROPERTY_BROADCAST:
                propertyBuilder.append("broadcast");
                break;
            case BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS:
                propertyBuilder.append("extended-props");
                break;
            case BluetoothGattCharacteristic.PROPERTY_NOTIFY:
                propertyBuilder.append("notify");
                break;
            case BluetoothGattCharacteristic.PROPERTY_INDICATE:
                propertyBuilder.append("indicate");
                break;
            case BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE:
                propertyBuilder.append("write-signed");
                break;
            case BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE:
                propertyBuilder.append("write-no-response");
                break;
            default:
                propertyBuilder.append("unknown");
        }
        if (i < properties.size() - 1) {
            propertyBuilder.append(", ");
        }
    }
    return propertyBuilder.toString();
}