/*
 * Java
 *
 * Copyright 2018-2024 MicroEJ Corp. All rights reserved.
 * This library is provided in source code for use, modification and test, subject to license terms.
 * Any modification of the source code will break MicroEJ Corp. warranties on the whole library.
 */
package ej.bluetooth.util;

import ej.bluetooth.BluetoothUuid;

/**
 * Provides constants and utility methods related to GATT descriptors.
 */
public class DescriptorHelper {

	/** UUID of the Characteristic User Description descriptor. */
	public static final BluetoothUuid CUD_UUID = new BluetoothUuid(0x2901);

	/** UUID of the Client Characteristic Configuration descriptor. */
	public static final BluetoothUuid CCC_UUID = new BluetoothUuid(0x2902);

	private static final byte CCC_NOTIFICATIONS_FLAG = 0x01;
	private static final byte CCC_INDICATIONS_FLAG = 0x02;

	private DescriptorHelper() {
		// private constructor
	}

	/**
	 * Creates a CCC descriptor value specifying whether or not notifications and indications should be enabled.
	 *
	 * @param notificationsEnabled
	 *            whether notifications should be enabled.
	 * @param indicationsEnabled
	 *            whether indications should be enabled.
	 * @return the CCC descriptor value.
	 */
	public static byte[] createCccValue(boolean notificationsEnabled, boolean indicationsEnabled) {
		int flags = 0;
		if (notificationsEnabled) {
			flags |= CCC_NOTIFICATIONS_FLAG;
		}
		if (indicationsEnabled) {
			flags |= CCC_INDICATIONS_FLAG;
		}
		return new byte[] { (byte) flags, 0x00 };
	}

	/**
	 * Returns whether notifications are enabled in the given CCC descriptor value.
	 *
	 * @param value
	 *            the value of the CCC descriptor.
	 * @return true if notifications are enabled, false otherwise.
	 */
	public static boolean checkNotificationsEnabled(byte[] value) {
		return (value.length == 2 && (value[0] & CCC_NOTIFICATIONS_FLAG) != 0);
	}

	/**
	 * Returns whether indications are enabled in the given CCC descriptor value.
	 *
	 * @param value
	 *            the value of the CCC descriptor.
	 * @return true if indications are enabled, false otherwise.
	 */
	public static boolean checkIndicationsEnabled(byte[] value) {
		return (value.length == 2 && (value[0] & CCC_INDICATIONS_FLAG) != 0);
	}
}
