static void gatt_ccc_write_cb(struct gatt_db_attribute *attrib,
					unsigned int id, uint16_t offset,
					const uint8_t *value, size_t len,
					uint8_t opcode, struct bt_att *att,
					void *user_data)
{
	struct btd_gatt_database *database = user_data;
	struct ccc_state *ccc;
	struct ccc_cb_data *ccc_cb;
	uint16_t handle, val;
	uint8_t ecode = 0;

	handle = gatt_db_attribute_get_handle(attrib);

	DBG("CCC write called for handle: 0x%04x", handle);

	if (!value || len > 2) {
		ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
		goto done;
	}

	if (offset > 2) {
		ecode = BT_ATT_ERROR_INVALID_OFFSET;
		goto done;
	}

	ccc = get_ccc_state(database, att, handle);
	if (!ccc) {
		ecode = BT_ATT_ERROR_UNLIKELY;
		goto done;
	}

	ccc_cb = queue_find(database->ccc_callbacks, ccc_cb_match_handle,
			UINT_TO_PTR(gatt_db_attribute_get_handle(attrib)));
	if (!ccc_cb) {
		ecode = BT_ATT_ERROR_UNLIKELY;
		goto done;
	}

	if (len == 1)
		val = *value;
	else
		val = get_le16(value);

	/* If value is identical, then just succeed */
	if (val == ccc->value)
		goto done;

	if (ccc_cb->callback) {
		struct pending_op *op;

		op = pending_ccc_new(att, attrib, val,
					bt_att_get_link_type(att));
		if (!op) {
			ecode = BT_ATT_ERROR_UNLIKELY;
			goto done;
		}

		ecode = ccc_cb->callback(op, ccc_cb->user_data);
		if (ecode)
			pending_op_free(op);
	}

	if (!ecode)
		ccc->value = val;

done:
	gatt_db_attribute_write_result(attrib, id, ecode);
}
static void gatt_ccc_write_cb(struct gatt_db_attribute *attrib,
					unsigned int id, uint16_t offset,
					const uint8_t *value, size_t len,
					uint8_t opcode, struct bt_att *att,
					void *user_data)
{
	struct btd_gatt_database *database = user_data;
	struct ccc_state *ccc;
	struct ccc_cb_data *ccc_cb;
	uint16_t handle, val;
	uint8_t ecode = 0;

	handle = gatt_db_attribute_get_handle(attrib);

	DBG("CCC write called for handle: 0x%04x", handle);

	if (!value || len > 2) {
		ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
		goto done;
	}

	if (offset > 2) {
		ecode = BT_ATT_ERROR_INVALID_OFFSET;
		goto done;
	}

	ccc = get_ccc_state(database, att, handle);
	if (!ccc) {
		ecode = BT_ATT_ERROR_UNLIKELY;
		goto done;
	}

	ccc_cb = queue_find(database->ccc_callbacks, ccc_cb_match_handle,
			UINT_TO_PTR(gatt_db_attribute_get_handle(attrib)));
	if (!ccc_cb) {
		ecode = BT_ATT_ERROR_UNLIKELY;
		goto done;
	}

	if (len == 1)
		val = *value;
	else
		val = get_le16(value);

	 
	if (val == ccc->value)
		goto done;

	if (ccc_cb->callback) {
		struct pending_op *op;

		op = pending_ccc_new(att, attrib, val,
					bt_att_get_link_type(att));
		if (!op) {
			ecode = BT_ATT_ERROR_UNLIKELY;
			goto done;
		}

		ecode = ccc_cb->callback(op, ccc_cb->user_data);
		if (ecode)
			pending_op_free(op);
	}

	if (!ecode)
		ccc->value = val;

done:
	gatt_db_attribute_write_result(attrib, id, ecode);
}