fixed svn EOL and MIME settings.

This commit is contained in:
skarg
2012-04-06 23:24:43 +00:00
parent 62eea57d4b
commit d1f4e78cba
57 changed files with 11387 additions and 11363 deletions
+9 -1
View File
@@ -9,10 +9,18 @@ TARGET = bacgateway
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c
SRCS = main.c \
$(BACNET_OBJECT)/gw_device.c \
${CORE_SRC} \
${PORT_SRC} \
${HANDLER_SRC} \
${OBJECT_SRC} \
${ROUTING_SRC}
OBJS = ${SRCS:.c=.o}
DEFINES += -DBAC_ROUTING
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
+173 -173
View File
@@ -1,173 +1,173 @@
/**************************************************************************
*
* Copyright (C) 2011 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>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "apdu.h"
#include "npdu.h"
#include "abort.h"
/* special for this module */
#include "cov.h"
#include "bactext.h"
#include "handlers.h"
#ifndef MAX_COV_PROPERTIES
#define MAX_COV_PROPERTIES 2
#endif
/** @file h_ccov.c Handles Confirmed COV Notifications. */
/* */
/** Handler for an Confirmed COV Notification.
* @ingroup DSCOV
* Decodes the received list of Properties to update,
* and print them out with the subscription information.
* @note Nothing is specified in BACnet about what to do with the
* information received from Confirmed COV Notifications.
*
* @param service_request [in] The contents of the service request.
* @param service_len [in] The length of the service_request.
* @param src [in] BACNET_ADDRESS of the source of the message
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_ccov_notification(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_NPDU_DATA npdu_data;
BACNET_COV_DATA cov_data;
BACNET_PROPERTY_VALUE property_value[MAX_COV_PROPERTIES];
BACNET_PROPERTY_VALUE *pProperty_value = NULL;
unsigned index = 0;
int len = 0;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_ADDRESS my_address;
/* create linked list to store data if more
than one property value is expected */
pProperty_value = &property_value[0];
while (pProperty_value) {
index++;
if (index < MAX_COV_PROPERTIES) {
pProperty_value->next = &property_value[index];
} else {
pProperty_value->next = NULL;
}
pProperty_value = pProperty_value->next;
}
cov_data.listOfValues = &property_value[0];
/* 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);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Received Notification!\n");
#endif
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n");
#endif
goto CCOV_ABORT;
} /* decode the service request only */
/* decode the service request only */
len =
cov_notify_decode_service_request(service_request, service_len,
&cov_data);
#if PRINT_ENABLED
if (len > 0) {
fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
fprintf(stderr, "%s %u ",
bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
cov_data.monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
fprintf(stderr, "\n");
pProperty_value = &property_value[0];
while (pProperty_value) {
fprintf(stderr, "CCOV: ");
if (pProperty_value->propertyIdentifier < 512) {
fprintf(stderr, "%s ",
bactext_property_name
(pProperty_value->propertyIdentifier));
} else {
fprintf(stderr, "proprietary %u ",
pProperty_value->propertyIdentifier);
}
if (pProperty_value->propertyArrayIndex != BACNET_ARRAY_ALL) {
fprintf(stderr, "%u ", pProperty_value->propertyArrayIndex);
}
fprintf(stderr, "\n");
pProperty_value = pProperty_value->next;
}
}
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len <= 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n");
#endif
goto CCOV_ABORT;
} else {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_COV_NOTIFICATION);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Sending Simple Ack!\n");
#endif
}
CCOV_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
fprintf(stderr, "CCOV: Failed to send PDU (%s)!\n", strerror(errno));
}
#else
bytes_sent = bytes_sent;
#endif
return;
}
/**************************************************************************
*
* Copyright (C) 2011 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>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "apdu.h"
#include "npdu.h"
#include "abort.h"
/* special for this module */
#include "cov.h"
#include "bactext.h"
#include "handlers.h"
#ifndef MAX_COV_PROPERTIES
#define MAX_COV_PROPERTIES 2
#endif
/** @file h_ccov.c Handles Confirmed COV Notifications. */
/* */
/** Handler for an Confirmed COV Notification.
* @ingroup DSCOV
* Decodes the received list of Properties to update,
* and print them out with the subscription information.
* @note Nothing is specified in BACnet about what to do with the
* information received from Confirmed COV Notifications.
*
* @param service_request [in] The contents of the service request.
* @param service_len [in] The length of the service_request.
* @param src [in] BACNET_ADDRESS of the source of the message
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_ccov_notification(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_NPDU_DATA npdu_data;
BACNET_COV_DATA cov_data;
BACNET_PROPERTY_VALUE property_value[MAX_COV_PROPERTIES];
BACNET_PROPERTY_VALUE *pProperty_value = NULL;
unsigned index = 0;
int len = 0;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_ADDRESS my_address;
/* create linked list to store data if more
than one property value is expected */
pProperty_value = &property_value[0];
while (pProperty_value) {
index++;
if (index < MAX_COV_PROPERTIES) {
pProperty_value->next = &property_value[index];
} else {
pProperty_value->next = NULL;
}
pProperty_value = pProperty_value->next;
}
cov_data.listOfValues = &property_value[0];
/* 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);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Received Notification!\n");
#endif
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n");
#endif
goto CCOV_ABORT;
} /* decode the service request only */
/* decode the service request only */
len =
cov_notify_decode_service_request(service_request, service_len,
&cov_data);
#if PRINT_ENABLED
if (len > 0) {
fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
fprintf(stderr, "%s %u ",
bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
cov_data.monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
fprintf(stderr, "\n");
pProperty_value = &property_value[0];
while (pProperty_value) {
fprintf(stderr, "CCOV: ");
if (pProperty_value->propertyIdentifier < 512) {
fprintf(stderr, "%s ",
bactext_property_name
(pProperty_value->propertyIdentifier));
} else {
fprintf(stderr, "proprietary %u ",
pProperty_value->propertyIdentifier);
}
if (pProperty_value->propertyArrayIndex != BACNET_ARRAY_ALL) {
fprintf(stderr, "%u ", pProperty_value->propertyArrayIndex);
}
fprintf(stderr, "\n");
pProperty_value = pProperty_value->next;
}
}
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len <= 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n");
#endif
goto CCOV_ABORT;
} else {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_COV_NOTIFICATION);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Sending Simple Ack!\n");
#endif
}
CCOV_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
fprintf(stderr, "CCOV: Failed to send PDU (%s)!\n", strerror(errno));
}
#else
bytes_sent = bytes_sent;
#endif
return;
}
+158 -158
View File
@@ -1,158 +1,158 @@
/**************************************************************************
*
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* 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>
#include <string.h>
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "bacerror.h"
#include "apdu.h"
#include "npdu.h"
#include "abort.h"
#include "handlers.h"
/** @file h_alarm_sum.c Handles Get Alarm Summary request. */
static get_alarm_summary_function Get_Alarm_Summary[MAX_BACNET_OBJECT_TYPE];
void handler_get_alarm_summary_set(
BACNET_OBJECT_TYPE object_type,
get_alarm_summary_function pFunction)
{
if (object_type < MAX_BACNET_OBJECT_TYPE) {
Get_Alarm_Summary[object_type] = pFunction;
}
}
void handler_get_alarm_summary(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
int len = 0;
int pdu_len = 0;
int apdu_len = 0;
int bytes_sent = 0;
int alarm_value = 0;
unsigned i = 0;
unsigned j = 0;
bool error = false;
BACNET_ADDRESS my_address;
BACNET_NPDU_DATA npdu_data;
BACNET_GET_ALARM_SUMMARY_DATA getalarm_data;
/* 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);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
#if PRINT_ENABLED
fprintf(stderr,
"GetAlarmSummary: Segmented message. Sending Abort!\n");
#endif
goto GET_ALARM_SUMMARY_ABORT;
}
/* init header */
apdu_len = get_alarm_summary_ack_encode_apdu_init(
&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id);
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
if (Get_Alarm_Summary[i]) {
for (j = 0; j < 0xffff; j++) {
alarm_value = Get_Alarm_Summary[i] (j, &getalarm_data);
if (alarm_value > 0) {
len = get_alarm_sumary_ack_encode_apdu_data(
&Handler_Transmit_Buffer[pdu_len + apdu_len],
service_data->max_resp - apdu_len,
&getalarm_data);
if (len <= 0) {
error = true;
goto GET_ALARM_SUMMARY_ERROR;
}
else
apdu_len += len;
}
else if (alarm_value < 0) {
break;
}
}
}
}
#if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending response!\n");
#endif
GET_ALARM_SUMMARY_ERROR:
if (error) {
if (len == BACNET_STATUS_ABORT) {
/* BACnet APDU too small to fit data, so proper response is Abort */
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"GetAlarmSummary: Reply too big to fit into APDU!\n");
#endif
}
else {
apdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_GET_ALARM_SUMMARY,
ERROR_CLASS_PROPERTY, ERROR_CODE_OTHER);
#if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending Error!\n");
#endif
}
}
GET_ALARM_SUMMARY_ABORT:
pdu_len += apdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
return;
}
/**************************************************************************
*
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* 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>
#include <string.h>
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "bacerror.h"
#include "apdu.h"
#include "npdu.h"
#include "abort.h"
#include "handlers.h"
/** @file h_alarm_sum.c Handles Get Alarm Summary request. */
static get_alarm_summary_function Get_Alarm_Summary[MAX_BACNET_OBJECT_TYPE];
void handler_get_alarm_summary_set(
BACNET_OBJECT_TYPE object_type,
get_alarm_summary_function pFunction)
{
if (object_type < MAX_BACNET_OBJECT_TYPE) {
Get_Alarm_Summary[object_type] = pFunction;
}
}
void handler_get_alarm_summary(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
int len = 0;
int pdu_len = 0;
int apdu_len = 0;
int bytes_sent = 0;
int alarm_value = 0;
unsigned i = 0;
unsigned j = 0;
bool error = false;
BACNET_ADDRESS my_address;
BACNET_NPDU_DATA npdu_data;
BACNET_GET_ALARM_SUMMARY_DATA getalarm_data;
/* 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);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
#if PRINT_ENABLED
fprintf(stderr,
"GetAlarmSummary: Segmented message. Sending Abort!\n");
#endif
goto GET_ALARM_SUMMARY_ABORT;
}
/* init header */
apdu_len = get_alarm_summary_ack_encode_apdu_init(
&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id);
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
if (Get_Alarm_Summary[i]) {
for (j = 0; j < 0xffff; j++) {
alarm_value = Get_Alarm_Summary[i] (j, &getalarm_data);
if (alarm_value > 0) {
len = get_alarm_sumary_ack_encode_apdu_data(
&Handler_Transmit_Buffer[pdu_len + apdu_len],
service_data->max_resp - apdu_len,
&getalarm_data);
if (len <= 0) {
error = true;
goto GET_ALARM_SUMMARY_ERROR;
}
else
apdu_len += len;
}
else if (alarm_value < 0) {
break;
}
}
}
}
#if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending response!\n");
#endif
GET_ALARM_SUMMARY_ERROR:
if (error) {
if (len == BACNET_STATUS_ABORT) {
/* BACnet APDU too small to fit data, so proper response is Abort */
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"GetAlarmSummary: Reply too big to fit into APDU!\n");
#endif
}
else {
apdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_GET_ALARM_SUMMARY,
ERROR_CLASS_PROPERTY, ERROR_CODE_OTHER);
#if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending Error!\n");
#endif
}
}
GET_ALARM_SUMMARY_ABORT:
pdu_len += apdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
return;
}
+35 -35
View File
@@ -1,38 +1,38 @@
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
TARGET = baciamr
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
TARGET = baciamr
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
include: .depend
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
include: .depend
+35 -35
View File
@@ -1,38 +1,38 @@
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
TARGET = bacinitr
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
TARGET = bacinitr
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
include: .depend
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
include: .depend
+177 -177
View File
@@ -1,177 +1,177 @@
BACnet MS/TP Capture Tool
This tool captures BACnet MS/TP packets on an RS485 serial interface,
and saves the packets to a file in Wireshark PCAP format for
the BACnet MS/TP dissector to read. The filename has a date and time
code in it, and will contain up to 65535 packets. A new file
will be created at each 65535 packet interval. The tool can
be stopped by using Control-C.
Here is a sample of the tool running (use CTRL-C to quit):
D:\code\bacnet-stack>bin\mstpcap.exe com54 38400
Adjusted interface name to \\.\COM54
mstpcap: Using \\.\COM54 for capture at 38400 bps.
mstpcap: saving capture to mstp_20110413134119.cap
1156 packets
==== MS/TP Frame Counts ====
MAC Tokens PFM RPFM DER Postpd DNER TestReq TestRsp
0 188 4 0 0 0 0 0 0
2 189 0 0 0 0 0 0 0
3 189 9 0 0 0 0 0 0
7 189 60 0 0 0 0 0 0
35 188 140 0 0 0 0 0 0
Node Count: 5
==== MS/TP Usage and Timing Maximums ====
MAC MaxMstr Retries Npoll Self Treply Tusage Trpfm Tder Tpostpd
0 1 0 52 0 11 24 0 0 0
2 0 0 0 0 23 0 0 0 0
3 6 0 50 0 5 100 0 0 0
7 34 0 52 0 5 34 0 0 0
35 127 0 50 0 6 63 0 0 0
Node Count: 5
Invalid Frame Count: 0
The files that are captured can also be scanned to give some statistics:
D:\code\bacnet-stack>bin\mstpcap.exe --scan mstp_20110413134119.cap
Scanning mstp_20110413134119.cap
1156 packets
==== MS/TP Frame Counts ====
MAC Tokens PFM RPFM DER Postpd DNER TestReq TestRsp
0 188 4 0 0 0 0 0 0
2 189 0 0 0 0 0 0 0
3 189 9 0 0 0 0 0 0
7 189 60 0 0 0 0 0 0
35 188 140 0 0 0 0 0 0
Node Count: 5
==== MS/TP Usage and Timing Maximums ====
MAC MaxMstr Retries Npoll Self Treply Tusage Trpfm Tder Tpostpd
0 1 0 52 0 11 24 0 0 0
2 0 0 0 0 23 0 0 0 0
3 6 0 50 0 5 100 0 0 0
7 34 0 52 0 5 34 0 0 0
35 127 0 50 0 6 63 0 0 0
Node Count: 5
Invalid Frame Count: 0
The BACnet MS/TP capture tool also includes statistics which are
listed for any MAC addresses found passing a token,
or any MAC address replying to a DER message.
The statistics are emitted when Control-C is pressed, or when
65535 packets are captured and the new file is created.
The statistics are cleared when the new file is created.
The statistics can be emitted from a file using the "--scan" option.
The MS/TP Frame counts use the following abbreviations:
Tokens = number of Token frames sent from this MAC address.
PFM = number of Poll-For-Master frames sent from this MAC address.
RPFM = number of Reply-To-Poll-For-Master frames sent from this MAC address.
DER = number of Data-Expecting-Reply frames sent from this MAC address.
Postpd = number of Reply-Postponed frames sent from this MAC address.
DNER = number of Data-Not-Expecting-Reply frames sent from this MAC address.
TestReq = number of Test-Request frames sent from this MAC address.
TestRsp = number of Test-Response frames sent from this MAC address.
The MS/TP Usage and Timing Maximums use the following abbreviations:
MaxMstr = highest destination MAC address during PFM
Retries = number of second tokens sent to this MAC address.
Npoll = number of Tokens between Poll-For-Master
Self = number of Tokens sent to self (Addendum 135-2008v)
Treply = maximum number of milliseconds it took to reply with
a token after receiving a token. Treply is required to be less
than 25ms (but the mstpcap tool may not have that good of
resolution on Windows).
Tusage = the maximum number of milliseconds the
device waits for a ReplyToPollForMaster or Token retry.
Tusage is required to be between 20ms and 100ms.
Trpfm = maximum number of milliseconds to respond to PFM with RPFM. It is
required to be less than 25ms.
Tder = maximum number of milliseconds that a device takes to
respond to a DataExpectingReply request. Tder is required to be less
than 250ms.
Tpostpd = maximum number of milliseconds to respond to
DataExpectingReply request with ReplyPostponed. Tpostpd is
required to be less than 250ms.
==== FTDI chip RS-485 converter 76800 baud tricks ====
If you are using FTDI chip in your RS485 converter, you can
alias an existing baud rate on Windows in the FTDIPORT.INF file
in order to acheive non-standard 76800 bps:
HKR,,"ConfigData",1,11,00,3F,3F,27,C0,00,00,27,00,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
replace the 10,27,00,00 => divisor = 10000, rate = 300 bps alias
hex values actual
----------- ---------
27,C0,00,00 - 76923 bps => divisor=39.125
27,00,00,00 - 76677 bps => divisor=39.000
Windows XP (from koby3101)
1) Plug in and locate your USB/RSS85 in Device Manager under ports. Right click
on it and select Properties. Click Details tab and from the drop down select
Device Instance Id.
2) Click Start, Run and then type regedit.
Follow this path in the registry
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\FTDIBUS
Locate the folder that has the same name as what you found earlier Device Instance
Id in step 1. Click on 0000 folder and then Device Parameters. On the right
side you will see ConfigData. Right click and select Modify Binary Data.
Locate the 10 27 which in my case were in 5th and 6th position and replace with
27 C0.
This will make the RS485 go to 76800 baud (76923 baud) baud when you ask it
to be 300 baud.
So to capture at 76800 baud type: mstpcap.exe COM2 300
Linux (used with Debian Lenny and Fedora 15)
http://www.connecttech.com/KnowledgeDatabase/kdb309.htm
As root:
Change USB so I can use it later as normal user:
# chmod 777 /dev/ttyUSB0 -
Print current info about the device:
# setserial /dev/ttyUSB0 a
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 0
closing_wait: infinte
Flags: spd_normal low_latency
Make custom speed:
# setserial /dev/ttyUSB0 spd_cust
24000000/312 gives 76923 baudrate:
# setserial /dev/ttyUSB0 divisor 312
Print to make sure changes got applied:
# setserial /dev/ttyUSB0 a
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 312
closing_wait: infinte
Flags: spd_cust low_latency
Now as normal user running the mstpcap which uses the default 38400 baud it
will actually capture at 76800 baud. (76923)
Just navigate (cd bin) to bin folder in the project and type:
$ ./mstpcap
BACnet MS/TP Capture Tool
This tool captures BACnet MS/TP packets on an RS485 serial interface,
and saves the packets to a file in Wireshark PCAP format for
the BACnet MS/TP dissector to read. The filename has a date and time
code in it, and will contain up to 65535 packets. A new file
will be created at each 65535 packet interval. The tool can
be stopped by using Control-C.
Here is a sample of the tool running (use CTRL-C to quit):
D:\code\bacnet-stack>bin\mstpcap.exe com54 38400
Adjusted interface name to \\.\COM54
mstpcap: Using \\.\COM54 for capture at 38400 bps.
mstpcap: saving capture to mstp_20110413134119.cap
1156 packets
==== MS/TP Frame Counts ====
MAC Tokens PFM RPFM DER Postpd DNER TestReq TestRsp
0 188 4 0 0 0 0 0 0
2 189 0 0 0 0 0 0 0
3 189 9 0 0 0 0 0 0
7 189 60 0 0 0 0 0 0
35 188 140 0 0 0 0 0 0
Node Count: 5
==== MS/TP Usage and Timing Maximums ====
MAC MaxMstr Retries Npoll Self Treply Tusage Trpfm Tder Tpostpd
0 1 0 52 0 11 24 0 0 0
2 0 0 0 0 23 0 0 0 0
3 6 0 50 0 5 100 0 0 0
7 34 0 52 0 5 34 0 0 0
35 127 0 50 0 6 63 0 0 0
Node Count: 5
Invalid Frame Count: 0
The files that are captured can also be scanned to give some statistics:
D:\code\bacnet-stack>bin\mstpcap.exe --scan mstp_20110413134119.cap
Scanning mstp_20110413134119.cap
1156 packets
==== MS/TP Frame Counts ====
MAC Tokens PFM RPFM DER Postpd DNER TestReq TestRsp
0 188 4 0 0 0 0 0 0
2 189 0 0 0 0 0 0 0
3 189 9 0 0 0 0 0 0
7 189 60 0 0 0 0 0 0
35 188 140 0 0 0 0 0 0
Node Count: 5
==== MS/TP Usage and Timing Maximums ====
MAC MaxMstr Retries Npoll Self Treply Tusage Trpfm Tder Tpostpd
0 1 0 52 0 11 24 0 0 0
2 0 0 0 0 23 0 0 0 0
3 6 0 50 0 5 100 0 0 0
7 34 0 52 0 5 34 0 0 0
35 127 0 50 0 6 63 0 0 0
Node Count: 5
Invalid Frame Count: 0
The BACnet MS/TP capture tool also includes statistics which are
listed for any MAC addresses found passing a token,
or any MAC address replying to a DER message.
The statistics are emitted when Control-C is pressed, or when
65535 packets are captured and the new file is created.
The statistics are cleared when the new file is created.
The statistics can be emitted from a file using the "--scan" option.
The MS/TP Frame counts use the following abbreviations:
Tokens = number of Token frames sent from this MAC address.
PFM = number of Poll-For-Master frames sent from this MAC address.
RPFM = number of Reply-To-Poll-For-Master frames sent from this MAC address.
DER = number of Data-Expecting-Reply frames sent from this MAC address.
Postpd = number of Reply-Postponed frames sent from this MAC address.
DNER = number of Data-Not-Expecting-Reply frames sent from this MAC address.
TestReq = number of Test-Request frames sent from this MAC address.
TestRsp = number of Test-Response frames sent from this MAC address.
The MS/TP Usage and Timing Maximums use the following abbreviations:
MaxMstr = highest destination MAC address during PFM
Retries = number of second tokens sent to this MAC address.
Npoll = number of Tokens between Poll-For-Master
Self = number of Tokens sent to self (Addendum 135-2008v)
Treply = maximum number of milliseconds it took to reply with
a token after receiving a token. Treply is required to be less
than 25ms (but the mstpcap tool may not have that good of
resolution on Windows).
Tusage = the maximum number of milliseconds the
device waits for a ReplyToPollForMaster or Token retry.
Tusage is required to be between 20ms and 100ms.
Trpfm = maximum number of milliseconds to respond to PFM with RPFM. It is
required to be less than 25ms.
Tder = maximum number of milliseconds that a device takes to
respond to a DataExpectingReply request. Tder is required to be less
than 250ms.
Tpostpd = maximum number of milliseconds to respond to
DataExpectingReply request with ReplyPostponed. Tpostpd is
required to be less than 250ms.
==== FTDI chip RS-485 converter 76800 baud tricks ====
If you are using FTDI chip in your RS485 converter, you can
alias an existing baud rate on Windows in the FTDIPORT.INF file
in order to acheive non-standard 76800 bps:
HKR,,"ConfigData",1,11,00,3F,3F,27,C0,00,00,27,00,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
replace the 10,27,00,00 => divisor = 10000, rate = 300 bps alias
hex values actual
----------- ---------
27,C0,00,00 - 76923 bps => divisor=39.125
27,00,00,00 - 76677 bps => divisor=39.000
Windows XP (from koby3101)
1) Plug in and locate your USB/RSS85 in Device Manager under ports. Right click
on it and select Properties. Click Details tab and from the drop down select
Device Instance Id.
2) Click Start, Run and then type regedit.
Follow this path in the registry
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\FTDIBUS
Locate the folder that has the same name as what you found earlier Device Instance
Id in step 1. Click on 0000 folder and then Device Parameters. On the right
side you will see ConfigData. Right click and select Modify Binary Data.
Locate the 10 27 which in my case were in 5th and 6th position and replace with
27 C0.
This will make the RS485 go to 76800 baud (76923 baud) baud when you ask it
to be 300 baud.
So to capture at 76800 baud type: mstpcap.exe COM2 300
Linux (used with Debian Lenny and Fedora 15)
http://www.connecttech.com/KnowledgeDatabase/kdb309.htm
As root:
Change USB so I can use it later as normal user:
# chmod 777 /dev/ttyUSB0 -
Print current info about the device:
# setserial /dev/ttyUSB0 a
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 0
closing_wait: infinte
Flags: spd_normal low_latency
Make custom speed:
# setserial /dev/ttyUSB0 spd_cust
24000000/312 gives 76923 baudrate:
# setserial /dev/ttyUSB0 divisor 312
Print to make sure changes got applied:
# setserial /dev/ttyUSB0 a
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 312
closing_wait: infinte
Flags: spd_cust low_latency
Now as normal user running the mstpcap which uses the default 38400 baud it
will actually capture at 76800 baud. (76923)
Just navigate (cd bin) to bin folder in the project and type:
$ ./mstpcap
+9 -9
View File
@@ -1,9 +1,9 @@
@echo off
echo Build with MinGW and MSYS: mingw.sourceforge.net
rem set PATH=C:\MinGW\msys\1.0\bin;C:\MinGW\bin
rem assumes rm, cp, size are already in path
set CC=gcc
set AR=ar
set MAKE=make
set TARGET_EXT=.exe
make clean all
@echo off
echo Build with MinGW and MSYS: mingw.sourceforge.net
rem set PATH=C:\MinGW\msys\1.0\bin;C:\MinGW\bin
rem assumes rm, cp, size are already in path
set CC=gcc
set AR=ar
set MAKE=make
set TARGET_EXT=.exe
make clean all
+17 -17
View File
@@ -1,20 +1,20 @@
BACnet MS/TP CRC Calculator
BACnet MS/TP CRC Calculator
This tool receives MS/TP bytes and generates a CRC for those bytes
mstpcrc [options] <00 00 00 00...>
perform MS/TP CRC on data bytes.
options:
[-x] interprete the arguments as ascii hex (default)
[-d] interprete the argument as ascii decimal
[-8] calculate the MS/TP 8-bit Header CRC (default)
[-16] calculate the MS/TP 16-bit Data CRC
Here is a sample of the tool running (use CTRL-C to quit):
D:\code\bacnet-stack\demo\mstpcrc>mstpcrc 06 ff 01 00 15
0x06
0xFF
0x01
0x00
0x15
mstpcrc [options] <00 00 00 00...>
perform MS/TP CRC on data bytes.
options:
[-x] interprete the arguments as ascii hex (default)
[-d] interprete the argument as ascii decimal
[-8] calculate the MS/TP 8-bit Header CRC (default)
[-16] calculate the MS/TP 16-bit Data CRC
Here is a sample of the tool running (use CTRL-C to quit):
D:\code\bacnet-stack\demo\mstpcrc>mstpcrc 06 ff 01 00 15
0x06
0xFF
0x01
0x00
0x15
0x8E Header CRC
+6
View File
@@ -112,6 +112,12 @@ extern "C" {
uint32_t object_instance,
float value);
bool Analog_Input_Out_Of_Service(
uint32_t object_instance);
void Analog_Input_Out_Of_Service_Set(
uint32_t object_instance,
bool oos_flag);
/* note: header of Intrinsic_Reporting function is required
even when INTRINSIC_REPORTING is not defined */
void Analog_Input_Intrinsic_Reporting(
File diff suppressed because it is too large Load Diff
+94 -94
View File
@@ -1,94 +1,94 @@
/**************************************************************************
*
* Copyright (C) 2012 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.
*
*********************************************************************/
#ifndef CSV_H
#define CSV_H
#include <stdbool.h>
#include <stdint.h>
#include "bacdef.h"
#include "bacerror.h"
#include "rp.h"
#include "wp.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void CharacterString_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool CharacterString_Value_Valid_Instance(
uint32_t object_instance);
unsigned CharacterString_Value_Count(
void);
uint32_t CharacterString_Value_Index_To_Instance(
unsigned index);
unsigned CharacterString_Value_Instance_To_Index(
uint32_t instance);
int CharacterString_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
bool CharacterString_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data);
/* optional API */
bool CharacterString_Value_Object_Instance_Add(
uint32_t instance);
bool CharacterString_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name);
bool CharacterString_Value_Name_Set(
uint32_t object_instance,
char *new_name);
bool CharacterString_Value_Present_Value(
uint32_t object_instance,
BACNET_CHARACTER_STRING * value);
bool CharacterString_Value_Present_Value_Set(
uint32_t object_instance,
BACNET_CHARACTER_STRING * value);
bool CharacterString_Value_Description_Set(
uint32_t object_instance,
char *text_string);
void CharacterString_Value_Init(
void);
#ifdef TEST
#include "ctest.h"
void testCharacterStringValue(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2012 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.
*
*********************************************************************/
#ifndef CSV_H
#define CSV_H
#include <stdbool.h>
#include <stdint.h>
#include "bacdef.h"
#include "bacerror.h"
#include "rp.h"
#include "wp.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void CharacterString_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool CharacterString_Value_Valid_Instance(
uint32_t object_instance);
unsigned CharacterString_Value_Count(
void);
uint32_t CharacterString_Value_Index_To_Instance(
unsigned index);
unsigned CharacterString_Value_Instance_To_Index(
uint32_t instance);
int CharacterString_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
bool CharacterString_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data);
/* optional API */
bool CharacterString_Value_Object_Instance_Add(
uint32_t instance);
bool CharacterString_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name);
bool CharacterString_Value_Name_Set(
uint32_t object_instance,
char *new_name);
bool CharacterString_Value_Present_Value(
uint32_t object_instance,
BACNET_CHARACTER_STRING * value);
bool CharacterString_Value_Present_Value_Set(
uint32_t object_instance,
BACNET_CHARACTER_STRING * value);
bool CharacterString_Value_Description_Set(
uint32_t object_instance,
char *text_string);
void CharacterString_Value_Init(
void);
#ifdef TEST
#include "ctest.h"
void testCharacterStringValue(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
File diff suppressed because it is too large Load Diff
+107 -107
View File
@@ -1,107 +1,107 @@
/**************************************************************************
*
* Copyright (C) 2012 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.
*
*********************************************************************/
#ifndef MULTISTATE_VALUE_H
#define MULTISTATE_VALUE_H
#include <stdbool.h>
#include <stdint.h>
#include "bacdef.h"
#include "bacerror.h"
#include "rp.h"
#include "wp.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void Multistate_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Multistate_Value_Valid_Instance(
uint32_t object_instance);
unsigned Multistate_Value_Count(
void);
uint32_t Multistate_Value_Index_To_Instance(
unsigned index);
unsigned Multistate_Value_Instance_To_Index(
uint32_t instance);
int Multistate_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
bool Multistate_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data);
/* optional API */
bool Multistate_Value_Object_Instance_Add(
uint32_t instance);
bool Multistate_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name);
bool Multistate_Value_Name_Set(
uint32_t object_instance,
char *new_name);
uint32_t Multistate_Value_Present_Value(
uint32_t object_instance);
bool Multistate_Value_Present_Value_Set(
uint32_t object_instance,
uint32_t value);
bool Multistate_Value_Out_Of_Service(
uint32_t object_instance);
void Multistate_Value_Out_Of_Service_Set(
uint32_t object_instance,
bool value);
bool Multistate_Value_Description_Set(
uint32_t object_instance,
char *text_string);
bool Multistate_Value_State_Text_Set(
uint32_t object_instance,
uint32_t state_index,
char *new_name);
bool Multistate_Value_Max_States_Set(
uint32_t instance,
uint32_t max_states_requested);
void Multistate_Value_Init(
void);
#ifdef TEST
#include "ctest.h"
void testMultistateValue(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2012 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.
*
*********************************************************************/
#ifndef MULTISTATE_VALUE_H
#define MULTISTATE_VALUE_H
#include <stdbool.h>
#include <stdint.h>
#include "bacdef.h"
#include "bacerror.h"
#include "rp.h"
#include "wp.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void Multistate_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Multistate_Value_Valid_Instance(
uint32_t object_instance);
unsigned Multistate_Value_Count(
void);
uint32_t Multistate_Value_Index_To_Instance(
unsigned index);
unsigned Multistate_Value_Instance_To_Index(
uint32_t instance);
int Multistate_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
bool Multistate_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data);
/* optional API */
bool Multistate_Value_Object_Instance_Add(
uint32_t instance);
bool Multistate_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name);
bool Multistate_Value_Name_Set(
uint32_t object_instance,
char *new_name);
uint32_t Multistate_Value_Present_Value(
uint32_t object_instance);
bool Multistate_Value_Present_Value_Set(
uint32_t object_instance,
uint32_t value);
bool Multistate_Value_Out_Of_Service(
uint32_t object_instance);
void Multistate_Value_Out_Of_Service_Set(
uint32_t object_instance,
bool value);
bool Multistate_Value_Description_Set(
uint32_t object_instance,
char *text_string);
bool Multistate_Value_State_Text_Set(
uint32_t object_instance,
uint32_t state_index,
char *new_name);
bool Multistate_Value_Max_States_Set(
uint32_t instance,
uint32_t max_states_requested);
void Multistate_Value_Init(
void);
#ifdef TEST
#include "ctest.h"
void testMultistateValue(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+20 -20
View File
@@ -1,20 +1,20 @@
The BACnet Scriptable (using Perl) Tool.
* Running this tool assumes that the library has been already built. The
library should be built with a command similar to
CC=/mingw/bin/gcc BACNET_DEFINES="-DPRINT_ENABLED -DBACAPP_ALL -DBACFILE
-DINTRINSIC_REPORTING" BBMD_DEFINE=-DBBMD_ENABLED\=1 BACNET_PORT=win32 make
clean library
* Currently, the tool assumes only win32 port, but should be easily modifiable
for any port build.
* This tool has to be run from a path without any spaces. The presence of the
.Inline directory is required.
* Run the tool without any arguments to see usage instructions
* To run the example ReapProperty script (which reads Analog Value 0 Present
Value) for Device at instance 1234 run the following command
perl bacnet.pl --script example_readprop.pl -- 1234
The BACnet Scriptable (using Perl) Tool.
* Running this tool assumes that the library has been already built. The
library should be built with a command similar to
CC=/mingw/bin/gcc BACNET_DEFINES="-DPRINT_ENABLED -DBACAPP_ALL -DBACFILE
-DINTRINSIC_REPORTING" BBMD_DEFINE=-DBBMD_ENABLED\=1 BACNET_PORT=win32 make
clean library
* Currently, the tool assumes only win32 port, but should be easily modifiable
for any port build.
* This tool has to be run from a path without any spaces. The presence of the
.Inline directory is required.
* Run the tool without any arguments to see usage instructions
* To run the example ReapProperty script (which reads Analog Value 0 Present
Value) for Device at instance 1234 run the following command
perl bacnet.pl --script example_readprop.pl -- 1234
+44 -44
View File
@@ -1,44 +1,44 @@
#Makefile to build BACnet Application using GCC compiler
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# AR = ar
# MAKE = make
# SIZE = size
#
# Assumes rm and cp are available
# Executable file name
TARGET = ptransfer
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
#Makefile to build BACnet Application using GCC compiler
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# AR = ar
# MAKE = make
# SIZE = size
#
# Assumes rm and cp are available
# Executable file name
TARGET = ptransfer
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
+139 -139
View File
@@ -1,139 +1,139 @@
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = ptransfer
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = ptransfer
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
+5 -5
View File
@@ -1,9 +1,9 @@
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# Executable file name
TARGET = bacrpm
+139 -139
View File
@@ -1,139 +1,139 @@
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacrr
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG):
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacrr
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG):
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
+44 -44
View File
@@ -1,44 +1,44 @@
#Makefile to build BACnet Application using GCC compiler
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# AR = ar
# MAKE = make
# SIZE = size
#
# Assumes rm and cp are available
# Executable file name
TARGET = bacscov
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
#Makefile to build BACnet Application using GCC compiler
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# AR = ar
# MAKE = make
# SIZE = size
#
# Assumes rm and cp are available
# Executable file name
TARGET = bacscov
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
+394 -394
View File
@@ -1,394 +1,394 @@
/*************************************************************************
* 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.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#include <ctype.h> /* for toupper */
#define PRINT_ENABLED 1
#include "bacdef.h"
#include "config.h"
#include "bactext.h"
#include "bacerror.h"
#include "iam.h"
#include "arf.h"
#include "tsm.h"
#include "address.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "net.h"
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#include "dlenv.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* converted command line arguments */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
/* Process identifier for matching replies */
static uint32_t Target_Device_Process_Identifier = 0;
/* the invoke id is needed to filter incoming messages */
static uint8_t Request_Invoke_ID = 0;
/* MAC and SNET address of target */
static BACNET_ADDRESS Target_Address;
/* indication of error, reject, or abort */
static bool Error_Detected = false;
/* data used in COV subscription request */
BACNET_SUBSCRIBE_COV_DATA *COV_Subscribe_Data = NULL;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
Error_Detected = true;
}
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
(void) server;
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name((int) abort_reason));
Error_Detected = true;
}
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name((int) reject_reason));
Error_Detected = true;
}
}
static void Init_Service_Handlers(
void)
{
Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the data coming back from COV subscriptions */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_COV_NOTIFICATION,
handler_ccov_notification);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
handler_ucov_notification);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
void cleanup(
void)
{
BACNET_SUBSCRIBE_COV_DATA *cov_data = NULL;
BACNET_SUBSCRIBE_COV_DATA *cov_data_old = NULL;
cov_data = COV_Subscribe_Data;
while (cov_data) {
cov_data_old = cov_data;
cov_data = cov_data->next;
free(cov_data_old);
}
}
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
time_t delta_seconds = 0;
bool found = false;
char *filename = NULL;
bool print_usage_terse = false;
bool print_usage_verbose = false;
BACNET_SUBSCRIBE_COV_DATA *cov_data = NULL;
int argi = 0;
int arg_remaining = 0;
if (argc < 6) {
print_usage_terse = true;
}
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
print_usage_terse = true;
print_usage_verbose = true;
}
if (print_usage_terse) {
filename = filename_remove_path(argv[0]);
printf("Usage: %s device-id object-type object-instance "
"process-id <confirmed lifetime|cancel>\r\n",
filename);
if (!print_usage_verbose) {
return 0;
}
}
if (print_usage_verbose) {
printf("\r\n"
"device-id:\r\n"
"The subscriber BACnet Device Object Instance number.\r\n"
"\r\n"
"object-type:\r\n"
"The monitored object type is the integer value of the\r\n"
"enumeration BACNET_OBJECT_TYPE in bacenum.h. For example,\r\n"
"if you were monitoring Analog Output 2, the object-type\r\n"
"would be 1.\r\n"
"\r\n"
"object-instance:\r\n"
"The monitored object instance number.\r\n"
"\r\n"
"process-id:\r\n"
"Process Identifier for this COV subscription.\r\n"
"\r\n"
"confirmed:\r\n"
"Optional flag to subscribe using Confirmed notifications.\r\n"
"Use the word \'confirmed\' or \'unconfirmed\'.\r\n"
"\r\n"
"lifetime:\r\n"
"Optional subscription lifetime is conveyed in seconds.\r\n"
"\r\n"
"cancel:\r\n"
"Use the word \'cancel\' instead of confirm and lifetime.\r\n"
"This shall indicate a cancellation request.\r\n"
"\r\n"
"Example:\r\n"
"If you want subscribe to Device 123 Analog Input 9 object\r\n"
"using confirmed COV notifications for 5 minutes,\r\n"
"you could send the following command:\r\n"
"%s 123 0 9 1 confirmed 600\r\n"
"To send the same COV subscription request for unconfirmed\r\n"
"notifications, send the following command:\r\n"
"%s 123 0 9 1 unconfirmed 600\r\n"
"To cancel the same COV subscription request,\r\n"
"send the following command:\r\n"
"%s 123 0 9 1 cancel\r\n",
filename, filename, filename);
return 0;
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1;
}
atexit(cleanup);
COV_Subscribe_Data = calloc(1, sizeof(BACNET_SUBSCRIBE_COV_DATA));
cov_data = COV_Subscribe_Data;
argi = 2;
while (cov_data) {
cov_data->monitoredObjectIdentifier.type =
strtol(argv[argi], NULL, 0);
if (cov_data->monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
cov_data->monitoredObjectIdentifier.type, MAX_BACNET_OBJECT_TYPE);
return 1;
}
argi++;
cov_data->monitoredObjectIdentifier.instance =
strtol(argv[argi], NULL, 0);
if (cov_data->monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
cov_data->monitoredObjectIdentifier.instance,
BACNET_MAX_INSTANCE + 1);
return 1;
}
argi++;
cov_data->subscriberProcessIdentifier =
strtol(argv[argi], NULL, 0);
argi++;
if (strcmp(argv[argi],"cancel") == 0) {
cov_data->cancellationRequest = true;
argi++;
} else {
cov_data->cancellationRequest = false;
if (strcmp(argv[argi],"confirmed") == 0) {
cov_data->issueConfirmedNotifications = true;
} else if (strcmp(argv[argi],"unconfirmed") == 0) {
cov_data->issueConfirmedNotifications = false;
} else {
fprintf(stderr, "unknown option: %s\r\n",
argv[argi]);
return 1;
}
argi++;
arg_remaining = argc - argi;
if (arg_remaining > 0) {
cov_data->lifetime = strtol(argv[argi], NULL, 0);
argi++;
} else {
cov_data->lifetime = 0;
}
}
arg_remaining = argc - argi;
if (arg_remaining < 5) {
break;
} else {
cov_data->next = calloc(1, sizeof(BACNET_SUBSCRIBE_COV_DATA));
cov_data = cov_data->next;
}
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
Init_Service_Handlers();
dlenv_init();
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
}
/* start at the beginning of the subscribe list */
cov_data = COV_Subscribe_Data;
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* at least one second has passed */
if (current_seconds != last_seconds) {
/* increment timer - exit if timed out */
delta_seconds = current_seconds - last_seconds;
elapsed_seconds += delta_seconds;
tsm_timer_milliseconds((delta_seconds * 1000));
/* keep track of time for next check */
last_seconds = current_seconds;
}
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
if (!found) {
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
}
if (found) {
if (Request_Invoke_ID == 0) {
Target_Device_Process_Identifier =
cov_data->subscriberProcessIdentifier;
Request_Invoke_ID = Send_COV_Subscribe(
Target_Device_Object_Instance,
cov_data);
if (!cov_data->cancellationRequest &&
(timeout_seconds < cov_data->lifetime)) {
/* increase the timeout to the longest lifetime */
timeout_seconds = cov_data->lifetime;
}
printf("Sent SubscribeCOV request. Waiting %u seconds.\r\n",
(unsigned)(timeout_seconds - elapsed_seconds));
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
if (cov_data->next) {
cov_data = cov_data->next;
Request_Invoke_ID = 0;
} else {
/* do nothing - wait for lifetime value to expire */
}
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
fprintf(stderr, "\rError: TSM Timeout!\r\n");
tsm_free_invoke_id(Request_Invoke_ID);
Error_Detected = true;
/* try again or abort? */
break;
}
} else {
/* exit if timed out */
if (elapsed_seconds > timeout_seconds) {
Error_Detected = true;
printf("\rError: APDU Timeout!\r\n");
break;
}
}
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (Error_Detected) {
break;
}
/* COV - so just wait until lifetime value expires */
if (elapsed_seconds > timeout_seconds) {
break;
}
}
if (Error_Detected)
return 1;
return 0;
}
/*************************************************************************
* 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.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#include <ctype.h> /* for toupper */
#define PRINT_ENABLED 1
#include "bacdef.h"
#include "config.h"
#include "bactext.h"
#include "bacerror.h"
#include "iam.h"
#include "arf.h"
#include "tsm.h"
#include "address.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "net.h"
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#include "dlenv.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* converted command line arguments */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
/* Process identifier for matching replies */
static uint32_t Target_Device_Process_Identifier = 0;
/* the invoke id is needed to filter incoming messages */
static uint8_t Request_Invoke_ID = 0;
/* MAC and SNET address of target */
static BACNET_ADDRESS Target_Address;
/* indication of error, reject, or abort */
static bool Error_Detected = false;
/* data used in COV subscription request */
BACNET_SUBSCRIBE_COV_DATA *COV_Subscribe_Data = NULL;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
Error_Detected = true;
}
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
(void) server;
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name((int) abort_reason));
Error_Detected = true;
}
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name((int) reject_reason));
Error_Detected = true;
}
}
static void Init_Service_Handlers(
void)
{
Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the data coming back from COV subscriptions */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_COV_NOTIFICATION,
handler_ccov_notification);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
handler_ucov_notification);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
void cleanup(
void)
{
BACNET_SUBSCRIBE_COV_DATA *cov_data = NULL;
BACNET_SUBSCRIBE_COV_DATA *cov_data_old = NULL;
cov_data = COV_Subscribe_Data;
while (cov_data) {
cov_data_old = cov_data;
cov_data = cov_data->next;
free(cov_data_old);
}
}
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
time_t delta_seconds = 0;
bool found = false;
char *filename = NULL;
bool print_usage_terse = false;
bool print_usage_verbose = false;
BACNET_SUBSCRIBE_COV_DATA *cov_data = NULL;
int argi = 0;
int arg_remaining = 0;
if (argc < 6) {
print_usage_terse = true;
}
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
print_usage_terse = true;
print_usage_verbose = true;
}
if (print_usage_terse) {
filename = filename_remove_path(argv[0]);
printf("Usage: %s device-id object-type object-instance "
"process-id <confirmed lifetime|cancel>\r\n",
filename);
if (!print_usage_verbose) {
return 0;
}
}
if (print_usage_verbose) {
printf("\r\n"
"device-id:\r\n"
"The subscriber BACnet Device Object Instance number.\r\n"
"\r\n"
"object-type:\r\n"
"The monitored object type is the integer value of the\r\n"
"enumeration BACNET_OBJECT_TYPE in bacenum.h. For example,\r\n"
"if you were monitoring Analog Output 2, the object-type\r\n"
"would be 1.\r\n"
"\r\n"
"object-instance:\r\n"
"The monitored object instance number.\r\n"
"\r\n"
"process-id:\r\n"
"Process Identifier for this COV subscription.\r\n"
"\r\n"
"confirmed:\r\n"
"Optional flag to subscribe using Confirmed notifications.\r\n"
"Use the word \'confirmed\' or \'unconfirmed\'.\r\n"
"\r\n"
"lifetime:\r\n"
"Optional subscription lifetime is conveyed in seconds.\r\n"
"\r\n"
"cancel:\r\n"
"Use the word \'cancel\' instead of confirm and lifetime.\r\n"
"This shall indicate a cancellation request.\r\n"
"\r\n"
"Example:\r\n"
"If you want subscribe to Device 123 Analog Input 9 object\r\n"
"using confirmed COV notifications for 5 minutes,\r\n"
"you could send the following command:\r\n"
"%s 123 0 9 1 confirmed 600\r\n"
"To send the same COV subscription request for unconfirmed\r\n"
"notifications, send the following command:\r\n"
"%s 123 0 9 1 unconfirmed 600\r\n"
"To cancel the same COV subscription request,\r\n"
"send the following command:\r\n"
"%s 123 0 9 1 cancel\r\n",
filename, filename, filename);
return 0;
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1;
}
atexit(cleanup);
COV_Subscribe_Data = calloc(1, sizeof(BACNET_SUBSCRIBE_COV_DATA));
cov_data = COV_Subscribe_Data;
argi = 2;
while (cov_data) {
cov_data->monitoredObjectIdentifier.type =
strtol(argv[argi], NULL, 0);
if (cov_data->monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
cov_data->monitoredObjectIdentifier.type, MAX_BACNET_OBJECT_TYPE);
return 1;
}
argi++;
cov_data->monitoredObjectIdentifier.instance =
strtol(argv[argi], NULL, 0);
if (cov_data->monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
cov_data->monitoredObjectIdentifier.instance,
BACNET_MAX_INSTANCE + 1);
return 1;
}
argi++;
cov_data->subscriberProcessIdentifier =
strtol(argv[argi], NULL, 0);
argi++;
if (strcmp(argv[argi],"cancel") == 0) {
cov_data->cancellationRequest = true;
argi++;
} else {
cov_data->cancellationRequest = false;
if (strcmp(argv[argi],"confirmed") == 0) {
cov_data->issueConfirmedNotifications = true;
} else if (strcmp(argv[argi],"unconfirmed") == 0) {
cov_data->issueConfirmedNotifications = false;
} else {
fprintf(stderr, "unknown option: %s\r\n",
argv[argi]);
return 1;
}
argi++;
arg_remaining = argc - argi;
if (arg_remaining > 0) {
cov_data->lifetime = strtol(argv[argi], NULL, 0);
argi++;
} else {
cov_data->lifetime = 0;
}
}
arg_remaining = argc - argi;
if (arg_remaining < 5) {
break;
} else {
cov_data->next = calloc(1, sizeof(BACNET_SUBSCRIBE_COV_DATA));
cov_data = cov_data->next;
}
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
Init_Service_Handlers();
dlenv_init();
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
}
/* start at the beginning of the subscribe list */
cov_data = COV_Subscribe_Data;
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* at least one second has passed */
if (current_seconds != last_seconds) {
/* increment timer - exit if timed out */
delta_seconds = current_seconds - last_seconds;
elapsed_seconds += delta_seconds;
tsm_timer_milliseconds((delta_seconds * 1000));
/* keep track of time for next check */
last_seconds = current_seconds;
}
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
if (!found) {
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
}
if (found) {
if (Request_Invoke_ID == 0) {
Target_Device_Process_Identifier =
cov_data->subscriberProcessIdentifier;
Request_Invoke_ID = Send_COV_Subscribe(
Target_Device_Object_Instance,
cov_data);
if (!cov_data->cancellationRequest &&
(timeout_seconds < cov_data->lifetime)) {
/* increase the timeout to the longest lifetime */
timeout_seconds = cov_data->lifetime;
}
printf("Sent SubscribeCOV request. Waiting %u seconds.\r\n",
(unsigned)(timeout_seconds - elapsed_seconds));
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
if (cov_data->next) {
cov_data = cov_data->next;
Request_Invoke_ID = 0;
} else {
/* do nothing - wait for lifetime value to expire */
}
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
fprintf(stderr, "\rError: TSM Timeout!\r\n");
tsm_free_invoke_id(Request_Invoke_ID);
Error_Detected = true;
/* try again or abort? */
break;
}
} else {
/* exit if timed out */
if (elapsed_seconds > timeout_seconds) {
Error_Detected = true;
printf("\rError: APDU Timeout!\r\n");
break;
}
}
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (Error_Detected) {
break;
}
/* COV - so just wait until lifetime value expires */
if (elapsed_seconds > timeout_seconds) {
break;
}
}
if (Error_Detected)
return 1;
return 0;
}
+143 -143
View File
@@ -1,143 +1,143 @@
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacscov
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
# by default bacupt can handle 64 tag/value pairs
BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacscov
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
# by default bacupt can handle 64 tag/value pairs
BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
+44 -44
View File
@@ -1,44 +1,44 @@
#Makefile to build BACnet Application using GCC compiler
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# AR = ar
# MAKE = make
# SIZE = size
#
# Assumes rm and cp are available
# Executable file name
TARGET = bacupt
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
#Makefile to build BACnet Application using GCC compiler
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
# AR = ar
# MAKE = make
# SIZE = size
#
# Assumes rm and cp are available
# Executable file name
TARGET = bacupt
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
+353 -353
View File
@@ -1,353 +1,353 @@
/*************************************************************************
* 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.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#include <ctype.h> /* for toupper */
#define PRINT_ENABLED 1
#include "bacdef.h"
#include "config.h"
#include "bactext.h"
#include "bacerror.h"
#include "iam.h"
#include "arf.h"
#include "tsm.h"
#include "address.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "net.h"
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#include "dlenv.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* converted command line arguments */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
static uint16_t Target_Vendor_Identifier = 260;
static uint32_t Target_Service_Number = 0;
/* property value encodings */
#ifndef MAX_PROPERTY_VALUES
#define MAX_PROPERTY_VALUES 64
#endif
static BACNET_APPLICATION_DATA_VALUE
Target_Object_Property_Value[MAX_PROPERTY_VALUES];
/* buffer for service parameters */
static uint8_t Service_Parameters[MAX_APDU];
/* the invoke id is needed to filter incoming messages */
static uint8_t Request_Invoke_ID = 0;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
Error_Detected = true;
}
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
(void) server;
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name((int) abort_reason));
Error_Detected = true;
}
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name((int) reject_reason));
Error_Detected = true;
}
}
static void Init_Service_Handlers(
void)
{
Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the data coming back from requests */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
handler_unconfirmed_private_transfer);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
time_t delta_seconds = 0;
bool found = false;
char *filename = NULL;
char *value_string = NULL;
bool status = false;
int args_remaining = 0, tag_value_arg = 0, i = 0;
BACNET_APPLICATION_TAG property_tag;
uint8_t context_tag = 0;
BACNET_PRIVATE_TRANSFER_DATA private_data = {0};
int len = 0;
bool sent_message = false;
if (argc < 6) {
filename = filename_remove_path(argv[0]);
printf("Usage: %s device-instance vendor-id service-number "
"tag value [tag value...]\r\n", filename);
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("device-instance:\r\n"
"BACnet Device Object Instance number that you are\r\n"
"trying to communicate to. This number will be used\r\n"
"to try and bind with the device using Who-Is and\r\n"
"I-Am services. For example, if you were transferring to\r\n"
"Device Object 123, the device-instance would be 123.\r\n"
"\r\n"
"vendor_id:\r\n"
"the unique vendor identification code for the type of\r\n"
"vendor proprietary service to be performed.\r\n"
"\r\n"
"service-number (Unsigned32):\r\n"
"the desired proprietary service to be performed.\r\n"
"\r\n"
"tag:\r\n"
"Tag is the integer value of the enumeration \r\n"
"BACNET_APPLICATION_TAG in bacenum.h.\r\n"
"It is the data type of the value that you are sending.\r\n"
"For example, if you were transfering a REAL value, you would \r\n"
"use a tag of 4.\r\n"
"Context tags are created using two tags in a row.\r\n"
"The context tag is preceded by a C. Ctag tag.\r\n"
"C2 4 creates a context 2 tagged REAL.\r\n"
"\r\n"
"value:\r\n"
"The value is an ASCII representation of some type of data\r\n"
"that you are transfering.\r\n"
"It is encoded using the tag information provided.\r\n"
"For example, if you were transferring a REAL value of 100.0,\r\n"
"you would use 100.0 as the value.\r\n"
"If you were transferring an object identifier for Device 123,\r\n"
"you would use 8:123 as the value.\r\n"
"\r\n"
"Example:\r\n"
"If you want to transfer a REAL value of 1.1 to service 23 of \r\n"
"vendor 260 in Device 99, you could send the following command:\r\n"
"%s 99 260 23 4 1.1\r\n", filename);
}
return 0;
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
Target_Vendor_Identifier = strtol(argv[2], NULL, 0);
Target_Service_Number = strtol(argv[3], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1;
}
args_remaining = (argc - (6-2));
for (i = 0; i < MAX_PROPERTY_VALUES; i++) {
tag_value_arg = (6-2) + (i * 2);
/* special case for context tagged values */
if (toupper(argv[tag_value_arg][0]) == 'C') {
context_tag = strtol(&argv[tag_value_arg][1], NULL, 0);
tag_value_arg++;
args_remaining--;
Target_Object_Property_Value[i].context_tag = context_tag;
Target_Object_Property_Value[i].context_specific = true;
} else {
Target_Object_Property_Value[i].context_specific = false;
}
property_tag = strtol(argv[tag_value_arg], NULL, 0);
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough tag-value pairs\r\n");
return 1;
}
value_string = argv[tag_value_arg + 1];
args_remaining--;
/* printf("tag[%d]=%u value[%d]=%s\r\n",
i, property_tag, i, value_string); */
if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, "Error: tag=%u - it must be less than %u\r\n",
property_tag, MAX_BACNET_APPLICATION_TAG);
return 1;
}
status =
bacapp_parse_application_data(property_tag, value_string,
&Target_Object_Property_Value[i]);
if (!status) {
/* FIXME: show the expected entry format for the tag */
fprintf(stderr, "Error: unable to parse the tag value\r\n");
return 1;
}
Target_Object_Property_Value[i].next = NULL;
if (i > 0) {
Target_Object_Property_Value[i - 1].next =
&Target_Object_Property_Value[i];
}
if (args_remaining <= 0) {
break;
}
}
if (args_remaining > 0) {
fprintf(stderr, "Error: Exceeded %d tag-value pairs.\r\n",
MAX_PROPERTY_VALUES);
return 1;
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
Init_Service_Handlers();
dlenv_init();
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
}
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* at least one second has passed */
if (current_seconds != last_seconds) {
/* increment timer - exit if timed out */
delta_seconds = current_seconds - last_seconds;
elapsed_seconds += delta_seconds;
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
}
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
if (!found) {
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
}
if (!sent_message) {
if (found) {
len = bacapp_encode_data(&Service_Parameters[0],
&Target_Object_Property_Value[0]);
private_data.serviceParameters = &Service_Parameters[0];
private_data.serviceParametersLen = len;
private_data.vendorID = Target_Vendor_Identifier;
private_data.serviceNumber = Target_Service_Number;
Send_UnconfirmedPrivateTransfer(
&Target_Address,
&private_data);
printf("Sent PrivateTransfer. Waiting %u seconds.\r\n",
(unsigned)(timeout_seconds - elapsed_seconds));
sent_message = true;
} else {
if (elapsed_seconds > timeout_seconds) {
printf("\rError: APDU Timeout!\r\n");
Error_Detected = true;
break;
}
}
}
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (Error_Detected) {
break;
}
/* unconfirmed - so just wait until our timeout value */
if (elapsed_seconds > timeout_seconds) {
break;
}
/* keep track of time for next check */
last_seconds = current_seconds;
}
if (Error_Detected)
return 1;
return 0;
}
/*************************************************************************
* 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.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#include <ctype.h> /* for toupper */
#define PRINT_ENABLED 1
#include "bacdef.h"
#include "config.h"
#include "bactext.h"
#include "bacerror.h"
#include "iam.h"
#include "arf.h"
#include "tsm.h"
#include "address.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "net.h"
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#include "dlenv.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* converted command line arguments */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
static uint16_t Target_Vendor_Identifier = 260;
static uint32_t Target_Service_Number = 0;
/* property value encodings */
#ifndef MAX_PROPERTY_VALUES
#define MAX_PROPERTY_VALUES 64
#endif
static BACNET_APPLICATION_DATA_VALUE
Target_Object_Property_Value[MAX_PROPERTY_VALUES];
/* buffer for service parameters */
static uint8_t Service_Parameters[MAX_APDU];
/* the invoke id is needed to filter incoming messages */
static uint8_t Request_Invoke_ID = 0;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
Error_Detected = true;
}
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
(void) server;
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name((int) abort_reason));
Error_Detected = true;
}
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name((int) reject_reason));
Error_Detected = true;
}
}
static void Init_Service_Handlers(
void)
{
Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the data coming back from requests */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
handler_unconfirmed_private_transfer);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
time_t delta_seconds = 0;
bool found = false;
char *filename = NULL;
char *value_string = NULL;
bool status = false;
int args_remaining = 0, tag_value_arg = 0, i = 0;
BACNET_APPLICATION_TAG property_tag;
uint8_t context_tag = 0;
BACNET_PRIVATE_TRANSFER_DATA private_data = {0};
int len = 0;
bool sent_message = false;
if (argc < 6) {
filename = filename_remove_path(argv[0]);
printf("Usage: %s device-instance vendor-id service-number "
"tag value [tag value...]\r\n", filename);
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("device-instance:\r\n"
"BACnet Device Object Instance number that you are\r\n"
"trying to communicate to. This number will be used\r\n"
"to try and bind with the device using Who-Is and\r\n"
"I-Am services. For example, if you were transferring to\r\n"
"Device Object 123, the device-instance would be 123.\r\n"
"\r\n"
"vendor_id:\r\n"
"the unique vendor identification code for the type of\r\n"
"vendor proprietary service to be performed.\r\n"
"\r\n"
"service-number (Unsigned32):\r\n"
"the desired proprietary service to be performed.\r\n"
"\r\n"
"tag:\r\n"
"Tag is the integer value of the enumeration \r\n"
"BACNET_APPLICATION_TAG in bacenum.h.\r\n"
"It is the data type of the value that you are sending.\r\n"
"For example, if you were transfering a REAL value, you would \r\n"
"use a tag of 4.\r\n"
"Context tags are created using two tags in a row.\r\n"
"The context tag is preceded by a C. Ctag tag.\r\n"
"C2 4 creates a context 2 tagged REAL.\r\n"
"\r\n"
"value:\r\n"
"The value is an ASCII representation of some type of data\r\n"
"that you are transfering.\r\n"
"It is encoded using the tag information provided.\r\n"
"For example, if you were transferring a REAL value of 100.0,\r\n"
"you would use 100.0 as the value.\r\n"
"If you were transferring an object identifier for Device 123,\r\n"
"you would use 8:123 as the value.\r\n"
"\r\n"
"Example:\r\n"
"If you want to transfer a REAL value of 1.1 to service 23 of \r\n"
"vendor 260 in Device 99, you could send the following command:\r\n"
"%s 99 260 23 4 1.1\r\n", filename);
}
return 0;
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
Target_Vendor_Identifier = strtol(argv[2], NULL, 0);
Target_Service_Number = strtol(argv[3], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1;
}
args_remaining = (argc - (6-2));
for (i = 0; i < MAX_PROPERTY_VALUES; i++) {
tag_value_arg = (6-2) + (i * 2);
/* special case for context tagged values */
if (toupper(argv[tag_value_arg][0]) == 'C') {
context_tag = strtol(&argv[tag_value_arg][1], NULL, 0);
tag_value_arg++;
args_remaining--;
Target_Object_Property_Value[i].context_tag = context_tag;
Target_Object_Property_Value[i].context_specific = true;
} else {
Target_Object_Property_Value[i].context_specific = false;
}
property_tag = strtol(argv[tag_value_arg], NULL, 0);
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough tag-value pairs\r\n");
return 1;
}
value_string = argv[tag_value_arg + 1];
args_remaining--;
/* printf("tag[%d]=%u value[%d]=%s\r\n",
i, property_tag, i, value_string); */
if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, "Error: tag=%u - it must be less than %u\r\n",
property_tag, MAX_BACNET_APPLICATION_TAG);
return 1;
}
status =
bacapp_parse_application_data(property_tag, value_string,
&Target_Object_Property_Value[i]);
if (!status) {
/* FIXME: show the expected entry format for the tag */
fprintf(stderr, "Error: unable to parse the tag value\r\n");
return 1;
}
Target_Object_Property_Value[i].next = NULL;
if (i > 0) {
Target_Object_Property_Value[i - 1].next =
&Target_Object_Property_Value[i];
}
if (args_remaining <= 0) {
break;
}
}
if (args_remaining > 0) {
fprintf(stderr, "Error: Exceeded %d tag-value pairs.\r\n",
MAX_PROPERTY_VALUES);
return 1;
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
Init_Service_Handlers();
dlenv_init();
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
}
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* at least one second has passed */
if (current_seconds != last_seconds) {
/* increment timer - exit if timed out */
delta_seconds = current_seconds - last_seconds;
elapsed_seconds += delta_seconds;
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
}
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
if (!found) {
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
}
if (!sent_message) {
if (found) {
len = bacapp_encode_data(&Service_Parameters[0],
&Target_Object_Property_Value[0]);
private_data.serviceParameters = &Service_Parameters[0];
private_data.serviceParametersLen = len;
private_data.vendorID = Target_Vendor_Identifier;
private_data.serviceNumber = Target_Service_Number;
Send_UnconfirmedPrivateTransfer(
&Target_Address,
&private_data);
printf("Sent PrivateTransfer. Waiting %u seconds.\r\n",
(unsigned)(timeout_seconds - elapsed_seconds));
sent_message = true;
} else {
if (elapsed_seconds > timeout_seconds) {
printf("\rError: APDU Timeout!\r\n");
Error_Detected = true;
break;
}
}
}
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (Error_Detected) {
break;
}
/* unconfirmed - so just wait until our timeout value */
if (elapsed_seconds > timeout_seconds) {
break;
}
/* keep track of time for next check */
last_seconds = current_seconds;
}
if (Error_Detected)
return 1;
return 0;
}
+143 -143
View File
@@ -1,143 +1,143 @@
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacupt
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
# by default bacupt can handle 64 tag/value pairs
BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacupt
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
BACNET_OBJECT = ..\object
BACNET_HANDLER = ..\handler
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BACNET_OBJECT) \
-I$(BACNET_HANDLER) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
# by default bacupt can handle 64 tag/value pairs
BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE)
SRCS = main.c \
$(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile
+35 -35
View File
@@ -1,38 +1,38 @@
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
TARGET = bacwir
#Makefile to build BACnet Application for the Linux Port
# tools - only if you need them.
# Most platforms have this already defined
# CC = gcc
TARGET = bacwir
TARGET_BIN = ${TARGET}$(TARGET_EXT)
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
SRCS = main.c \
../object/device-client.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
size $@
cp $@ ../../bin
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
include: .depend
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
include: .depend