Feature/make pretty apps and ports (#80)
* Added pretty-apps and pretty-ports make targets * pretty-fied apps folder C files * Pretty-fied ports folder C and H files Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
+39
-48
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* Analog Input Objects customize for your use */
|
||||
|
||||
@@ -44,8 +44,7 @@ float Present_Value[MAX_ANALOG_INPUTS];
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need validate that the */
|
||||
/* given instance exists */
|
||||
bool Analog_Input_Valid_Instance(
|
||||
uint32_t object_instance)
|
||||
bool Analog_Input_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_ANALOG_INPUTS)
|
||||
return true;
|
||||
@@ -54,34 +53,29 @@ bool Analog_Input_Valid_Instance(
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
unsigned Analog_Input_Count(
|
||||
void)
|
||||
unsigned Analog_Input_Count(void)
|
||||
{
|
||||
return MAX_ANALOG_INPUTS;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
uint32_t Analog_Input_Index_To_Instance(
|
||||
unsigned index)
|
||||
uint32_t Analog_Input_Index_To_Instance(unsigned index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
unsigned Analog_Input_Instance_To_Index(
|
||||
uint32_t object_instance)
|
||||
unsigned Analog_Input_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
return object_instance;
|
||||
}
|
||||
|
||||
|
||||
char *Analog_Input_Name(
|
||||
uint32_t object_instance)
|
||||
char *Analog_Input_Name(uint32_t object_instance)
|
||||
{
|
||||
static char text_string[5] = "AI-0"; /* okay for single thread */
|
||||
static char text_string[5] = "AI-0"; /* okay for single thread */
|
||||
|
||||
if (object_instance < MAX_ANALOG_INPUTS) {
|
||||
text_string[3] = '0' + (uint8_t) object_instance;
|
||||
text_string[3] = '0' + (uint8_t)object_instance;
|
||||
return text_string;
|
||||
}
|
||||
|
||||
@@ -90,34 +84,31 @@ char *Analog_Input_Name(
|
||||
|
||||
/* return apdu length, or -1 on error */
|
||||
/* assumption - object has already exists */
|
||||
int Analog_Input_Encode_Property_APDU(
|
||||
uint8_t * apdu,
|
||||
int Analog_Input_Encode_Property_APDU(uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
int apdu_len = 0; /* return value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
unsigned object_index;
|
||||
|
||||
|
||||
(void) array_index;
|
||||
(void)array_index;
|
||||
switch (property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
|
||||
object_instance);
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], OBJECT_ANALOG_INPUT, object_instance);
|
||||
break;
|
||||
/* note: Name and Description don't have to be the same.
|
||||
You could make Description writable and different.
|
||||
Note that Object-Name must be unique in this device */
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Analog_Input_Name(object_instance));
|
||||
characterstring_init_ansi(
|
||||
&char_string, Analog_Input_Name(object_instance));
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
+14
-16
@@ -41,8 +41,7 @@
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
bool apdu_service_supported(
|
||||
BACNET_SERVICES_SUPPORTED service_supported)
|
||||
bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
@@ -61,15 +60,14 @@ bool apdu_service_supported(
|
||||
return status;
|
||||
}
|
||||
|
||||
uint16_t apdu_decode_confirmed_service_request(
|
||||
uint8_t * apdu, /* APDU data */
|
||||
uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
|
||||
uint16_t apdu_len,
|
||||
BACNET_CONFIRMED_SERVICE_DATA * service_data,
|
||||
uint8_t * service_choice,
|
||||
uint8_t ** service_request,
|
||||
uint16_t * service_request_len)
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data,
|
||||
uint8_t *service_choice,
|
||||
uint8_t **service_request,
|
||||
uint16_t *service_request_len)
|
||||
{
|
||||
uint16_t len = 0; /* counts where we are in PDU */
|
||||
uint16_t len = 0; /* counts where we are in PDU */
|
||||
|
||||
service_data->segmented_message = (apdu[0] & BIT(3)) ? true : false;
|
||||
service_data->more_follows = (apdu[0] & BIT(2)) ? true : false;
|
||||
@@ -90,22 +88,22 @@ uint16_t apdu_decode_confirmed_service_request(
|
||||
return len;
|
||||
}
|
||||
|
||||
void apdu_handler(
|
||||
BACNET_ADDRESS * src,
|
||||
uint8_t * apdu, /* APDU data */
|
||||
void apdu_handler(BACNET_ADDRESS *src,
|
||||
uint8_t *apdu, /* APDU data */
|
||||
uint16_t apdu_len)
|
||||
{
|
||||
BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 };
|
||||
uint8_t service_choice = 0;
|
||||
uint8_t *service_request = NULL;
|
||||
uint16_t service_request_len = 0;
|
||||
uint16_t len = 0; /* counts where we are in PDU */
|
||||
uint16_t len = 0; /* counts where we are in PDU */
|
||||
|
||||
if (apdu) {
|
||||
/* PDU Type */
|
||||
switch (apdu[0] & 0xF0) {
|
||||
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
|
||||
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */
|
||||
len = apdu_decode_confirmed_service_request(
|
||||
&apdu[0], /* APDU data */
|
||||
apdu_len, &service_data, &service_choice, &service_request,
|
||||
&service_request_len);
|
||||
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
|
||||
@@ -114,8 +112,8 @@ void apdu_handler(
|
||||
}
|
||||
#ifdef WRITE_PROPERTY
|
||||
else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
|
||||
handler_write_property(service_request,
|
||||
service_request_len, src, &service_data);
|
||||
handler_write_property(service_request, service_request_len,
|
||||
src, &service_data);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
|
||||
+50
-65
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* Analog Value Objects - customize for your use */
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
|
||||
@@ -49,8 +49,7 @@ float AV_Present_Value[MAX_ANALOG_VALUES];
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need validate that the */
|
||||
/* given instance exists */
|
||||
bool Analog_Value_Valid_Instance(
|
||||
uint32_t object_instance)
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_ANALOG_VALUES)
|
||||
return true;
|
||||
@@ -60,8 +59,7 @@ bool Analog_Value_Valid_Instance(
|
||||
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then count how many you have */
|
||||
unsigned Analog_Value_Count(
|
||||
void)
|
||||
unsigned Analog_Value_Count(void)
|
||||
{
|
||||
return MAX_ANALOG_VALUES;
|
||||
}
|
||||
@@ -69,8 +67,7 @@ unsigned Analog_Value_Count(
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need to return the instance */
|
||||
/* that correlates to the correct index */
|
||||
uint32_t Analog_Value_Index_To_Instance(
|
||||
unsigned index)
|
||||
uint32_t Analog_Value_Index_To_Instance(unsigned index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
@@ -78,28 +75,25 @@ uint32_t Analog_Value_Index_To_Instance(
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need to return the index */
|
||||
/* that correlates to the correct instance number */
|
||||
unsigned Analog_Value_Instance_To_Index(
|
||||
uint32_t object_instance)
|
||||
unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
return object_instance;
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Analog_Value_Name(
|
||||
uint32_t object_instance)
|
||||
char *Analog_Value_Name(uint32_t object_instance)
|
||||
{
|
||||
static char text_string[5] = "AV-"; /* okay for single thread */
|
||||
|
||||
text_string[3] = '0' + (uint8_t) object_instance;
|
||||
text_string[3] = '0' + (uint8_t)object_instance;
|
||||
|
||||
return text_string;
|
||||
}
|
||||
|
||||
/* return apdu len, or -1 on error */
|
||||
int Analog_Value_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
int apdu_len = 0; /* return value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
unsigned object_index;
|
||||
@@ -108,13 +102,12 @@ int Analog_Value_Read_Property(
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
|
||||
rpdata->object_instance);
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Analog_Value_Name(rpdata->object_instance));
|
||||
characterstring_init_ansi(
|
||||
&char_string, Analog_Value_Name(rpdata->object_instance));
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
@@ -123,11 +116,10 @@ int Analog_Value_Read_Property(
|
||||
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
|
||||
break;
|
||||
case PROP_PRESENT_VALUE:
|
||||
object_index = Analog_Value_Instance_To_Index(
|
||||
rpdata->object_instance);
|
||||
apdu_len =
|
||||
encode_application_real(&apdu[0],
|
||||
AV_Present_Value[object_index]);
|
||||
object_index =
|
||||
Analog_Value_Instance_To_Index(rpdata->object_instance);
|
||||
apdu_len = encode_application_real(
|
||||
&apdu[0], AV_Present_Value[object_index]);
|
||||
break;
|
||||
case PROP_STATUS_FLAGS:
|
||||
bitstring_init(&bit_string);
|
||||
@@ -154,8 +146,7 @@ int Analog_Value_Read_Property(
|
||||
break;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((apdu_len >= 0) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
@@ -165,10 +156,9 @@ int Analog_Value_Read_Property(
|
||||
}
|
||||
|
||||
/* returns true if successful */
|
||||
bool Analog_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
bool status = false; /* return value */
|
||||
unsigned int object_index = 0;
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
@@ -179,9 +169,8 @@ bool Analog_Value_Write_Property(
|
||||
return false;
|
||||
}
|
||||
/* decode the some of the request */
|
||||
len =
|
||||
bacapp_decode_application_data(wp_data->application_data,
|
||||
wp_data->application_data_len, &value);
|
||||
len = bacapp_decode_application_data(
|
||||
wp_data->application_data, wp_data->application_data_len, &value);
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
@@ -233,8 +222,7 @@ bool Analog_Value_Write_Property(
|
||||
#include <string.h>
|
||||
#include "ctest.h"
|
||||
|
||||
void testAnalog_Value(
|
||||
Test * pTest)
|
||||
void testAnalog_Value(Test *pTest)
|
||||
{
|
||||
uint8_t apdu[MAX_APDU] = { 0 };
|
||||
int len = 0;
|
||||
@@ -246,14 +234,12 @@ void testAnalog_Value(
|
||||
BACNET_ERROR_CLASS error_class;
|
||||
BACNET_ERROR_CODE error_code;
|
||||
|
||||
len =
|
||||
Analog_Value_Encode_Property_APDU(&apdu[0], instance,
|
||||
len = Analog_Value_Encode_Property_APDU(&apdu[0], instance,
|
||||
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
|
||||
ct_test(pTest, len != 0);
|
||||
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
|
||||
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
|
||||
len =
|
||||
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
|
||||
len = decode_object_id(&apdu[len], (int *)&decoded_type, &decoded_instance);
|
||||
ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE);
|
||||
ct_test(pTest, decoded_instance == instance);
|
||||
|
||||
@@ -261,8 +247,7 @@ void testAnalog_Value(
|
||||
}
|
||||
|
||||
#ifdef TEST_ANALOG_VALUE
|
||||
int main(
|
||||
void)
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
@@ -274,7 +259,7 @@ int main(
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void) ct_report(pTest);
|
||||
(void)ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
|
||||
+50
-66
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* Binary Value Objects - customize for your use */
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
@@ -47,8 +47,7 @@
|
||||
static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
bool Binary_Value_Valid_Instance(
|
||||
uint32_t object_instance)
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_BINARY_VALUES)
|
||||
return true;
|
||||
@@ -57,22 +56,19 @@ bool Binary_Value_Valid_Instance(
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
unsigned Binary_Value_Count(
|
||||
void)
|
||||
unsigned Binary_Value_Count(void)
|
||||
{
|
||||
return MAX_BINARY_VALUES;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
uint32_t Binary_Value_Index_To_Instance(
|
||||
unsigned index)
|
||||
uint32_t Binary_Value_Index_To_Instance(unsigned index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
unsigned Binary_Value_Instance_To_Index(
|
||||
uint32_t object_instance)
|
||||
unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
unsigned index = MAX_BINARY_VALUES;
|
||||
|
||||
@@ -82,8 +78,7 @@ unsigned Binary_Value_Instance_To_Index(
|
||||
return index;
|
||||
}
|
||||
|
||||
BACNET_BINARY_PV Binary_Value_Present_Value(
|
||||
uint32_t object_instance)
|
||||
BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
|
||||
{
|
||||
BACNET_BINARY_PV value = BINARY_INACTIVE;
|
||||
|
||||
@@ -95,13 +90,12 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Binary_Value_Name(
|
||||
uint32_t object_instance)
|
||||
char *Binary_Value_Name(uint32_t object_instance)
|
||||
{
|
||||
static char text_string[5] = "BV-0"; /* okay for single thread */
|
||||
static char text_string[5] = "BV-0"; /* okay for single thread */
|
||||
|
||||
if (object_instance < MAX_BINARY_VALUES) {
|
||||
text_string[3] = '0' + (uint8_t) object_instance;
|
||||
text_string[3] = '0' + (uint8_t)object_instance;
|
||||
return text_string;
|
||||
}
|
||||
|
||||
@@ -109,10 +103,9 @@ char *Binary_Value_Name(
|
||||
}
|
||||
|
||||
/* return apdu len, or -1 on error */
|
||||
int Binary_Value_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
int apdu_len = 0; /* return value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
|
||||
@@ -122,15 +115,14 @@ int Binary_Value_Read_Property(
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE,
|
||||
rpdata->object_instance);
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
|
||||
break;
|
||||
/* note: Name and Description don't have to be the same.
|
||||
You could make Description writable and different */
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Binary_Value_Name(rpdata->object_instance));
|
||||
characterstring_init_ansi(
|
||||
&char_string, Binary_Value_Name(rpdata->object_instance));
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
@@ -180,10 +172,9 @@ int Binary_Value_Read_Property(
|
||||
}
|
||||
|
||||
/* returns true if successful */
|
||||
bool Binary_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
bool status = false; /* return value */
|
||||
unsigned int object_index = 0;
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
@@ -194,9 +185,8 @@ bool Binary_Value_Write_Property(
|
||||
return false;
|
||||
}
|
||||
/* decode the some of the request */
|
||||
len =
|
||||
bacapp_decode_application_data(wp_data->application_data,
|
||||
wp_data->application_data_len, &value);
|
||||
len = bacapp_decode_application_data(
|
||||
wp_data->application_data, wp_data->application_data_len, &value);
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
@@ -216,12 +206,11 @@ bool Binary_Value_Write_Property(
|
||||
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
||||
if ((value.type.Enumerated == BINARY_ACTIVE) ||
|
||||
(value.type.Enumerated == BINARY_INACTIVE)) {
|
||||
object_index =
|
||||
Binary_Value_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
object_index = Binary_Value_Instance_To_Index(
|
||||
wp_data->object_instance);
|
||||
/* NOTE: this Binary value has no priority array */
|
||||
Present_Value[object_index] =
|
||||
(BACNET_BINARY_PV) value.type.Enumerated;
|
||||
(BACNET_BINARY_PV)value.type.Enumerated;
|
||||
/* Note: you could set the physical output here if we
|
||||
are the highest priority.
|
||||
However, if Out of Service is TRUE, then don't set the
|
||||
@@ -277,8 +266,7 @@ bool Binary_Value_Write_Property(
|
||||
#include <string.h>
|
||||
#include "ctest.h"
|
||||
|
||||
void testBinary_Value(
|
||||
Test * pTest)
|
||||
void testBinary_Value(Test *pTest)
|
||||
{
|
||||
uint8_t apdu[MAX_APDU] = { 0 };
|
||||
int len = 0;
|
||||
@@ -290,15 +278,12 @@ void testBinary_Value(
|
||||
BACNET_ERROR_CLASS error_class;
|
||||
BACNET_ERROR_CODE error_code;
|
||||
|
||||
|
||||
len =
|
||||
Binary_Value_Encode_Property_APDU(&apdu[0], instance,
|
||||
len = Binary_Value_Encode_Property_APDU(&apdu[0], instance,
|
||||
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
|
||||
ct_test(pTest, len != 0);
|
||||
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
|
||||
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
|
||||
len =
|
||||
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
|
||||
len = decode_object_id(&apdu[len], (int *)&decoded_type, &decoded_instance);
|
||||
ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE);
|
||||
ct_test(pTest, decoded_instance == instance);
|
||||
|
||||
@@ -306,8 +291,7 @@ void testBinary_Value(
|
||||
}
|
||||
|
||||
#ifdef TEST_BINARY_VALUE
|
||||
int main(
|
||||
void)
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
@@ -319,7 +303,7 @@ int main(
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void) ct_report(pTest);
|
||||
(void)ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
|
||||
+59
-74
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@@ -50,8 +50,7 @@ static uint32_t Object_Instance_Number = 260001;
|
||||
static char Object_Name[20] = "My Device";
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
|
||||
void Device_Init(
|
||||
object_functions_t * object_table)
|
||||
void Device_Init(object_functions_t *object_table)
|
||||
{
|
||||
(void)object_table;
|
||||
/* Reinitialize_State = BACNET_REINIT_IDLE; */
|
||||
@@ -64,14 +63,12 @@ void Device_Init(
|
||||
}
|
||||
|
||||
/* methods to manipulate the data */
|
||||
uint32_t Device_Object_Instance_Number(
|
||||
void)
|
||||
uint32_t Device_Object_Instance_Number(void)
|
||||
{
|
||||
return Object_Instance_Number;
|
||||
}
|
||||
|
||||
bool Device_Set_Object_Instance_Number(
|
||||
uint32_t object_id)
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
bool status = true; /* return value */
|
||||
|
||||
@@ -89,21 +86,18 @@ bool Device_Set_Object_Instance_Number(
|
||||
return status;
|
||||
}
|
||||
|
||||
bool Device_Valid_Object_Instance_Number(
|
||||
uint32_t object_id)
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
/* BACnet allows for a wildcard instance number */
|
||||
return (Object_Instance_Number == object_id);
|
||||
}
|
||||
|
||||
uint16_t Device_Vendor_Identifier(
|
||||
void)
|
||||
uint16_t Device_Vendor_Identifier(void)
|
||||
{
|
||||
return BACNET_VENDOR_ID;
|
||||
}
|
||||
|
||||
unsigned Device_Object_List_Count(
|
||||
void)
|
||||
unsigned Device_Object_List_Count(void)
|
||||
{
|
||||
unsigned count = 1; /* at least 1 for device object */
|
||||
|
||||
@@ -115,9 +109,7 @@ unsigned Device_Object_List_Count(
|
||||
}
|
||||
|
||||
bool Device_Object_List_Identifier(
|
||||
uint32_t array_index,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * instance)
|
||||
uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
|
||||
{
|
||||
bool status = false;
|
||||
uint32_t object_index = 0;
|
||||
@@ -163,12 +155,11 @@ bool Device_Object_List_Identifier(
|
||||
}
|
||||
|
||||
/* return the length of the apdu encoded or -1 for error */
|
||||
int Device_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
uint8_t * apdu;
|
||||
int apdu_len = 0; /* return value */
|
||||
int len = 0; /* apdu len intermediate value */
|
||||
uint8_t *apdu;
|
||||
int apdu_len = 0; /* return value */
|
||||
int len = 0; /* apdu len intermediate value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
uint32_t i = 0;
|
||||
@@ -179,9 +170,8 @@ int Device_Read_Property(
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
|
||||
Object_Instance_Number);
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], OBJECT_DEVICE, Object_Instance_Number);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string, Object_Name);
|
||||
@@ -200,9 +190,8 @@ int Device_Read_Property(
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_VENDOR_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0],
|
||||
Device_Vendor_Identifier());
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0], Device_Vendor_Identifier());
|
||||
break;
|
||||
case PROP_MODEL_NAME:
|
||||
characterstring_init_ansi(&char_string, "GNU Demo");
|
||||
@@ -225,16 +214,15 @@ int Device_Read_Property(
|
||||
break;
|
||||
case PROP_PROTOCOL_REVISION:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0],
|
||||
BACNET_PROTOCOL_REVISION);
|
||||
encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_REVISION);
|
||||
break;
|
||||
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
||||
/* Note: list of services that are executed, not initiated. */
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* automatic lookup based on handlers set */
|
||||
bitstring_set_bit(&bit_string, (uint8_t) i,
|
||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
|
||||
bitstring_set_bit(&bit_string, (uint8_t)i,
|
||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
|
||||
}
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
@@ -245,7 +233,7 @@ int Device_Read_Property(
|
||||
/* must have the bit string as big as it can be */
|
||||
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
|
||||
/* initialize all the object types to not-supported */
|
||||
bitstring_set_bit(&bit_string, (uint8_t) i, false);
|
||||
bitstring_set_bit(&bit_string, (uint8_t)i, false);
|
||||
}
|
||||
/* FIXME: indicate the objects that YOU support */
|
||||
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
||||
@@ -265,9 +253,8 @@ int Device_Read_Property(
|
||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
for (i = 1; i <= count; i++) {
|
||||
Device_Object_List_Identifier(i, &object_type, &instance);
|
||||
len =
|
||||
encode_application_object_id(&apdu[apdu_len],
|
||||
object_type, instance);
|
||||
len = encode_application_object_id(
|
||||
&apdu[apdu_len], object_type, instance);
|
||||
apdu_len += len;
|
||||
/* assume next one is the same size as this one */
|
||||
/* can we all fit into the APDU? */
|
||||
@@ -280,11 +267,10 @@ int Device_Read_Property(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Device_Object_List_Identifier(rpdata->array_index,
|
||||
&object_type, &instance))
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], object_type,
|
||||
instance);
|
||||
if (Device_Object_List_Identifier(
|
||||
rpdata->array_index, &object_type, &instance))
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], object_type, instance);
|
||||
else {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
@@ -313,8 +299,7 @@ int Device_Read_Property(
|
||||
break;
|
||||
case PROP_MAX_INFO_FRAMES:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0],
|
||||
dlmstp_max_info_frames());
|
||||
encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
|
||||
break;
|
||||
case PROP_MAX_MASTER:
|
||||
apdu_len =
|
||||
@@ -347,10 +332,9 @@ int Device_Read_Property(
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
bool status = false; /* return value */
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
|
||||
@@ -360,9 +344,8 @@ bool Device_Write_Property(
|
||||
return false;
|
||||
}
|
||||
/* decode the some of the request */
|
||||
len =
|
||||
bacapp_decode_application_data(wp_data->application_data,
|
||||
wp_data->application_data_len, &value);
|
||||
len = bacapp_decode_application_data(
|
||||
wp_data->application_data, wp_data->application_data_len, &value);
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
@@ -381,8 +364,8 @@ bool Device_Write_Property(
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||
(Device_Set_Object_Instance_Number(value.type.
|
||||
Object_Id.instance))) {
|
||||
(Device_Set_Object_Instance_Number(
|
||||
value.type.Object_Id.instance))) {
|
||||
/* we could send an I-Am broadcast to let the world know */
|
||||
status = true;
|
||||
} else {
|
||||
@@ -436,11 +419,13 @@ bool Device_Write_Property(
|
||||
status = true;
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
wp_data->error_code =
|
||||
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
}
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
|
||||
wp_data->error_code =
|
||||
ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
|
||||
+111
-102
@@ -66,23 +66,23 @@ static struct mstp_flag_t {
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if an invalid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedInvalidFrame:1;
|
||||
unsigned ReceivedInvalidFrame : 1;
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if a valid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedValidFrame:1;
|
||||
unsigned ReceivedValidFrame : 1;
|
||||
/* A Boolean flag set to TRUE by the master machine if this node is the */
|
||||
/* only known master node. */
|
||||
unsigned SoleMaster:1;
|
||||
unsigned SoleMaster : 1;
|
||||
/* A Boolean flag set TRUE by the datalink transmit if a
|
||||
frame is pending */
|
||||
unsigned TransmitPacketPending:1;
|
||||
unsigned TransmitPacketPending : 1;
|
||||
/* A Boolean flag set TRUE by the datalink transmit if a
|
||||
pending packet is DataExpectingReply */
|
||||
unsigned TransmitPacketDER:1;
|
||||
unsigned TransmitPacketDER : 1;
|
||||
/* A Boolean flag set TRUE by the datalink if a
|
||||
packet has been received, but not processed. */
|
||||
unsigned ReceivePacketPending:1;
|
||||
unsigned ReceivePacketPending : 1;
|
||||
} MSTP_Flag;
|
||||
|
||||
/* Used to store the data length of a received frame. */
|
||||
@@ -165,10 +165,13 @@ static uint8_t TransmitPacketDest;
|
||||
#define Treply_delay 250
|
||||
|
||||
/* we need to be able to increment without rolling over */
|
||||
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;}
|
||||
#define INCREMENT_AND_LIMIT_UINT8(x) \
|
||||
{ \
|
||||
if (x < 0xFF) \
|
||||
x++; \
|
||||
}
|
||||
|
||||
bool dlmstp_init(
|
||||
char *ifname)
|
||||
bool dlmstp_init(char *ifname)
|
||||
{
|
||||
ifname = ifname;
|
||||
/* initialize hardware */
|
||||
@@ -177,15 +180,12 @@ bool dlmstp_init(
|
||||
return true;
|
||||
}
|
||||
|
||||
void dlmstp_cleanup(
|
||||
void)
|
||||
void dlmstp_cleanup(void)
|
||||
{
|
||||
/* nothing to do for static buffers */
|
||||
}
|
||||
|
||||
void dlmstp_fill_bacnet_address(
|
||||
BACNET_ADDRESS * src,
|
||||
uint8_t mstp_address)
|
||||
void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@@ -212,8 +212,7 @@ void dlmstp_fill_bacnet_address(
|
||||
extern bool Send_I_Am_Flag;
|
||||
|
||||
/* look at any of the unconfirmed message bits and encode if set */
|
||||
static uint16_t dlmstp_encode_unconfirmed_frame(
|
||||
void)
|
||||
static uint16_t dlmstp_encode_unconfirmed_frame(void)
|
||||
{
|
||||
BACNET_ADDRESS dest;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
@@ -243,16 +242,16 @@ static uint16_t dlmstp_encode_unconfirmed_frame(
|
||||
/* (pad): (optional) at most one octet of padding: X'FF' */
|
||||
static void MSTP_Send_Frame(
|
||||
uint8_t frame_type, /* type of frame to send - see defines */
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t source, /* source address */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t source, /* source address */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
uint16_t pdu_len)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
|
||||
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
|
||||
uint8_t buffer[8]; /* stores the header and crc */
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
|
||||
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
|
||||
uint8_t buffer[8]; /* stores the header and crc */
|
||||
uint8_t datacrc[2]; /* stores the data crc */
|
||||
uint16_t i = 0; /* used to calculate CRC for data */
|
||||
uint16_t i = 0; /* used to calculate CRC for data */
|
||||
|
||||
/* create the MS/TP header */
|
||||
buffer[0] = 0x55;
|
||||
@@ -290,8 +289,7 @@ static void MSTP_Send_Frame(
|
||||
RS485_Transmitter_Enable(false);
|
||||
}
|
||||
|
||||
static void MSTP_Receive_Frame_FSM(
|
||||
void)
|
||||
static void MSTP_Receive_Frame_FSM(void)
|
||||
{
|
||||
/* stores the latest received data octet */
|
||||
uint8_t DataRegister = 0;
|
||||
@@ -305,7 +303,8 @@ static void MSTP_Receive_Frame_FSM(
|
||||
|
||||
switch (Receive_State) {
|
||||
case MSTP_RECEIVE_STATE_IDLE:
|
||||
/* In the IDLE state, the node waits for the beginning of a frame. */
|
||||
/* In the IDLE state, the node waits for the beginning of a frame.
|
||||
*/
|
||||
if (RS485_ReceiveError()) {
|
||||
/* EatAnError */
|
||||
Timer_Silence_Reset();
|
||||
@@ -355,10 +354,12 @@ static void MSTP_Receive_Frame_FSM(
|
||||
}
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_HEADER:
|
||||
/* In the HEADER state, the node waits for the fixed message header. */
|
||||
/* In the HEADER state, the node waits for the fixed message header.
|
||||
*/
|
||||
if (Timer_Silence() > Tframe_abort) {
|
||||
/* Timeout */
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
/* indicate that an error has occurred during the reception of a
|
||||
* frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
@@ -366,7 +367,8 @@ static void MSTP_Receive_Frame_FSM(
|
||||
/* Error */
|
||||
Timer_Silence_Reset();
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
/* indicate that an error has occurred during the reception of a
|
||||
* frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
@@ -454,10 +456,12 @@ static void MSTP_Receive_Frame_FSM(
|
||||
}
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_DATA:
|
||||
/* In the DATA state, the node waits for the data portion of a frame. */
|
||||
/* In the DATA state, the node waits for the data portion of a
|
||||
* frame. */
|
||||
if (Timer_Silence() > Tframe_abort) {
|
||||
/* Timeout */
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
/* indicate that an error has occurred during the reception of a
|
||||
* frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of the next frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
@@ -512,15 +516,16 @@ static void MSTP_Receive_Frame_FSM(
|
||||
}
|
||||
|
||||
/* returns true if we need to transition immediately */
|
||||
static bool MSTP_Master_Node_FSM(
|
||||
void)
|
||||
static bool MSTP_Master_Node_FSM(void)
|
||||
{
|
||||
/* The number of frames sent by this node during a single token hold. */
|
||||
/* When this counter reaches the value Nmax_info_frames, the node must */
|
||||
/* pass the token. */
|
||||
static uint8_t FrameCount;
|
||||
/* "Next Station," the MAC address of the node to which This Station passes */
|
||||
/* the token. If the Next_Station is unknown, Next_Station shall be equal to */
|
||||
/* "Next Station," the MAC address of the node to which This Station passes
|
||||
*/
|
||||
/* the token. If the Next_Station is unknown, Next_Station shall be equal to
|
||||
*/
|
||||
/* This_Station. */
|
||||
static uint8_t Next_Station;
|
||||
/* "Poll Station," the MAC address of the node to which This Station last */
|
||||
@@ -529,7 +534,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* A counter of transmission retries used for Token and Poll For Master */
|
||||
/* transmission. */
|
||||
static unsigned RetryCount;
|
||||
/* The number of tokens received by this node. When this counter reaches the */
|
||||
/* The number of tokens received by this node. When this counter reaches the
|
||||
*/
|
||||
/* value Npoll, the node polls the address range between TS and NS for */
|
||||
/* additional master nodes. TokenCount is set to zero at the end of the */
|
||||
/* polling process. */
|
||||
@@ -603,7 +609,7 @@ static bool MSTP_Master_Node_FSM(
|
||||
MSTP_Flag.ReceivePacketPending = true;
|
||||
break;
|
||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||
/* indicate successful reception to the higher layers */
|
||||
/* indicate successful reception to the higher layers */
|
||||
MSTP_Flag.ReceivePacketPending = true;
|
||||
/* broadcast DER just remains IDLE */
|
||||
if (DestinationAddress != MSTP_BROADCAST_ADDRESS) {
|
||||
@@ -612,9 +618,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
}
|
||||
break;
|
||||
case FRAME_TYPE_TEST_REQUEST:
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE,
|
||||
SourceAddress, This_Station, &InputBuffer[0],
|
||||
DataLength);
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress,
|
||||
This_Station, &InputBuffer[0], DataLength);
|
||||
break;
|
||||
case FRAME_TYPE_TEST_RESPONSE:
|
||||
default:
|
||||
@@ -638,7 +643,7 @@ static bool MSTP_Master_Node_FSM(
|
||||
if (TransmitPacketLen) {
|
||||
MSTP_Send_Frame(FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY,
|
||||
MSTP_BROADCAST_ADDRESS, This_Station,
|
||||
(uint8_t *) & TransmitPacket[0], TransmitPacketLen);
|
||||
(uint8_t *)&TransmitPacket[0], TransmitPacketLen);
|
||||
FrameCount++;
|
||||
} else {
|
||||
/* NothingToSend */
|
||||
@@ -656,8 +661,10 @@ static bool MSTP_Master_Node_FSM(
|
||||
FrameCount = Nmax_info_frames;
|
||||
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||
/* Any retry of the data frame shall await the next entry */
|
||||
/* to the USE_TOKEN state. (Because of the length of the timeout, */
|
||||
/* this transition will cause the token to be passed regardless */
|
||||
/* to the USE_TOKEN state. (Because of the length of the
|
||||
* timeout, */
|
||||
/* this transition will cause the token to be passed regardless
|
||||
*/
|
||||
/* of the initial value of FrameCount.) */
|
||||
transition_now = true;
|
||||
} else {
|
||||
@@ -682,8 +689,10 @@ static bool MSTP_Master_Node_FSM(
|
||||
break;
|
||||
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
||||
/* ReceivedReply */
|
||||
/* or a proprietary type that indicates a reply */
|
||||
/* indicate successful reception to the higher layers */
|
||||
/* or a proprietary type that indicates a reply
|
||||
*/
|
||||
/* indicate successful reception to the higher
|
||||
* layers */
|
||||
MSTP_Flag.ReceivePacketPending = true;
|
||||
Master_State =
|
||||
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||
@@ -735,7 +744,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
(Next_Station != next_this_station)) {
|
||||
/* SoleMaster */
|
||||
/* there are no other known master nodes to */
|
||||
/* which the token may be sent (true master-slave operation). */
|
||||
/* which the token may be sent (true master-slave
|
||||
* operation). */
|
||||
FrameCount = 0;
|
||||
TokenCount++;
|
||||
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
@@ -743,13 +753,16 @@ static bool MSTP_Master_Node_FSM(
|
||||
} else {
|
||||
/* SendToken */
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
/* The comparison of NS and TS+1 eliminates the Poll For Master */
|
||||
/* if there are no addresses between TS and NS, since there is no */
|
||||
/* address at which a new master node may be found in that case. */
|
||||
/* The comparison of NS and TS+1 eliminates the Poll For
|
||||
* Master */
|
||||
/* if there are no addresses between TS and NS, since there
|
||||
* is no */
|
||||
/* address at which a new master node may be found in that
|
||||
* case. */
|
||||
TokenCount++;
|
||||
/* transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
EventCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
|
||||
@@ -763,7 +776,7 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* no known successor node */
|
||||
Next_Station = This_Station;
|
||||
RetryCount = 0;
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
/* EventCount = 0; removed in Addendum 135-2004d-8 */
|
||||
/* find a new successor to TS */
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
@@ -771,10 +784,10 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* ResetMaintenancePFM */
|
||||
Poll_Station = This_Station;
|
||||
/* transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
EventCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
|
||||
}
|
||||
@@ -793,7 +806,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
if (Timer_Silence() <= Tusage_timeout) {
|
||||
if (EventCount > Nmin_octets) {
|
||||
/* SawTokenUser */
|
||||
/* Assume that a frame has been sent by the new token user. */
|
||||
/* Assume that a frame has been sent by the new token user.
|
||||
*/
|
||||
/* Enter the IDLE state to process the frame. */
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
@@ -803,8 +817,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* RetrySendToken */
|
||||
RetryCount++;
|
||||
/* Transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
EventCount = 0;
|
||||
/* re-enter the current state to listen for NS */
|
||||
/* to begin using the token. */
|
||||
@@ -826,9 +840,11 @@ static bool MSTP_Master_Node_FSM(
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* The NO_TOKEN state is entered if Timer_Silence() becomes greater */
|
||||
/* than Tno_token, indicating that there has been no network activity */
|
||||
/* for that period of time. The timeout is continued to determine */
|
||||
/* The NO_TOKEN state is entered if Timer_Silence() becomes greater
|
||||
*/
|
||||
/* than Tno_token, indicating that there has been no network
|
||||
* activity */
|
||||
/* for that period of time. The timeout is continued to determine */
|
||||
/* whether or not this node may create a token. */
|
||||
case MSTP_MASTER_STATE_NO_TOKEN:
|
||||
my_timeout = Tno_token + (Tslot * This_Station);
|
||||
@@ -836,7 +852,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
if (EventCount > Nmin_octets) {
|
||||
/* SawFrame */
|
||||
/* Some other node exists at a lower address. */
|
||||
/* Enter the IDLE state to receive and process the incoming frame. */
|
||||
/* Enter the IDLE state to receive and process the incoming
|
||||
* frame. */
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
}
|
||||
@@ -855,7 +872,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
RetryCount = 0;
|
||||
TokenCount = 0;
|
||||
/* EventCount = 0; removed Addendum 135-2004d-8 */
|
||||
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */
|
||||
/* enter the POLL_FOR_MASTER state to find a new successor
|
||||
* to TS. */
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
}
|
||||
}
|
||||
@@ -865,15 +883,15 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* a successor node. */
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
if (MSTP_Flag.ReceivedValidFrame == true) {
|
||||
if ((DestinationAddress == This_Station)
|
||||
&& (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
|
||||
if ((DestinationAddress == This_Station) &&
|
||||
(FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
|
||||
/* ReceivedReplyToPFM */
|
||||
MSTP_Flag.SoleMaster = false;
|
||||
Next_Station = SourceAddress;
|
||||
EventCount = 0;
|
||||
/* Transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
Poll_Station = This_Station;
|
||||
TokenCount = 0;
|
||||
RetryCount = 0;
|
||||
@@ -920,7 +938,8 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* Re-enter the current state. */
|
||||
} else {
|
||||
/* DeclareSoleMaster */
|
||||
/* to indicate that this station is the only master */
|
||||
/* to indicate that this station is the only master
|
||||
*/
|
||||
MSTP_Flag.SoleMaster = true;
|
||||
FrameCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
@@ -948,7 +967,7 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* Note: optimized such that we are never a client */
|
||||
MSTP_Send_Frame(FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY,
|
||||
TransmitPacketDest, This_Station,
|
||||
(uint8_t *) & TransmitPacket[0], TransmitPacketLen);
|
||||
(uint8_t *)&TransmitPacket[0], TransmitPacketLen);
|
||||
MSTP_Flag.TransmitPacketPending = false;
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
} else {
|
||||
@@ -977,12 +996,11 @@ static bool MSTP_Master_Node_FSM(
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, zero on failure */
|
||||
int dlmstp_send_pdu(
|
||||
BACNET_ADDRESS * dest, /* destination address */
|
||||
BACNET_NPDU_DATA * npdu_data, /* network information */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
{ /* number of bytes of data */
|
||||
{ /* number of bytes of data */
|
||||
int bytes_sent = 0;
|
||||
|
||||
if (MSTP_Flag.TransmitPacketPending == false) {
|
||||
@@ -1003,13 +1021,12 @@ int dlmstp_send_pdu(
|
||||
}
|
||||
|
||||
/* Return the length of the packet */
|
||||
uint16_t dlmstp_receive(
|
||||
BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
|
||||
/* dummy - unused parameter */
|
||||
timeout = timeout;
|
||||
@@ -1051,8 +1068,7 @@ uint16_t dlmstp_receive(
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
void dlmstp_set_mac_address(
|
||||
uint8_t mac_address)
|
||||
void dlmstp_set_mac_address(uint8_t mac_address)
|
||||
{
|
||||
/* Master Nodes can only have address 0-127 */
|
||||
if (mac_address <= 127) {
|
||||
@@ -1069,8 +1085,7 @@ void dlmstp_set_mac_address(
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t dlmstp_mac_address(
|
||||
void)
|
||||
uint8_t dlmstp_mac_address(void)
|
||||
{
|
||||
return This_Station;
|
||||
}
|
||||
@@ -1082,8 +1097,7 @@ uint8_t dlmstp_mac_address(
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
void dlmstp_set_max_info_frames(
|
||||
uint8_t max_info_frames)
|
||||
void dlmstp_set_max_info_frames(uint8_t max_info_frames)
|
||||
{
|
||||
if (max_info_frames >= 1) {
|
||||
Nmax_info_frames = max_info_frames;
|
||||
@@ -1097,8 +1111,7 @@ void dlmstp_set_max_info_frames(
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t dlmstp_max_info_frames(
|
||||
void)
|
||||
uint8_t dlmstp_max_info_frames(void)
|
||||
{
|
||||
return Nmax_info_frames;
|
||||
}
|
||||
@@ -1108,8 +1121,7 @@ uint8_t dlmstp_max_info_frames(
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
void dlmstp_set_max_master(
|
||||
uint8_t max_master)
|
||||
void dlmstp_set_max_master(uint8_t max_master)
|
||||
{
|
||||
if (max_master <= 127) {
|
||||
if (This_Station <= max_master) {
|
||||
@@ -1125,20 +1137,18 @@ void dlmstp_set_max_master(
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t dlmstp_max_master(
|
||||
void)
|
||||
uint8_t dlmstp_max_master(void)
|
||||
{
|
||||
return Nmax_master;
|
||||
}
|
||||
|
||||
void dlmstp_get_my_address(
|
||||
BACNET_ADDRESS * my_address)
|
||||
void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
|
||||
{
|
||||
int i = 0; /* counter */
|
||||
int i = 0; /* counter */
|
||||
|
||||
my_address->mac_len = 1;
|
||||
my_address->mac[0] = This_Station;
|
||||
my_address->net = 0; /* local only, no routing */
|
||||
my_address->net = 0; /* local only, no routing */
|
||||
my_address->len = 0;
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
my_address->adr[i] = 0;
|
||||
@@ -1147,16 +1157,15 @@ void dlmstp_get_my_address(
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_broadcast_address(
|
||||
BACNET_ADDRESS * dest)
|
||||
{ /* destination address */
|
||||
int i = 0; /* counter */
|
||||
void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
|
||||
{ /* destination address */
|
||||
int i = 0; /* counter */
|
||||
|
||||
if (dest) {
|
||||
dest->mac_len = 1;
|
||||
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
|
||||
dest->net = BACNET_BROADCAST_NETWORK;
|
||||
dest->len = 0; /* always zero when DNET is broadcast */
|
||||
dest->len = 0; /* always zero when DNET is broadcast */
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
dest->adr[i] = 0;
|
||||
}
|
||||
|
||||
+44
-55
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -44,9 +44,7 @@
|
||||
|
||||
/* Encodes the property APDU and returns the length,
|
||||
or sets the error, and returns -1 */
|
||||
int Encode_Property_APDU(
|
||||
uint8_t * apdu,
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
int Encode_Property_APDU(uint8_t *apdu, BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = -1;
|
||||
|
||||
@@ -80,11 +78,10 @@ int Encode_Property_APDU(
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
void handler_read_property(
|
||||
uint8_t * service_request,
|
||||
void handler_read_property(uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
||||
{
|
||||
BACNET_READ_PROPERTY_DATA data;
|
||||
int len = 0;
|
||||
@@ -98,13 +95,11 @@ void handler_read_property(
|
||||
/* encode the NPDU portion of the packet */
|
||||
datalink_get_my_address(&my_address);
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
pdu_len =
|
||||
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
||||
&npdu_data);
|
||||
pdu_len = npdu_encode_pdu(
|
||||
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
||||
if (service_data->segmented_message) {
|
||||
/* we don't support segmentation - send an abort */
|
||||
len =
|
||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
goto RP_ABORT;
|
||||
@@ -112,48 +107,42 @@ void handler_read_property(
|
||||
len = rp_decode_service_request(service_request, service_len, &data);
|
||||
if (len < 0) {
|
||||
/* bad decoding - send an abort */
|
||||
len =
|
||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
goto RP_ABORT;
|
||||
}
|
||||
/* most cases will be error */
|
||||
ack_len =
|
||||
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, &data);
|
||||
ack_len = rp_ack_encode_apdu_init(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
|
||||
/* FIXME: add buffer len as passed into function or use smart buffer */
|
||||
data.error_class = ERROR_CLASS_OBJECT;
|
||||
data.error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
property_len =
|
||||
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len],
|
||||
&data);
|
||||
property_len = Encode_Property_APDU(
|
||||
&Handler_Transmit_Buffer[pdu_len + ack_len], &data);
|
||||
if (property_len >= 0) {
|
||||
len =
|
||||
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer
|
||||
[pdu_len + property_len + ack_len]);
|
||||
len = rp_ack_encode_apdu_object_property_end(
|
||||
&Handler_Transmit_Buffer[pdu_len + property_len + ack_len]);
|
||||
len += ack_len + property_len;
|
||||
} else {
|
||||
switch (property_len) {
|
||||
/* BACnet APDU too small to fit data, so proper response is Abort */
|
||||
/* BACnet APDU too small to fit data, so proper response is
|
||||
* Abort */
|
||||
case BACNET_STATUS_ABORT:
|
||||
len =
|
||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
break;
|
||||
default:
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
data.error_class, data.error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
RP_ABORT:
|
||||
RP_ABORT:
|
||||
pdu_len += len;
|
||||
bytes_sent =
|
||||
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||
pdu_len);
|
||||
bytes_sent = datalink_send_pdu(
|
||||
src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||
(void)bytes_sent;
|
||||
|
||||
return;
|
||||
|
||||
+27
-30
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -40,19 +40,16 @@
|
||||
bool Send_I_Am_Flag = true;
|
||||
|
||||
void handler_who_is(
|
||||
uint8_t * service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src)
|
||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
|
||||
{
|
||||
int len = 0;
|
||||
int32_t low_limit = 0;
|
||||
int32_t high_limit = 0;
|
||||
int32_t target_device;
|
||||
|
||||
(void) src;
|
||||
len =
|
||||
whois_decode_service_request(service_request, service_len, &low_limit,
|
||||
&high_limit);
|
||||
(void)src;
|
||||
len = whois_decode_service_request(
|
||||
service_request, service_len, &low_limit, &high_limit);
|
||||
if (len == 0) {
|
||||
Send_I_Am_Flag = true;
|
||||
} else if (len != BACNET_STATUS_ERROR) {
|
||||
|
||||
+45
-54
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -45,11 +45,10 @@
|
||||
/* too big to reside on stack frame for PIC */
|
||||
static BACNET_WRITE_PROPERTY_DATA wp_data;
|
||||
|
||||
void handler_write_property(
|
||||
uint8_t * service_request,
|
||||
void handler_write_property(uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
||||
{
|
||||
int len = 0;
|
||||
int pdu_len = 0;
|
||||
@@ -62,17 +61,14 @@ void handler_write_property(
|
||||
/* encode the NPDU portion of the packet */
|
||||
datalink_get_my_address(&my_address);
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
pdu_len =
|
||||
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
||||
&npdu_data);
|
||||
pdu_len = npdu_encode_pdu(
|
||||
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
||||
/* bad decoding or something we didn't understand - send an abort */
|
||||
if (len <= 0) {
|
||||
len =
|
||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
} else if (service_data->segmented_message) {
|
||||
len =
|
||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
} else {
|
||||
@@ -81,58 +77,53 @@ void handler_write_property(
|
||||
switch (wp_data.object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if (Device_Write_Property(&wp_data)) {
|
||||
len =
|
||||
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class,
|
||||
wp_data.error_code);
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
wp_data.error_class, wp_data.error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Write_Property(&wp_data)) {
|
||||
len =
|
||||
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class,
|
||||
wp_data.error_code);
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
wp_data.error_class, wp_data.error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Write_Property(&wp_data)) {
|
||||
len =
|
||||
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class,
|
||||
wp_data.error_code);
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
wp_data.error_class, wp_data.error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
wp_data.error_class, wp_data.error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pdu_len += len;
|
||||
bytes_sent =
|
||||
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||
pdu_len);
|
||||
bytes_sent = datalink_send_pdu(
|
||||
src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||
(void)bytes_sent;
|
||||
|
||||
return;
|
||||
|
||||
+28
-33
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@@ -45,14 +45,12 @@ const char *BACnet_Version = "1.0";
|
||||
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
|
||||
|
||||
/* dummy function - so we can use default demo handlers */
|
||||
bool dcc_communication_enabled(
|
||||
void)
|
||||
bool dcc_communication_enabled(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void init(
|
||||
void)
|
||||
static void init(void)
|
||||
{
|
||||
/* Initialize the Clock Prescaler for ATmega48/88/168 */
|
||||
/* The default CLKPSx bits are factory set to 0011 */
|
||||
@@ -105,8 +103,7 @@ static void init(
|
||||
__enable_interrupt();
|
||||
}
|
||||
|
||||
static void task_milliseconds(
|
||||
void)
|
||||
static void task_milliseconds(void)
|
||||
{
|
||||
while (Timer_Milliseconds) {
|
||||
Timer_Milliseconds--;
|
||||
@@ -117,8 +114,7 @@ static void task_milliseconds(
|
||||
|
||||
static uint8_t Address_Switch;
|
||||
|
||||
static void input_switch_read(
|
||||
void)
|
||||
static void input_switch_read(void)
|
||||
{
|
||||
uint8_t value;
|
||||
static uint8_t old_value = 0;
|
||||
@@ -140,8 +136,7 @@ static void input_switch_read(
|
||||
}
|
||||
|
||||
static uint8_t PDUBuffer[MAX_MPDU];
|
||||
int main(
|
||||
void)
|
||||
int main(void)
|
||||
{
|
||||
uint16_t pdu_len = 0;
|
||||
BACNET_ADDRESS src; /* source address */
|
||||
|
||||
+92
-104
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* The module handles sending data out the RS-485 port */
|
||||
/* and handles receiving data from the RS-485 port. */
|
||||
@@ -45,14 +45,13 @@ static uint8_t LED3_Off_Timer;
|
||||
static uint32_t RS485_Baud = 9600;
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
|
||||
* receive mode.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Initialize(
|
||||
void)
|
||||
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
|
||||
* receive mode.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Initialize(void)
|
||||
{
|
||||
/* enable Transmit and Receive */
|
||||
UCSR0B = _BV(TXEN0) | _BV(RXEN0);
|
||||
@@ -81,25 +80,23 @@ void RS485_Initialize(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Returns the baud rate that we are currently running at
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
uint32_t RS485_Get_Baud_Rate(
|
||||
void)
|
||||
* DESCRIPTION: Returns the baud rate that we are currently running at
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
uint32_t RS485_Get_Baud_Rate(void)
|
||||
{
|
||||
return RS485_Baud;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Sets the baud rate for the chip USART
|
||||
* RETURN: true if valid baud rate
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
bool RS485_Set_Baud_Rate(
|
||||
uint32_t baud)
|
||||
* DESCRIPTION: Sets the baud rate for the chip USART
|
||||
* RETURN: true if valid baud rate
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
bool RS485_Set_Baud_Rate(uint32_t baud)
|
||||
{
|
||||
bool valid = true;
|
||||
|
||||
@@ -126,13 +123,12 @@ bool RS485_Set_Baud_Rate(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Enable or disable the transmitter
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Transmitter_Enable(
|
||||
bool enable)
|
||||
* DESCRIPTION: Enable or disable the transmitter
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Transmitter_Enable(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
BIT_SET(PORTD, PD2);
|
||||
@@ -142,13 +138,12 @@ void RS485_Transmitter_Enable(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Waits on the SilenceTimer for 40 bits.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Turnaround_Delay(
|
||||
void)
|
||||
* DESCRIPTION: Waits on the SilenceTimer for 40 bits.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Turnaround_Delay(void)
|
||||
{
|
||||
uint8_t nbytes = 4;
|
||||
|
||||
@@ -171,13 +166,12 @@ void RS485_Turnaround_Delay(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Timers for delaying the LED indicators going off
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: expected to be called once a millisecond
|
||||
*****************************************************************************/
|
||||
void RS485_LED_Timers(
|
||||
void)
|
||||
* DESCRIPTION: Timers for delaying the LED indicators going off
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: expected to be called once a millisecond
|
||||
*****************************************************************************/
|
||||
void RS485_LED_Timers(void)
|
||||
{
|
||||
if (LED1_Off_Timer) {
|
||||
LED1_Off_Timer--;
|
||||
@@ -194,41 +188,38 @@ void RS485_LED_Timers(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Turn on the LED, and set the off timer to turn it off
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
static void RS485_LED1_On(
|
||||
void)
|
||||
* DESCRIPTION: Turn on the LED, and set the off timer to turn it off
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
static void RS485_LED1_On(void)
|
||||
{
|
||||
BIT_CLEAR(PORTD, PD6);
|
||||
LED1_Off_Timer = 20;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Turn on the LED, and set the off timer to turn it off
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
static void RS485_LED3_On(
|
||||
void)
|
||||
* DESCRIPTION: Turn on the LED, and set the off timer to turn it off
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
static void RS485_LED3_On(void)
|
||||
{
|
||||
BIT_CLEAR(PORTD, PD7);
|
||||
LED3_Off_Timer = 20;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Send some data and wait until it is sent
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Send_Data(
|
||||
uint8_t * buffer, /* data to send */
|
||||
* DESCRIPTION: Send some data and wait until it is sent
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Send_Data(uint8_t *buffer, /* data to send */
|
||||
uint16_t nbytes)
|
||||
{ /* number of bytes of data */
|
||||
{ /* number of bytes of data */
|
||||
RS485_LED3_On();
|
||||
while (nbytes) {
|
||||
while (!BIT_CHECK(UCSR0A, UDRE0)) {
|
||||
@@ -251,13 +242,12 @@ void RS485_Send_Data(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Return true if a framing or overrun error is present
|
||||
* RETURN: true if error
|
||||
* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate
|
||||
* NOTES: Clears any error flags.
|
||||
*****************************************************************************/
|
||||
bool RS485_ReceiveError(
|
||||
void)
|
||||
* DESCRIPTION: Return true if a framing or overrun error is present
|
||||
* RETURN: true if error
|
||||
* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate
|
||||
* NOTES: Clears any error flags.
|
||||
*****************************************************************************/
|
||||
bool RS485_ReceiveError(void)
|
||||
{
|
||||
bool ReceiveError = false;
|
||||
volatile uint8_t dummy_data;
|
||||
@@ -287,13 +277,12 @@ bool RS485_ReceiveError(
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Return true if data is available
|
||||
* RETURN: true if data is available, with the data in the parameter set
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
bool RS485_DataAvailable(
|
||||
uint8_t * data)
|
||||
* DESCRIPTION: Return true if data is available
|
||||
* RETURN: true if data is available, with the data in the parameter set
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
bool RS485_DataAvailable(uint8_t *data)
|
||||
{
|
||||
bool DataAvailable = false;
|
||||
|
||||
@@ -308,8 +297,7 @@ bool RS485_DataAvailable(
|
||||
}
|
||||
|
||||
#ifdef TEST_RS485
|
||||
int main(
|
||||
void)
|
||||
int main(void)
|
||||
{
|
||||
unsigned i = 0;
|
||||
uint8_t DataRegister;
|
||||
|
||||
+40
-38
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
|
||||
@@ -33,12 +33,10 @@ extern uint8_t __stack;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define STACK_CANARY (0xC5)
|
||||
void stack_init(
|
||||
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
|
||||
void stack_init(void) __attribute__((naked)) __attribute__((section(".init1")));
|
||||
#endif
|
||||
|
||||
void stack_init(
|
||||
void)
|
||||
void stack_init(void)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if 0
|
||||
@@ -49,17 +47,23 @@ void stack_init(
|
||||
p++;
|
||||
}
|
||||
#else
|
||||
__asm volatile (
|
||||
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
|
||||
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
|
||||
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
|
||||
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
|
||||
__asm volatile(" ldi r30,lo8(_end)\n"
|
||||
" ldi r31,hi8(_end)\n"
|
||||
" ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
|
||||
" ldi r25,hi8(__stack)\n"
|
||||
" rjmp .cmp\n"
|
||||
".loop:\n"
|
||||
" st Z+,r24\n"
|
||||
".cmp:\n"
|
||||
" cpi r30,lo8(__stack)\n"
|
||||
" cpc r31,r25\n"
|
||||
" brlo .loop\n"
|
||||
" breq .loop" ::);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned stack_size(
|
||||
void)
|
||||
unsigned stack_size(void)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
return (&__stack) - (&_end);
|
||||
@@ -68,8 +72,7 @@ unsigned stack_size(
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t stack_byte(
|
||||
unsigned offset)
|
||||
uint8_t stack_byte(unsigned offset)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
return *(&_end + offset);
|
||||
@@ -79,8 +82,7 @@ uint8_t stack_byte(
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned stack_unused(
|
||||
void)
|
||||
unsigned stack_unused(void)
|
||||
{
|
||||
unsigned count = 0;
|
||||
#if defined(__GNUC__)
|
||||
|
||||
+28
-31
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
|
||||
@@ -30,19 +30,18 @@
|
||||
/* Prescaling: 1, 8, 64, 256, 1024 */
|
||||
#define TIMER_PRESCALER 64
|
||||
/* Count: Timer0 counts up to 0xFF and then signals overflow */
|
||||
#define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000)
|
||||
#define TIMER_TICKS (F_CPU / TIMER_PRESCALER / 1000)
|
||||
#if (TIMER_TICKS > 0xFF)
|
||||
#error Timer Prescaler value is too small
|
||||
#endif
|
||||
#define TIMER_COUNT (0xFF-TIMER_TICKS)
|
||||
#define TIMER_COUNT (0xFF - TIMER_TICKS)
|
||||
/* Global variable millisecond timer - used by main.c for timers task */
|
||||
volatile uint8_t Timer_Milliseconds = 0;
|
||||
/* MS/TP Silence Timer */
|
||||
static volatile uint16_t SilenceTime;
|
||||
|
||||
/* Configure the Timer */
|
||||
void Timer_Initialize(
|
||||
void)
|
||||
void Timer_Initialize(void)
|
||||
{
|
||||
/* Normal Operation */
|
||||
TCCR1A = 0;
|
||||
@@ -84,8 +83,7 @@ ISR(TIMER0_OVF_vect)
|
||||
}
|
||||
|
||||
/* Public access to the Silence Timer */
|
||||
uint16_t Timer_Silence(
|
||||
void)
|
||||
uint16_t Timer_Silence(void)
|
||||
{
|
||||
uint16_t timer;
|
||||
|
||||
@@ -97,8 +95,7 @@ uint16_t Timer_Silence(
|
||||
}
|
||||
|
||||
/* Public reset of the Silence Timer */
|
||||
void Timer_Silence_Reset(
|
||||
void)
|
||||
void Timer_Silence_Reset(void)
|
||||
{
|
||||
BIT_CLEAR(TIMSK0, TOIE0);
|
||||
SilenceTime = 0;
|
||||
|
||||
Reference in New Issue
Block a user