Reducing the memory required by ATmega168 port.
This commit is contained in:
@@ -22,16 +22,16 @@ CSRC = main.c \
|
||||
timer.c \
|
||||
rs485.c \
|
||||
dlmstp.c \
|
||||
apdu.c \
|
||||
$(BACNET_CORE)/crc.c
|
||||
|
||||
DEMOSRC = h_rp.c \
|
||||
h_wp.c \
|
||||
device.c \
|
||||
ai.c \
|
||||
$(BACNET_DEMO)/handler/txbuf.c \
|
||||
$(BACNET_DEMO)/handler/h_whois.c \
|
||||
$(BACNET_DEMO)/handler/h_rd.c \
|
||||
$(BACNET_DEMO)/handler/h_dcc.c
|
||||
$(BACNET_DEMO)/handler/noserv.c \
|
||||
h_whois.c
|
||||
# h_wp.c \
|
||||
|
||||
CORESRC = \
|
||||
$(BACNET_CORE)/apdu.c \
|
||||
@@ -42,36 +42,37 @@ CORESRC = \
|
||||
$(BACNET_CORE)/bacdcode/bitstring.c \
|
||||
$(BACNET_CORE)/bacdcode/octetstring.c \
|
||||
$(BACNET_CORE)/bacdcode/characterstring.c \
|
||||
$(BACNET_CORE)/bacapp.c \
|
||||
$(BACNET_CORE)/bacprop.c \
|
||||
$(BACNET_CORE)/bactext.c \
|
||||
$(BACNET_CORE)/datetime.c \
|
||||
$(BACNET_CORE)/indtext.c \
|
||||
$(BACNET_CORE)/bigend.c \
|
||||
$(BACNET_CORE)/arf.c \
|
||||
$(BACNET_CORE)/awf.c \
|
||||
$(BACNET_CORE)/cov.c \
|
||||
$(BACNET_CORE)/dcc.c \
|
||||
$(BACNET_CORE)/iam/iam_client.c \
|
||||
$(BACNET_CORE)/iam/iam_server.c \
|
||||
$(BACNET_CORE)/iam/iam_send.c \
|
||||
$(BACNET_CORE)/ihave.c \
|
||||
$(BACNET_CORE)/rd.c \
|
||||
$(BACNET_CORE)/rp.c \
|
||||
$(BACNET_CORE)/rpm.c \
|
||||
$(BACNET_CORE)/timesync.c \
|
||||
$(BACNET_CORE)/whohas.c \
|
||||
$(BACNET_CORE)/whois.c \
|
||||
$(BACNET_CORE)/wp.c \
|
||||
$(BACNET_CORE)/bacaddr.c \
|
||||
$(BACNET_CORE)/abort.c \
|
||||
$(BACNET_CORE)/reject.c \
|
||||
$(BACNET_CORE)/bacerror.c \
|
||||
$(BACNET_CORE)/filename.c \
|
||||
$(BACNET_CORE)/tsm.c \
|
||||
$(BACNET_CORE)/bacaddr.c \
|
||||
$(BACNET_CORE)/address.c \
|
||||
$(BACNET_CORE)/version.c
|
||||
|
||||
# $(BACNET_CORE)/bacapp.c \
|
||||
# $(BACNET_CORE)/bacprop.c \
|
||||
# $(BACNET_CORE)/bactext.c \
|
||||
# $(BACNET_CORE)/datetime.c \
|
||||
# $(BACNET_CORE)/indtext.c \
|
||||
# $(BACNET_CORE)/bigend.c \
|
||||
# $(BACNET_CORE)/arf.c \
|
||||
# $(BACNET_CORE)/awf.c \
|
||||
# $(BACNET_CORE)/cov.c \
|
||||
# $(BACNET_CORE)/dcc.c \
|
||||
# $(BACNET_CORE)/iam/iam_client.c \
|
||||
# $(BACNET_CORE)/ihave.c \
|
||||
# $(BACNET_CORE)/rd.c \
|
||||
# $(BACNET_CORE)/rpm.c \
|
||||
# $(BACNET_CORE)/timesync.c \
|
||||
# $(BACNET_CORE)/whohas.c \
|
||||
# $(BACNET_CORE)/wp.c \
|
||||
# $(BACNET_CORE)/filename.c \
|
||||
# $(BACNET_CORE)/tsm.c \
|
||||
# $(BACNET_CORE)/address.c \
|
||||
|
||||
## Include Directories
|
||||
INCLUDES = -I. -I$(BACNET_INCLUDE)
|
||||
|
||||
@@ -116,8 +117,8 @@ HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
|
||||
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
|
||||
|
||||
## Objects that must be built in order to link
|
||||
#OBJECTS = $(COBJ) $(DEMOOBJ)
|
||||
OBJECTS = $(COBJ)
|
||||
OBJECTS = $(COBJ) $(DEMOOBJ)
|
||||
#OBJECTS = $(COBJ)
|
||||
|
||||
## Build
|
||||
TARGET_ELF=$(TARGET).elf
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2005 Steve Karg
|
||||
Copyright (C) 2007 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@@ -39,212 +39,19 @@
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "tsm.h"
|
||||
#include "dcc.h"
|
||||
#include "iam.h"
|
||||
|
||||
/* a simple table for crossing the services supported */
|
||||
static BACNET_SERVICES_SUPPORTED
|
||||
confirmed_service_supported[MAX_BACNET_CONFIRMED_SERVICE] = {
|
||||
SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM,
|
||||
SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION,
|
||||
SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION,
|
||||
SERVICE_SUPPORTED_GET_ALARM_SUMMARY,
|
||||
SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY,
|
||||
SERVICE_SUPPORTED_SUBSCRIBE_COV,
|
||||
SERVICE_SUPPORTED_ATOMIC_READ_FILE,
|
||||
SERVICE_SUPPORTED_ATOMIC_WRITE_FILE,
|
||||
SERVICE_SUPPORTED_ADD_LIST_ELEMENT,
|
||||
SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT,
|
||||
SERVICE_SUPPORTED_CREATE_OBJECT,
|
||||
SERVICE_SUPPORTED_DELETE_OBJECT,
|
||||
SERVICE_SUPPORTED_READ_PROPERTY,
|
||||
SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL,
|
||||
SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE,
|
||||
SERVICE_SUPPORTED_WRITE_PROPERTY,
|
||||
SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE,
|
||||
SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL,
|
||||
SERVICE_SUPPORTED_PRIVATE_TRANSFER,
|
||||
SERVICE_SUPPORTED_TEXT_MESSAGE,
|
||||
SERVICE_SUPPORTED_REINITIALIZE_DEVICE,
|
||||
SERVICE_SUPPORTED_VT_OPEN,
|
||||
SERVICE_SUPPORTED_VT_CLOSE,
|
||||
SERVICE_SUPPORTED_VT_DATA,
|
||||
SERVICE_SUPPORTED_AUTHENTICATE,
|
||||
SERVICE_SUPPORTED_REQUEST_KEY,
|
||||
SERVICE_SUPPORTED_READ_RANGE,
|
||||
SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION,
|
||||
SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY,
|
||||
SERVICE_SUPPORTED_GET_EVENT_INFORMATION
|
||||
};
|
||||
|
||||
/* a simple table for crossing the services supported */
|
||||
static BACNET_SERVICES_SUPPORTED
|
||||
unconfirmed_service_supported[MAX_BACNET_UNCONFIRMED_SERVICE] = {
|
||||
SERVICE_SUPPORTED_I_AM,
|
||||
SERVICE_SUPPORTED_I_HAVE,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE,
|
||||
SERVICE_SUPPORTED_TIME_SYNCHRONIZATION,
|
||||
SERVICE_SUPPORTED_WHO_HAS,
|
||||
SERVICE_SUPPORTED_WHO_IS,
|
||||
SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION
|
||||
};
|
||||
|
||||
/* Confirmed Function Handlers */
|
||||
/* If they are not set, they are handled by a reject message */
|
||||
static confirmed_function Confirmed_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
||||
|
||||
void apdu_set_confirmed_handler(BACNET_CONFIRMED_SERVICE service_choice,
|
||||
confirmed_function pFunction)
|
||||
{
|
||||
if (service_choice < MAX_BACNET_CONFIRMED_SERVICE)
|
||||
Confirmed_Function[service_choice] = pFunction;
|
||||
}
|
||||
|
||||
/* Allow the APDU handler to automatically reject */
|
||||
static confirmed_function Unrecognized_Service_Handler;
|
||||
|
||||
void apdu_set_unrecognized_service_handler_handler(confirmed_function
|
||||
pFunction)
|
||||
{
|
||||
Unrecognized_Service_Handler = pFunction;
|
||||
}
|
||||
|
||||
/* Unconfirmed Function Handlers */
|
||||
/* If they are not set, they are not handled */
|
||||
static unconfirmed_function
|
||||
Unconfirmed_Function[MAX_BACNET_UNCONFIRMED_SERVICE] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
void apdu_set_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE
|
||||
service_choice, unconfirmed_function pFunction)
|
||||
{
|
||||
if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE)
|
||||
Unconfirmed_Function[service_choice] = pFunction;
|
||||
}
|
||||
#include "handlers.h"
|
||||
|
||||
bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
|
||||
{
|
||||
int i = 0;
|
||||
bool status = false;
|
||||
bool found = false;
|
||||
|
||||
if (service_supported < MAX_BACNET_SERVICES_SUPPORTED) {
|
||||
/* is it a confirmed service? */
|
||||
for (i = 0; i < MAX_BACNET_CONFIRMED_SERVICE; i++) {
|
||||
if (confirmed_service_supported[i] == service_supported) {
|
||||
if (Confirmed_Function[i] != NULL)
|
||||
status = true;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
/* is it an unconfirmed service? */
|
||||
for (i = 0; i < MAX_BACNET_UNCONFIRMED_SERVICE; i++) {
|
||||
if (unconfirmed_service_supported[i] == service_supported) {
|
||||
if (Unconfirmed_Function[i] != NULL)
|
||||
status = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) {
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Confirmed ACK Function Handlers */
|
||||
static void *Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
||||
|
||||
void apdu_set_confirmed_simple_ack_handler(BACNET_CONFIRMED_SERVICE
|
||||
service_choice, confirmed_simple_ack_function pFunction)
|
||||
{
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM:
|
||||
case SERVICE_CONFIRMED_COV_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_EVENT_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY:
|
||||
case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_ADD_LIST_ELEMENT:
|
||||
case SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT:
|
||||
case SERVICE_CONFIRMED_DELETE_OBJECT:
|
||||
case SERVICE_CONFIRMED_WRITE_PROPERTY:
|
||||
case SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE:
|
||||
/* Remote Device Management Services */
|
||||
case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL:
|
||||
case SERVICE_CONFIRMED_TEXT_MESSAGE:
|
||||
case SERVICE_CONFIRMED_REINITIALIZE_DEVICE:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_CLOSE:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_REQUEST_KEY:
|
||||
Confirmed_ACK_Function[service_choice] = (void *) pFunction;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void apdu_set_confirmed_ack_handler(BACNET_CONFIRMED_SERVICE
|
||||
service_choice, confirmed_ack_function pFunction)
|
||||
{
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_GET_ALARM_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_EVENT_INFORMATION:
|
||||
/* File Access Services */
|
||||
case SERVICE_CONFIRMED_ATOMIC_READ_FILE:
|
||||
case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_CREATE_OBJECT:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE:
|
||||
case SERVICE_CONFIRMED_READ_RANGE:
|
||||
/* Remote Device Management Services */
|
||||
case SERVICE_CONFIRMED_PRIVATE_TRANSFER:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_OPEN:
|
||||
case SERVICE_CONFIRMED_VT_DATA:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_AUTHENTICATE:
|
||||
Confirmed_ACK_Function[service_choice] = (void *) pFunction;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static error_function Error_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
||||
|
||||
void apdu_set_error_handler(BACNET_CONFIRMED_SERVICE service_choice,
|
||||
error_function pFunction)
|
||||
{
|
||||
if (service_choice < MAX_BACNET_CONFIRMED_SERVICE)
|
||||
Error_Function[service_choice] = pFunction;
|
||||
}
|
||||
|
||||
static abort_function Abort_Function;
|
||||
|
||||
void apdu_set_abort_handler(abort_function pFunction)
|
||||
{
|
||||
Abort_Function = pFunction;
|
||||
}
|
||||
|
||||
static reject_function Reject_Function;
|
||||
|
||||
void apdu_set_reject_handler(reject_function pFunction)
|
||||
{
|
||||
Reject_Function = pFunction;
|
||||
}
|
||||
|
||||
uint16_t apdu_decode_confirmed_service_request(uint8_t * apdu, /* APDU data */
|
||||
uint16_t apdu_len,
|
||||
BACNET_CONFIRMED_SERVICE_DATA * service_data,
|
||||
@@ -276,18 +83,10 @@ void apdu_handler(BACNET_ADDRESS * src, uint8_t * apdu, /* APDU data */
|
||||
uint16_t apdu_len)
|
||||
{
|
||||
BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 };
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA service_ack_data = { 0 };
|
||||
uint8_t invoke_id = 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 */
|
||||
uint8_t tag_number = 0;
|
||||
uint32_t len_value = 0;
|
||||
int error_code = 0;
|
||||
int error_class = 0;
|
||||
uint8_t reason = 0;
|
||||
bool server = false;
|
||||
|
||||
if (apdu) {
|
||||
/* PDU Type */
|
||||
@@ -297,158 +96,29 @@ void apdu_handler(BACNET_ADDRESS * src, uint8_t * apdu, /* APDU data */
|
||||
apdu_len,
|
||||
&service_data,
|
||||
&service_choice, &service_request, &service_request_len);
|
||||
/* When network communications are completely disabled,
|
||||
only DeviceCommunicationControl and ReinitializeDevice APDUs
|
||||
shall be processed and no messages shall be initiated. */
|
||||
if (dcc_communication_disabled() &&
|
||||
((service_choice !=
|
||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL)
|
||||
&& (service_choice !=
|
||||
SERVICE_CONFIRMED_REINITIALIZE_DEVICE)))
|
||||
break;
|
||||
if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) &&
|
||||
(Confirmed_Function[service_choice]))
|
||||
Confirmed_Function[service_choice] (service_request,
|
||||
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
|
||||
handler_read_property(service_request,
|
||||
service_request_len, src, &service_data);
|
||||
else if (Unrecognized_Service_Handler)
|
||||
Unrecognized_Service_Handler(service_request,
|
||||
} else {
|
||||
handler_unrecognized_service(service_request,
|
||||
service_request_len, src, &service_data);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
|
||||
if (dcc_communication_disabled())
|
||||
break;
|
||||
service_choice = apdu[1];
|
||||
service_request = &apdu[2];
|
||||
service_request_len = apdu_len - 2;
|
||||
if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) {
|
||||
if (Unconfirmed_Function[service_choice])
|
||||
Unconfirmed_Function[service_choice] (service_request,
|
||||
if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) {
|
||||
handler_who_is(service_request,
|
||||
service_request_len, src);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_SIMPLE_ACK:
|
||||
invoke_id = apdu[1];
|
||||
service_choice = apdu[2];
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM:
|
||||
case SERVICE_CONFIRMED_COV_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_EVENT_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY:
|
||||
case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_ADD_LIST_ELEMENT:
|
||||
case SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT:
|
||||
case SERVICE_CONFIRMED_DELETE_OBJECT:
|
||||
case SERVICE_CONFIRMED_WRITE_PROPERTY:
|
||||
case SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE:
|
||||
/* Remote Device Management Services */
|
||||
case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL:
|
||||
case SERVICE_CONFIRMED_REINITIALIZE_DEVICE:
|
||||
case SERVICE_CONFIRMED_TEXT_MESSAGE:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_CLOSE:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_REQUEST_KEY:
|
||||
if (Confirmed_ACK_Function[service_choice]) {
|
||||
((confirmed_simple_ack_function)
|
||||
Confirmed_ACK_Function[service_choice]) (src,
|
||||
invoke_id);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_COMPLEX_ACK:
|
||||
service_ack_data.segmented_message =
|
||||
(apdu[0] & BIT3) ? true : false;
|
||||
service_ack_data.more_follows =
|
||||
(apdu[0] & BIT2) ? true : false;
|
||||
invoke_id = service_ack_data.invoke_id = apdu[1];
|
||||
len = 2;
|
||||
if (service_ack_data.segmented_message) {
|
||||
service_ack_data.sequence_number = apdu[len++];
|
||||
service_ack_data.proposed_window_number = apdu[len++];
|
||||
}
|
||||
service_choice = apdu[len++];
|
||||
service_request = &apdu[len];
|
||||
service_request_len = apdu_len - len;
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_GET_ALARM_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_EVENT_INFORMATION:
|
||||
/* File Access Services */
|
||||
case SERVICE_CONFIRMED_ATOMIC_READ_FILE:
|
||||
case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_CREATE_OBJECT:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE:
|
||||
case SERVICE_CONFIRMED_READ_RANGE:
|
||||
case SERVICE_CONFIRMED_PRIVATE_TRANSFER:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_OPEN:
|
||||
case SERVICE_CONFIRMED_VT_DATA:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_AUTHENTICATE:
|
||||
if (Confirmed_ACK_Function[service_choice]) {
|
||||
((confirmed_ack_function)
|
||||
Confirmed_ACK_Function[service_choice])
|
||||
(service_request, service_request_len, src,
|
||||
&service_ack_data);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_SEGMENT_ACK:
|
||||
/* FIXME: what about a denial of service attack here?
|
||||
we could check src to see if that matched the tsm */
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
case PDU_TYPE_ERROR:
|
||||
invoke_id = apdu[1];
|
||||
service_choice = apdu[2];
|
||||
len = 3;
|
||||
len +=
|
||||
decode_tag_number_and_value(&apdu[len], &tag_number,
|
||||
&len_value);
|
||||
/* FIXME: we could validate that the tag is enumerated... */
|
||||
len += decode_enumerated(&apdu[len], len_value, &error_class);
|
||||
len +=
|
||||
decode_tag_number_and_value(&apdu[len], &tag_number,
|
||||
&len_value);
|
||||
/* FIXME: we could validate that the tag is enumerated... */
|
||||
len += decode_enumerated(&apdu[len], len_value, &error_code);
|
||||
if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) {
|
||||
if (Error_Function[service_choice])
|
||||
Error_Function[service_choice] (src,
|
||||
invoke_id,
|
||||
(BACNET_ERROR_CLASS)error_class,
|
||||
(BACNET_ERROR_CODE)error_code);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
case PDU_TYPE_REJECT:
|
||||
invoke_id = apdu[1];
|
||||
reason = apdu[2];
|
||||
if (Reject_Function)
|
||||
Reject_Function(src, invoke_id, reason);
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
case PDU_TYPE_ABORT:
|
||||
server = apdu[0] & 0x01;
|
||||
invoke_id = apdu[1];
|
||||
reason = apdu[2];
|
||||
if (Abort_Function)
|
||||
Abort_Function(src, invoke_id, reason, server);
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -53,19 +53,10 @@ static uint32_t Object_Instance_Number = 12345;
|
||||
static char Object_Name[32] = "ATmega Device";
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
|
||||
BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State =
|
||||
REINITIALIZED_STATE_IDLE;
|
||||
|
||||
void Device_Reinit(void)
|
||||
{
|
||||
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
|
||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||
}
|
||||
|
||||
void Device_Init(void)
|
||||
{
|
||||
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
||||
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
|
||||
/* Reinitialize_State = REINITIALIZED_STATE_IDLE; */
|
||||
/* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */
|
||||
/* FIXME: Get the data from the eeprom */
|
||||
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
||||
(char *)&Object_Instance_Number,
|
||||
@@ -79,6 +70,7 @@ uint32_t Device_Object_Instance_Number(void)
|
||||
return Object_Instance_Number;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
bool status = true; /* return value */
|
||||
@@ -96,6 +88,7 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
@@ -104,17 +97,6 @@ bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
||||
(object_id == BACNET_MAX_INSTANCE));
|
||||
}
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(void)
|
||||
{
|
||||
return System_Status;
|
||||
}
|
||||
|
||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status)
|
||||
{
|
||||
if (status < MAX_DEVICE_STATUS)
|
||||
System_Status = status;
|
||||
}
|
||||
|
||||
uint16_t Device_Vendor_Identifier(void)
|
||||
{
|
||||
return BACNET_VENDOR_ID;
|
||||
@@ -280,7 +262,7 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
||||
break;
|
||||
case PROP_SYSTEM_STATUS:
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], Device_System_Status());
|
||||
encode_application_enumerated(&apdu[0], System_Status);
|
||||
break;
|
||||
case PROP_VENDOR_NAME:
|
||||
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
|
||||
@@ -460,6 +442,7 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
|
||||
{
|
||||
@@ -574,3 +557,4 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
@@ -66,8 +66,7 @@ int Encode_Property_APDU(
|
||||
/* handle each object type */
|
||||
switch(object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if ((object_instance == Device_Object_Instance_Number()) ||
|
||||
(object_instance == BACNET_MAX_INSTANCE)) {
|
||||
if (Device_Valid_Object_Instance_Number(object_instance)) {
|
||||
apdu_len = Device_Encode_Property_APDU(
|
||||
&apdu[0],
|
||||
property,
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "client.h"
|
||||
#include "txbuf.h"
|
||||
|
||||
bool Send_I_Am = true;
|
||||
|
||||
void handler_who_is(uint8_t * service_request,
|
||||
uint16_t service_len, BACNET_ADDRESS * src)
|
||||
{
|
||||
@@ -56,8 +58,9 @@ void handler_who_is(uint8_t * service_request,
|
||||
||
|
||||
/* BACnet wildcard is the max instance number - everyone responds */
|
||||
((BACNET_MAX_INSTANCE >= (uint32_t) low_limit) &&
|
||||
(BACNET_MAX_INSTANCE <= (uint32_t) high_limit)))
|
||||
iam_send(&Handler_Transmit_Buffer[0]);
|
||||
(BACNET_MAX_INSTANCE <= (uint32_t) high_limit))) {
|
||||
Send_I_Am = true;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2005 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
this file and link it with other works to produce a work based
|
||||
on this file, this file does not by itself cause the resulting
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
#include <stdint.h>
|
||||
#include "bacenum.h"
|
||||
#include "bacdef.h"
|
||||
#include "npdu.h"
|
||||
#include "dcc.h"
|
||||
#include "datalink.h"
|
||||
#include "device.h"
|
||||
#include "bacdcode.h"
|
||||
#include "address.h"
|
||||
#include "iam.h"
|
||||
|
||||
int iam_send(uint8_t * buffer)
|
||||
{
|
||||
int len = 0;
|
||||
int pdu_len = 0;
|
||||
BACNET_ADDRESS dest;
|
||||
int bytes_sent = 0;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
|
||||
/* if we are forbidden to send, don't send! */
|
||||
if (!dcc_communication_enabled())
|
||||
return 0;
|
||||
|
||||
/* I-Am is a global broadcast */
|
||||
datalink_get_broadcast_address(&dest);
|
||||
/* encode the NPDU portion of the packet */
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
pdu_len = npdu_encode_pdu(&buffer[0], &dest, NULL, &npdu_data);
|
||||
/* encode the APDU portion of the packet */
|
||||
len = iam_encode_apdu(&buffer[pdu_len],
|
||||
Device_Object_Instance_Number(),
|
||||
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier());
|
||||
pdu_len += len;
|
||||
/* send data */
|
||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
@@ -36,12 +36,13 @@
|
||||
/* For porting to IAR, see:
|
||||
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
|
||||
|
||||
/* Notice: Fuse Bit Settings
|
||||
|
||||
|
||||
|
||||
*/
|
||||
/* broadcast an I-Am on startup */
|
||||
extern bool Send_I_Am;
|
||||
|
||||
/* dummy function */
|
||||
bool dcc_communication_enabled(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void init(void)
|
||||
{
|
||||
@@ -143,17 +144,6 @@ void input_switch_read(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TEST_MSTP)
|
||||
void apdu_handler(BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * apdu, /* APDU data */
|
||||
uint16_t pdu_len) /* for confirmed messages */
|
||||
{
|
||||
(void)src;
|
||||
(void)apdu;
|
||||
(void)pdu_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t PDUBuffer[MAX_MPDU];
|
||||
int main(void)
|
||||
{
|
||||
@@ -167,11 +157,9 @@ int main(void)
|
||||
dlmstp_set_max_info_frames(1);
|
||||
#endif
|
||||
datalink_init(NULL);
|
||||
/* broadcast an I-Am on startup */
|
||||
#if !defined(TEST_MSTP)
|
||||
iam_send(&Handler_Transmit_Buffer[0]);
|
||||
#endif
|
||||
for (;;) {
|
||||
if (Send_I_Am)
|
||||
iam_send(&Handler_Transmit_Buffer[0]);
|
||||
input_switch_read();
|
||||
task_milliseconds();
|
||||
/* other tasks */
|
||||
|
||||
@@ -43,18 +43,6 @@ static uint8_t LED3_Off_Timer;
|
||||
|
||||
/* baud rate */
|
||||
static uint32_t RS485_Baud = 9600;
|
||||
/* autobaud - switch baud on errors if autobaud is true */
|
||||
static bool RS485_Autobaud = true;
|
||||
/* we saw some data, so we are on an active wire */
|
||||
static uint8_t RS485_Data_Count;
|
||||
/* count of errors before autobaud switching */
|
||||
static uint8_t RS485_Error_Count;
|
||||
/* time limit */
|
||||
#define RS485_ERROR_TIMEOUT 1000
|
||||
/* millisecond timer to limit error window */
|
||||
static uint16_t RS485_Error_Timer = RS485_ERROR_TIMEOUT;
|
||||
/* number of errors in 1000ms before autobaud switching */
|
||||
#define RS485_ERROR_LIMIT 30
|
||||
|
||||
/* The minimum time after the end of the stop bit of the final octet of a */
|
||||
/* received frame before a node may enable its EIA-485 driver: 40 bit times. */
|
||||
@@ -153,34 +141,6 @@ bool RS485_Set_Baud_Rate(uint32_t baud)
|
||||
return valid;
|
||||
}
|
||||
|
||||
void RS485_Next_Baud_Rate(void)
|
||||
{
|
||||
uint32_t baud;
|
||||
|
||||
switch (RS485_Baud) {
|
||||
case 9600:
|
||||
baud = 19200;
|
||||
break;
|
||||
case 19200:
|
||||
baud = 38400;
|
||||
break;
|
||||
case 38400:
|
||||
baud = 57600;
|
||||
break;
|
||||
case 57600:
|
||||
baud = 76800;
|
||||
break;
|
||||
case 76800:
|
||||
baud = 115200;
|
||||
break;
|
||||
case 115200:
|
||||
default:
|
||||
baud = 9600;
|
||||
break;
|
||||
}
|
||||
RS485_Set_Baud_Rate(baud);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Waits on the SilenceTimer for 40 bits.
|
||||
* RETURN: none
|
||||
@@ -241,9 +201,6 @@ void RS485_LED_Timers(void)
|
||||
BIT_SET(PORTD,PD7);
|
||||
}
|
||||
}
|
||||
if (RS485_Error_Timer) {
|
||||
RS485_Error_Timer--;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -328,34 +285,6 @@ bool RS485_ReceiveError(void)
|
||||
do {
|
||||
dummy_data = UDR0;
|
||||
} while (BIT_CHECK(UCSR0A,RXC0));
|
||||
/* count errors during autobaud */
|
||||
if (RS485_Error_Count < RS485_ERROR_LIMIT) {
|
||||
RS485_Error_Count++;
|
||||
} else {
|
||||
if (RS485_Autobaud && RS485_Error_Timer) {
|
||||
/* We are in autobaud mode, and there were excessive
|
||||
errors while the timer was counting down */
|
||||
RS485_Next_Baud_Rate();
|
||||
RS485_Error_Timer = RS485_ERROR_TIMEOUT;
|
||||
RS485_Error_Count = 0;
|
||||
} else if (RS485_Autobaud) {
|
||||
/* autobaud, but timer expired */
|
||||
RS485_Autobaud = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (RS485_Autobaud) {
|
||||
if ((RS485_Error_Timer == 0) && (RS485_Error_Count == 0)) {
|
||||
if (RS485_Data_Count > 8) {
|
||||
/* no errors, timer expired, and we saw data */
|
||||
RS485_Autobaud = false;
|
||||
} else {
|
||||
/* no errors, timer expired, and no data*/
|
||||
RS485_Error_Timer = RS485_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ReceiveError;
|
||||
@@ -376,8 +305,6 @@ bool RS485_DataAvailable(uint8_t *data)
|
||||
*data = UDR0;
|
||||
DataAvailable = true;
|
||||
RS485_LED1_On();
|
||||
if (RS485_Data_Count < 0xFF)
|
||||
RS485_Data_Count++;
|
||||
}
|
||||
|
||||
return DataAvailable;
|
||||
|
||||
Reference in New Issue
Block a user