Feature/color objects color command (#302)

* added BACnetColorCommand and BACnetxyColor encoding and unit testing

* Added Color object and unit testing.

* Added Color Temperature object and Unit test

* Fix BVLC unit test warning.

* add port Makefile for extra types

* added RGB to and from CIE xy utility in sys folder, and add unit tests.

* added cmake-win32 target

* Change RP and RPM to use known property decoder.

Add color object RP and RPM decoding and printing
Fix RPM print for new reserved range above 4194303
Change default protocol-revision to 24 for Color object

* Integrate Color and Color Temperature objects into demo apps

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2022-07-13 09:54:36 -05:00
committed by GitHub
parent 085de3c385
commit 38d213b47c
80 changed files with 5369 additions and 347 deletions
+724 -35
View File
@@ -1,36 +1,14 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
/**
* @file
* @brief API for BACnetLightingCommand and BACnetColorCommand
* @author Steve Karg <skarg@users.sourceforge.net>
* @date June 2022
* @section LICENSE
*
* Copyright (C) 2022 Steve Karg <skarg@users.sourceforge.net>
*
* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
@@ -38,11 +16,12 @@
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "bacnet/lighting.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacreal.h"
#include "bacnet/lighting.h"
#ifndef islessgreater
#define islessgreater( x, y) ((x) < (y) || (x) > (y))
#define islessgreater(x, y) ((x) < (y) || (x) > (y))
#endif
/** @file lighting.c Manipulate BACnet lighting command values */
@@ -313,3 +292,713 @@ bool lighting_command_same(
return status;
}
/**
* @brief Encode a BACnetxyColor complex data type
*
* BACnetxyColor::= SEQUENCE {
* x-coordinate REAL, --(0.0 to 1.0)
* y-coordinate REAL --(0.0 to 1.0)
* }
* @param apdu - the APDU buffer, or NULL for length
* @param value - BACnetxyColor structure
* @return length of the encoded APDU buffer
*/
int xy_color_encode(uint8_t *apdu, BACNET_XY_COLOR *value)
{
int len = 0;
int apdu_len = 0;
uint8_t *apdu_offset = NULL;
if (value) {
/* x-coordinate REAL */
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_bacnet_real(value->x_coordinate, apdu_offset);
apdu_len += len;
/* y-coordinate REAL */
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_bacnet_real(value->y_coordinate, apdu_offset);
apdu_len += len;
}
return apdu_len;
}
/**
* @brief Encode a context tagged BACnetxyColor complex data type
* @param apdu - the APDU buffer
* @param tag_number - the APDU buffer size
* @param value - BACnetxyColor structure
* @return length of the APDU buffer, or 0 if not able to encode
*/
int xy_color_context_encode(
uint8_t *apdu, uint8_t tag_number, BACNET_XY_COLOR *value)
{
int len = 0;
int apdu_len = 0;
uint8_t *apdu_offset = NULL;
if (value) {
apdu_offset = apdu;
len = encode_opening_tag(apdu_offset, tag_number);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = xy_color_encode(apdu_offset, value);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_closing_tag(apdu_offset, tag_number);
apdu_len += len;
}
return apdu_len;
}
/**
* @brief Decode the BACnetxyColor complex data type Value
*
* @param apdu - buffer of data to be decoded
* @param apdu_size - the size of the data buffer
* @param value - decoded BACnetxyColor, if decoded
*
* @return the number of apdu bytes consumed
*/
int xy_color_decode(uint8_t *apdu, uint32_t apdu_size, BACNET_XY_COLOR *value)
{
float real_value;
int len = 0;
int apdu_len = 0;
if (apdu && value && (apdu_size >= 8)) {
/* each REAL is encoded in 4 octets */
len = decode_real(&apdu[0], &real_value);
if (len == 4) {
if (value) {
value->x_coordinate = real_value;
}
apdu_len += len;
}
len = decode_real(&apdu[4], &real_value);
if (len == 4) {
if (value) {
value->y_coordinate = real_value;
}
apdu_len += len;
}
}
return apdu_len;
}
/**
* @brief Decode the BACnetxyColor complex data type Value
*
* @param apdu - buffer of data to be decoded
* @param apdu_size - the size of the data buffer
* @param value - decoded BACnetxyColor, if decoded
*
* @return the number of apdu bytes consumed
*/
int xy_color_context_decode(uint8_t *apdu,
uint32_t apdu_size,
uint8_t tag_number,
BACNET_XY_COLOR *value)
{
int len = 0;
int rlen = 0;
int apdu_len = 0;
BACNET_XY_COLOR color = { 0.0, 0.0 };
if (apdu_size > 0) {
if (decode_is_opening_tag_number(&apdu[apdu_len], tag_number)) {
apdu_len += 1;
len =
xy_color_decode(&apdu[apdu_len], apdu_size - apdu_len, &color);
if (len > 0) {
apdu_len += len;
if (value) {
value->x_coordinate = color.x_coordinate;
value->y_coordinate = color.y_coordinate;
}
if ((apdu_size - apdu_len) > 0) {
if (decode_is_closing_tag_number(
&apdu[apdu_len], tag_number)) {
apdu_len += 1;
rlen = apdu_len;
}
}
}
}
}
return rlen;
}
/**
* @brief Copy the BACnetxyColor complex data from src to dst
* @param dst - destination BACNET_XY_COLOR structure
* @param src - source BACNET_XY_COLOR structure
* @return true if successfully copied
*/
int xy_color_copy(BACNET_XY_COLOR *dst, BACNET_XY_COLOR *src)
{
bool status = false;
if (dst && src) {
dst->x_coordinate = src->x_coordinate;
dst->y_coordinate = src->y_coordinate;
status = true;
}
return status;
}
/**
* @brief Compare the BACnetxyColor complex data
* @param value1 - BACNET_XY_COLOR structure
* @param value2 - BACNET_XY_COLOR structure
* @return true if the same
*/
bool xy_color_same(BACNET_XY_COLOR *value1, BACNET_XY_COLOR *value2)
{
bool status = false;
if (value1 && value2) {
if ((value1->x_coordinate == value2->x_coordinate) &&
(value1->y_coordinate == value2->y_coordinate)) {
status = true;
}
}
return status;
}
/**
* @brief Encode a BACnetColorCommand complex data type
*
* BACnetColorCommand structure ::= SEQUENCE {
* operation [0] BACnetColorOperation,
* target-color [1] BACnetxyColor OPTIONAL,
* target-color-temperature [2] Unsigned OPTIONAL,
* fade-time [3] Unsigned (100.. 86400000) OPTIONAL,
* ramp-rate [4] Unsigned (1..30000) OPTIONAL,
* step-increment [5] Unsigned (1..30000) OPTIONAL
* }
*
* @param apdu - the APDU buffer, or NULL for length
* @param value - BACnetColorCommand structure
* @return length of the encoded APDU buffer
*/
int color_command_encode(uint8_t *apdu, BACNET_COLOR_COMMAND *value)
{
int len = 0;
int apdu_len = 0;
uint8_t *apdu_offset = NULL;
BACNET_UNSIGNED_INTEGER unsigned_value;
if (value) {
/* operation [0] BACnetColorOperation */
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_context_enumerated(apdu_offset, 0, value->operation);
apdu_len += len;
switch (value->operation) {
case BACNET_COLOR_OPERATION_NONE:
break;
case BACNET_COLOR_OPERATION_FADE_TO_COLOR:
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
/* target-color [1] BACnetxyColor */
len = xy_color_context_encode(
apdu_offset, 1, &value->target.color);
apdu_len += len;
if ((value->transit.fade_time >= BACNET_COLOR_FADE_TIME_MIN) &&
(value->transit.fade_time <= BACNET_COLOR_FADE_TIME_MAX)) {
/* fade-time [3] Unsigned (100.. 86400000) */
unsigned_value = value->transit.fade_time;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len =
encode_context_unsigned(apdu_offset, 3, unsigned_value);
apdu_len += len;
}
break;
case BACNET_COLOR_OPERATION_FADE_TO_CCT:
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
/* target-color-temperature [2] Unsigned */
unsigned_value = value->target.color_temperature;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_context_unsigned(apdu_offset, 2, unsigned_value);
apdu_len += len;
if ((value->transit.fade_time >= BACNET_COLOR_FADE_TIME_MIN) &&
(value->transit.fade_time <= BACNET_COLOR_FADE_TIME_MAX)) {
/* fade-time [3] Unsigned (100.. 86400000) */
unsigned_value = value->transit.fade_time;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len =
encode_context_unsigned(apdu_offset, 3, unsigned_value);
apdu_len += len;
}
break;
case BACNET_COLOR_OPERATION_RAMP_TO_CCT:
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
/* target-color-temperature [2] Unsigned */
unsigned_value = value->target.color_temperature;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_context_unsigned(apdu_offset, 2, unsigned_value);
apdu_len += len;
if ((value->transit.ramp_rate >= BACNET_COLOR_RAMP_RATE_MIN) &&
(value->transit.ramp_rate <= BACNET_COLOR_RAMP_RATE_MAX)) {
/* ramp-rate [4] Unsigned (1..30000) */
unsigned_value = value->transit.ramp_rate;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len =
encode_context_unsigned(apdu_offset, 4, unsigned_value);
apdu_len += len;
}
break;
case BACNET_COLOR_OPERATION_STEP_UP_CCT:
case BACNET_COLOR_OPERATION_STEP_DOWN_CCT:
if ((value->transit.step_increment >=
BACNET_COLOR_STEP_INCREMENT_MIN) &&
(value->transit.step_increment <=
BACNET_COLOR_STEP_INCREMENT_MAX)) {
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
/* step-increment [5] Unsigned (1..30000) */
unsigned_value = value->transit.step_increment;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len =
encode_context_unsigned(apdu_offset, 5, unsigned_value);
apdu_len += len;
}
break;
case BACNET_COLOR_OPERATION_STOP:
break;
default:
break;
}
}
return apdu_len;
}
/**
* @brief Encode a context tagged BACnetColorCommand complex data type
* @param apdu - the APDU buffer
* @param tag_number - the APDU buffer size
* @param address - IP address and port number
* @return length of the APDU buffer, or 0 if not able to encode
*/
int color_command_context_encode(
uint8_t *apdu, uint8_t tag_number, BACNET_COLOR_COMMAND *value)
{
int len = 0;
int apdu_len = 0;
uint8_t *apdu_offset = NULL;
if (value) {
apdu_offset = apdu;
len = encode_opening_tag(apdu_offset, tag_number);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = color_command_encode(apdu_offset, value);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[apdu_len];
}
len = encode_closing_tag(apdu_offset, tag_number);
apdu_len += len;
}
return apdu_len;
}
/**
* @brief Decode the BACnetColorCommand complex data
*
* BACnetColorCommand ::= SEQUENCE {
* operation [0] BACnetColorOperation,
* target-color [1] BACnetxyColor OPTIONAL,
* target-color-temperature [2] Unsigned OPTIONAL,
* fade-time [3] Unsigned (100.. 86400000) OPTIONAL,
* ramp-rate [4] Unsigned (1..30000) OPTIONAL,
* step-increment [5] Unsigned (1..30000) OPTIONAL
* }
*
* @param apdu - the APDU buffer
* @param apdu_len - the APDU buffer length
* @param value - BACnetColorCommand structure values
* @return length of the APDU buffer decoded, or ERROR, REJECT, or ABORT
*/
int color_command_decode(uint8_t *apdu,
uint16_t apdu_size,
BACNET_ERROR_CODE *error_code,
BACNET_COLOR_COMMAND *value)
{
int len = 0;
int apdu_len = 0;
BACNET_UNSIGNED_INTEGER unsigned_value = 0;
BACNET_COLOR_OPERATION operation = BACNET_COLOR_OPERATION_NONE;
BACNET_XY_COLOR color;
/* default reject code */
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
/* check for value pointers */
if ((apdu_size == 0) || (!apdu)) {
return BACNET_STATUS_REJECT;
}
/* operation [0] BACnetColorOperation */
len = bacnet_unsigned_context_decode(
apdu, apdu_size - apdu_len, 0, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if (unsigned_value >= BACNET_COLOR_OPERATION_MAX) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
operation = (BACNET_COLOR_OPERATION)unsigned_value;
if (value) {
value->operation = operation;
}
switch (operation) {
case BACNET_COLOR_OPERATION_NONE:
break;
case BACNET_COLOR_OPERATION_FADE_TO_COLOR:
/* target-color [1] BACnetxyColor */
if ((apdu_size - apdu_len) == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
return BACNET_STATUS_REJECT;
}
len = xy_color_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 1, &color);
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if (value) {
value->target.color.x_coordinate = color.x_coordinate;
value->target.color.y_coordinate = color.y_coordinate;
}
if ((apdu_size - apdu_len) != 0) {
/* fade-time [3] Unsigned (100.. 86400000) OPTIONAL */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 3, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code =
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if ((unsigned_value < BACNET_COLOR_FADE_TIME_MIN) ||
(unsigned_value > BACNET_COLOR_FADE_TIME_MAX)) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
if (value) {
value->transit.fade_time = unsigned_value;
}
}
break;
case BACNET_COLOR_OPERATION_FADE_TO_CCT:
/* target-color-temperature [2] Unsigned */
if ((apdu_size - apdu_len) == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
return BACNET_STATUS_REJECT;
}
len = bacnet_unsigned_context_decode(
apdu, apdu_size - apdu_len, 2, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code =
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if (unsigned_value > UINT16_MAX) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
if (value) {
value->target.color_temperature = unsigned_value;
}
if ((apdu_size - apdu_len) != 0) {
/* fade-time [3] Unsigned (100.. 86400000) OPTIONAL */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 3, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code =
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if ((unsigned_value < BACNET_COLOR_FADE_TIME_MIN) ||
(unsigned_value > BACNET_COLOR_FADE_TIME_MAX)) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
if (value) {
value->transit.fade_time = unsigned_value;
}
}
break;
case BACNET_COLOR_OPERATION_RAMP_TO_CCT:
/* target-color-temperature [2] Unsigned */
if ((apdu_size - apdu_len) == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
return BACNET_STATUS_REJECT;
}
len = bacnet_unsigned_context_decode(
apdu, apdu_size - apdu_len, 2, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code =
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if (unsigned_value > UINT16_MAX) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
if (value) {
value->target.color_temperature = unsigned_value;
}
if ((apdu_size - apdu_len) != 0) {
/* ramp-rate [4] Unsigned (1..30000) */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 4, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code =
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if ((unsigned_value < BACNET_COLOR_RAMP_RATE_MIN) ||
(unsigned_value > BACNET_COLOR_RAMP_RATE_MAX)) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
if (value) {
value->transit.ramp_rate = unsigned_value;
}
}
break;
case BACNET_COLOR_OPERATION_STEP_UP_CCT:
case BACNET_COLOR_OPERATION_STEP_DOWN_CCT:
/* step-increment [5] Unsigned (1..30000) */
if ((apdu_size - apdu_len) == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
return BACNET_STATUS_REJECT;
}
len = bacnet_unsigned_context_decode(
apdu, apdu_size - apdu_len, 3, &unsigned_value);
if (len <= 0) {
if (len == 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
} else {
if (error_code) {
*error_code =
ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if ((unsigned_value < BACNET_COLOR_STEP_INCREMENT_MIN) ||
(unsigned_value > BACNET_COLOR_STEP_INCREMENT_MAX)) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
if (value) {
value->transit.step_increment = unsigned_value;
}
break;
case BACNET_COLOR_OPERATION_STOP:
break;
default:
break;
}
return apdu_len;
}
/**
* @brief Copy the BACnetColorCommand complex data from src to dst
* @param dst - destination structure
* @param src - source structure
* @return true if successfully copied
*/
bool color_command_copy(BACNET_COLOR_COMMAND *dst, BACNET_COLOR_COMMAND *src)
{
bool status = false;
if (dst && src) {
memcpy(dst, src, sizeof(BACNET_COLOR_COMMAND));
status = true;
}
return status;
}
/**
* @brief Compare the BACnetColorCommand complex data
* @param value1 - BACNET_COLOR_COMMAND structure
* @param value2 - BACNET_COLOR_COMMAND structure
* @return true if the same
*/
bool color_command_same(
BACNET_COLOR_COMMAND *value1, BACNET_COLOR_COMMAND *value2)
{
bool status = false;
if (value1 && value2 && (value1->operation == value2->operation)) {
switch (value1->operation) {
case BACNET_COLOR_OPERATION_NONE:
status = true;
break;
case BACNET_COLOR_OPERATION_FADE_TO_COLOR:
if ((value1->target.color.x_coordinate ==
value2->target.color.x_coordinate) &&
(value1->target.color.y_coordinate ==
value2->target.color.y_coordinate) &&
(value1->transit.fade_time == value2->transit.fade_time)) {
status = true;
}
break;
case BACNET_COLOR_OPERATION_FADE_TO_CCT:
if ((value1->target.color_temperature ==
value2->target.color_temperature) &&
(value1->transit.fade_time == value2->transit.fade_time)) {
status = true;
}
break;
case BACNET_COLOR_OPERATION_RAMP_TO_CCT:
if ((value1->target.color_temperature ==
value2->target.color_temperature) &&
(value1->transit.ramp_rate == value2->transit.ramp_rate)) {
status = true;
}
break;
case BACNET_COLOR_OPERATION_STEP_UP_CCT:
case BACNET_COLOR_OPERATION_STEP_DOWN_CCT:
if (value1->transit.step_increment ==
value2->transit.step_increment) {
status = true;
}
break;
case BACNET_COLOR_OPERATION_STOP:
status = true;
break;
default:
break;
}
}
return status;
}